summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-06-03 17:01:24 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-06-03 17:01:24 +0000
commit6dd3dfb79125cd02d02efbce435a6c82e5af92ef (patch)
tree45084fc83278586f6bbafcb935f92d53f71a6b03
parentInitial commit. (diff)
downloadcorosync-6dd3dfb79125cd02d02efbce435a6c82e5af92ef.tar.xz
corosync-6dd3dfb79125cd02d02efbce435a6c82e5af92ef.zip
Adding upstream version 3.1.8.upstream/3.1.8upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
-rw-r--r--.tarball-version1
-rw-r--r--.version1
-rw-r--r--AUTHORS24
-rw-r--r--ChangeLog26796
-rw-r--r--Doxyfile.in1644
-rw-r--r--INSTALL167
-rw-r--r--LICENSE59
-rw-r--r--Makefile.am201
-rw-r--r--Makefile.in1446
-rw-r--r--README.recovery116
-rw-r--r--aclocal.m41244
-rwxr-xr-xautogen.sh5
-rw-r--r--bindings/Makefile.am15
-rw-r--r--bindings/Makefile.in670
-rw-r--r--bindings/rust/Cargo.toml.in16
-rw-r--r--bindings/rust/Makefile.am60
-rw-r--r--bindings/rust/Makefile.in836
-rw-r--r--bindings/rust/README.md20
-rw-r--r--bindings/rust/build.rs.in7
-rw-r--r--bindings/rust/src/cfg.rs348
-rw-r--r--bindings/rust/src/cmap.rs894
-rw-r--r--bindings/rust/src/cpg.rs628
-rw-r--r--bindings/rust/src/lib.rs296
-rw-r--r--bindings/rust/src/quorum.rs298
-rw-r--r--bindings/rust/src/sys/mod.rs7
-rw-r--r--bindings/rust/src/votequorum.rs501
-rw-r--r--bindings/rust/tests/Cargo.toml.in36
-rw-r--r--bindings/rust/tests/Makefile.am26
-rw-r--r--bindings/rust/tests/Makefile.in625
-rw-r--r--bindings/rust/tests/build.rs.in22
-rw-r--r--bindings/rust/tests/src/bin/cfg-test.rs135
-rw-r--r--bindings/rust/tests/src/bin/cmap-test.rs195
-rw-r--r--bindings/rust/tests/src/bin/cpg-test.rs142
-rw-r--r--bindings/rust/tests/src/bin/quorum-test.rs83
-rw-r--r--bindings/rust/tests/src/bin/votequorum-test.rs117
-rwxr-xr-xbuild-aux/git-version-gen265
-rwxr-xr-xbuild-aux/gitlog-to-changelog191
-rw-r--r--build-aux/release.mk75
-rwxr-xr-xbuild-aux/rust-regen.sh28
-rw-r--r--build-aux/rust.mk114
-rw-r--r--common_lib/Makefile.am38
-rw-r--r--common_lib/Makefile.in720
-rw-r--r--common_lib/error_conversion.c234
-rw-r--r--conf/COROSYNC-MIB.txt239
-rw-r--r--conf/Makefile.am67
-rw-r--r--conf/Makefile.in883
-rw-r--r--conf/corosync-signals.conf26
-rw-r--r--conf/corosync.conf.example71
-rw-r--r--conf/lenses/corosync.aug184
-rw-r--r--conf/lenses/tests/test_corosync.aug167
-rw-r--r--conf/logrotate/Makefile.am45
-rw-r--r--conf/logrotate/Makefile.in577
-rw-r--r--conf/logrotate/corosync-copytruncate.in9
-rw-r--r--conf/logrotate/corosync-reopen.in17
-rw-r--r--conf/xml2conf.xsl94
-rwxr-xr-xconfig.guess1558
-rwxr-xr-xconfig.sub1788
-rwxr-xr-xconfigure19793
-rw-r--r--configure.ac842
-rw-r--r--corosync.spec.in305
-rwxr-xr-xdepcomp791
-rw-r--r--exec/Makefile.am70
-rw-r--r--exec/Makefile.in1218
-rw-r--r--exec/apidef.c149
-rw-r--r--exec/apidef.h42
-rw-r--r--exec/cfg.c1470
-rw-r--r--exec/cmap.c1155
-rw-r--r--exec/coroparse.c1697
-rw-r--r--exec/cpg.c2344
-rw-r--r--exec/cs_queue.h292
-rw-r--r--exec/fsm.h131
-rw-r--r--exec/icmap.c1330
-rw-r--r--exec/ipc_glue.c829
-rw-r--r--exec/ipcs_stats.h61
-rw-r--r--exec/logconfig.c757
-rw-r--r--exec/logconfig.h62
-rw-r--r--exec/logsys.c952
-rw-r--r--exec/main.c1666
-rw-r--r--exec/main.h129
-rw-r--r--exec/mon.c511
-rw-r--r--exec/pload.c357
-rw-r--r--exec/quorum.c110
-rw-r--r--exec/quorum.h65
-rw-r--r--exec/schedwrk.c157
-rw-r--r--exec/schedwrk.h53
-rw-r--r--exec/service.c468
-rw-r--r--exec/service.h91
-rw-r--r--exec/stats.c784
-rw-r--r--exec/stats.h73
-rw-r--r--exec/sync.c549
-rw-r--r--exec/sync.h73
-rw-r--r--exec/timer.c96
-rw-r--r--exec/timer.h65
-rw-r--r--exec/totemconfig.c2454
-rw-r--r--exec/totemconfig.h93
-rw-r--r--exec/totemip.c624
-rw-r--r--exec/totemknet.c2306
-rw-r--r--exec/totemknet.h159
-rw-r--r--exec/totemnet.c628
-rw-r--r--exec/totemnet.h166
-rw-r--r--exec/totempg.c1620
-rw-r--r--exec/totemsrp.c5252
-rw-r--r--exec/totemsrp.h168
-rw-r--r--exec/totemudp.c1549
-rw-r--r--exec/totemudp.h144
-rw-r--r--exec/totemudpu.c1453
-rw-r--r--exec/totemudpu.h144
-rw-r--r--exec/util.c343
-rw-r--r--exec/util.h98
-rw-r--r--exec/votequorum.c3082
-rw-r--r--exec/votequorum.h44
-rw-r--r--exec/vsf.h58
-rw-r--r--exec/vsf_quorum.c801
-rw-r--r--exec/vsf_ykd.c537
-rw-r--r--exec/vsf_ykd.h44
-rw-r--r--exec/wd.c767
-rw-r--r--include/Makefile.am47
-rw-r--r--include/Makefile.in646
-rw-r--r--include/corosync/cfg.h315
-rw-r--r--include/corosync/cmap.h378
-rw-r--r--include/corosync/config.h.in542
-rw-r--r--include/corosync/coroapi.h526
-rw-r--r--include/corosync/corodefs.h62
-rw-r--r--include/corosync/corotypes.h189
-rw-r--r--include/corosync/cpg.h440
-rw-r--r--include/corosync/hdb.h250
-rw-r--r--include/corosync/icmap.h565
-rw-r--r--include/corosync/ipc_cfg.h307
-rw-r--r--include/corosync/ipc_cmap.h263
-rw-r--r--include/corosync/ipc_cpg.h502
-rw-r--r--include/corosync/ipc_quorum.h142
-rw-r--r--include/corosync/ipc_votequorum.h265
-rw-r--r--include/corosync/logsys.h350
-rw-r--r--include/corosync/mar_gen.h307
-rw-r--r--include/corosync/quorum.h211
-rw-r--r--include/corosync/sam.h250
-rw-r--r--include/corosync/sq.h404
-rw-r--r--include/corosync/swab.h77
-rw-r--r--include/corosync/totem/totem.h295
-rw-r--r--include/corosync/totem/totemip.h131
-rw-r--r--include/corosync/totem/totempg.h210
-rw-r--r--include/corosync/totem/totemstats.h120
-rw-r--r--include/corosync/votequorum.h317
-rw-r--r--init/Makefile.am65
-rw-r--r--init/Makefile.in635
-rwxr-xr-xinit/corosync-notifyd.in150
-rw-r--r--init/corosync-notifyd.service.in14
-rwxr-xr-xinit/corosync.in230
-rw-r--r--init/corosync.service.in34
-rw-r--r--init/corosync.sysconfig.example10
-rwxr-xr-xinstall-sh527
-rw-r--r--lib/Makefile.am66
-rw-r--r--lib/Makefile.in786
-rw-r--r--lib/cfg.c835
-rw-r--r--lib/cmap.c1119
-rw-r--r--lib/cpg.c1426
-rw-r--r--lib/libcfg.versions18
-rw-r--r--lib/libcfg.verso1
-rw-r--r--lib/libcmap.versions6
-rw-r--r--lib/libcmap.verso1
-rw-r--r--lib/libcpg.versions17
-rw-r--r--lib/libcpg.verso1
-rw-r--r--lib/libquorum.versions11
-rw-r--r--lib/libquorum.verso1
-rw-r--r--lib/libsam.versions12
-rw-r--r--lib/libsam.verso1
-rw-r--r--lib/libvotequorum.versions17
-rw-r--r--lib/libvotequorum.verso1
-rw-r--r--lib/quorum.c588
-rw-r--r--lib/sam.c1489
-rw-r--r--lib/util.h54
-rw-r--r--lib/votequorum.c811
-rw-r--r--ltmain.sh9655
-rw-r--r--m4/libtool.m47986
-rw-r--r--m4/ltoptions.m4384
-rw-r--r--m4/ltsugar.m4123
-rw-r--r--m4/ltversion.m423
-rw-r--r--m4/lt~obsolete.m498
-rw-r--r--man/Makefile.am189
-rw-r--r--man/Makefile.in863
-rw-r--r--man/cmap_context_get.3.in58
-rw-r--r--man/cmap_context_set.3.in60
-rw-r--r--man/cmap_dec.3.in92
-rw-r--r--man/cmap_delete.3.in70
-rw-r--r--man/cmap_dispatch.3.in91
-rw-r--r--man/cmap_fd_get.3.in67
-rw-r--r--man/cmap_finalize.3.in61
-rw-r--r--man/cmap_get.3.in153
-rw-r--r--man/cmap_inc.3.in92
-rw-r--r--man/cmap_initialize.3.in64
-rw-r--r--man/cmap_initialize_map.3.in73
-rw-r--r--man/cmap_iter_finalize.3.in72
-rw-r--r--man/cmap_iter_init.3.in80
-rw-r--r--man/cmap_iter_next.3.in82
-rw-r--r--man/cmap_keys.7426
-rw-r--r--man/cmap_overview.378
-rw-r--r--man/cmap_set.3.in127
-rw-r--r--man/cmap_track_add.3.in170
-rw-r--r--man/cmap_track_delete.3.in70
-rw-r--r--man/corosync-blackbox.869
-rw-r--r--man/corosync-cfgtool.8139
-rw-r--r--man/corosync-cmapctl.899
-rw-r--r--man/corosync-cpgtool.885
-rw-r--r--man/corosync-keygen.8118
-rw-r--r--man/corosync-notifyd.8148
-rw-r--r--man/corosync-quorumtool.8112
-rw-r--r--man/corosync-vqsim.894
-rw-r--r--man/corosync-xmlproc.857
-rw-r--r--man/corosync.870
-rw-r--r--man/corosync.conf.51061
-rw-r--r--man/corosync.xml.572
-rw-r--r--man/corosync_overview.7176
-rw-r--r--man/cpg_context_get.3.in68
-rw-r--r--man/cpg_context_set.3.in69
-rw-r--r--man/cpg_dispatch.3.in111
-rw-r--r--man/cpg_fd_get.3.in75
-rw-r--r--man/cpg_finalize.3.in71
-rw-r--r--man/cpg_initialize.3.in177
-rw-r--r--man/cpg_iteration_finalize.3.in67
-rw-r--r--man/cpg_iteration_initialize.3.in96
-rw-r--r--man/cpg_iteration_next.3.in85
-rw-r--r--man/cpg_join.3.in112
-rw-r--r--man/cpg_leave.3.in77
-rw-r--r--man/cpg_local_get.3.in72
-rw-r--r--man/cpg_mcast_joined.3.in142
-rw-r--r--man/cpg_membership_get.3.in81
-rw-r--r--man/cpg_model_initialize.3.in233
-rw-r--r--man/cpg_overview.382
-rw-r--r--man/cpg_zcb_alloc.3.in85
-rw-r--r--man/cpg_zcb_free.3.in77
-rw-r--r--man/cpg_zcb_mcast_joined.3.in127
-rw-r--r--man/index.html400
-rw-r--r--man/ipc_common.sh.errors25
-rw-r--r--man/quorum_context_get.3.in62
-rw-r--r--man/quorum_context_set.3.in64
-rw-r--r--man/quorum_dispatch.3.in98
-rw-r--r--man/quorum_fd_get.3.in69
-rw-r--r--man/quorum_finalize.3.in66
-rw-r--r--man/quorum_getquorate.3.in62
-rw-r--r--man/quorum_initialize.3.in114
-rw-r--r--man/quorum_model_initialize.3.in165
-rw-r--r--man/quorum_overview.367
-rw-r--r--man/quorum_trackstart.3.in78
-rw-r--r--man/quorum_trackstop.3.in62
-rw-r--r--man/sam_data_getsize.3.in68
-rw-r--r--man/sam_data_restore.3.in77
-rw-r--r--man/sam_data_store.3.in83
-rw-r--r--man/sam_finalize.3.in63
-rw-r--r--man/sam_hc_callback_register.3.in89
-rw-r--r--man/sam_hc_send.3.in68
-rw-r--r--man/sam_initialize.3.in126
-rw-r--r--man/sam_mark_failed.3.in73
-rw-r--r--man/sam_overview.3181
-rw-r--r--man/sam_register.3.in88
-rw-r--r--man/sam_start.3.in83
-rw-r--r--man/sam_stop.3.in67
-rw-r--r--man/sam_warn_signal_set.3.in63
-rw-r--r--man/votequorum.5410
-rw-r--r--man/votequorum_context_get.3.in64
-rw-r--r--man/votequorum_context_set.3.in66
-rw-r--r--man/votequorum_dispatch.3.in99
-rw-r--r--man/votequorum_fd_get.3.in70
-rw-r--r--man/votequorum_finalize.3.in67
-rw-r--r--man/votequorum_getinfo.3.in111
-rw-r--r--man/votequorum_initialize.3.in139
-rw-r--r--man/votequorum_overview.384
-rw-r--r--man/votequorum_qdevice_master_wins.3.in77
-rw-r--r--man/votequorum_qdevice_poll.3.in83
-rw-r--r--man/votequorum_qdevice_register.3.in83
-rw-r--r--man/votequorum_qdevice_unregister.3.in68
-rw-r--r--man/votequorum_qdevice_update.3.in69
-rw-r--r--man/votequorum_setexpected.3.in66
-rw-r--r--man/votequorum_setvotes.3.in63
-rw-r--r--man/votequorum_trackstart.3.in83
-rw-r--r--man/votequorum_trackstop.3.in63
-rwxr-xr-xmissing215
-rw-r--r--pkgconfig/Makefile.am70
-rw-r--r--pkgconfig/Makefile.in597
-rw-r--r--pkgconfig/corosync.pc.in12
-rw-r--r--pkgconfig/libtemplate.pc.in11
-rwxr-xr-xtest-driver127
-rw-r--r--test/Makefile.am81
-rw-r--r--test/Makefile.in869
-rw-r--r--test/cpgbench.c197
-rw-r--r--test/cpgbenchzc.c193
-rw-r--r--test/cpgbound.c130
-rw-r--r--test/cpghum.c884
-rw-r--r--test/cpgverify.c183
-rw-r--r--test/ploadstart.sh60
-rw-r--r--test/stress_cpgcontext.c134
-rw-r--r--test/stress_cpgfdget.c117
-rw-r--r--test/stress_cpgzc.c141
-rw-r--r--test/testcfg.c159
-rw-r--r--test/testcpg.c438
-rw-r--r--test/testcpg2.c92
-rw-r--r--test/testcpgzc.c248
-rw-r--r--test/testquorum.c64
-rw-r--r--test/testquorummodel.c102
-rw-r--r--test/testsam.c1476
-rw-r--r--test/testvotequorum1.c200
-rw-r--r--test/testvotequorum2.c236
-rw-r--r--test/testzcgc.c175
-rw-r--r--tools/Makefile.am93
-rw-r--r--tools/Makefile.in899
-rw-r--r--tools/corosync-blackbox.sh34
-rw-r--r--tools/corosync-cfgtool.c614
-rw-r--r--tools/corosync-cmapctl.c996
-rw-r--r--tools/corosync-cpgtool.c276
-rw-r--r--tools/corosync-keygen.c191
-rw-r--r--tools/corosync-notifyd.c1420
-rw-r--r--tools/corosync-notifyd.sysconfig.example10
-rw-r--r--tools/corosync-quorumtool.c1023
-rw-r--r--tools/corosync-xmlproc.sh57
-rw-r--r--tools/util.c35
-rw-r--r--tools/util.h15
-rw-r--r--vqsim/Makefile.am57
-rw-r--r--vqsim/Makefile.in787
-rw-r--r--vqsim/parser.c418
-rw-r--r--vqsim/vq_object.c121
-rw-r--r--vqsim/vqmain.c854
-rw-r--r--vqsim/vqsim.h82
-rw-r--r--vqsim/vqsim_vq_engine.c479
322 files changed, 169591 insertions, 0 deletions
diff --git a/.tarball-version b/.tarball-version
new file mode 100644
index 0000000..c848fb9
--- /dev/null
+++ b/.tarball-version
@@ -0,0 +1 @@
+3.1.8
diff --git a/.version b/.version
new file mode 100644
index 0000000..c848fb9
--- /dev/null
+++ b/.version
@@ -0,0 +1 @@
+3.1.8
diff --git a/AUTHORS b/AUTHORS
new file mode 100644
index 0000000..7ce2b46
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1,24 @@
+Last Updated Dec 2009
+
+Main Developers
+---------------
+Steven Dake Maintainer, totem implementation, cfg,
+ logsys, service engine architecture, ipc system
+ poll, timers, objdb, hdb, sync, coroapi
+Christine Caulfield cpg, cfg, quorum, confdb, totem ipv6 support, totem NSS
+ support
+Fabien Thomas OS portability, BSD port
+Hans Feldt logging inspiration
+Angus Salkeld objdb, static code analysis cleanup, statistics
+Lon Hohberger logsys
+Fabio Di Nitto automake, pkgconfig, logsys, config, distro release
+Jim Meyering automake, sanitizing APIs, warnings removal
+Andrew Beekhof automake, integration with Pacemaker
+Dave Teigland cpg specification, integration with cluster3
+Jan Friesse cpg, sam
+Jérôme Flesch BSD portability
+
+Significant credit belongs in our large vibrant community members, who are
+unfortunately too numerous to list. Your tireless effort in testing, deploying,
+and providing bug reports of our community driven software model shows that
+open source can make a difference and produces better software.
diff --git a/ChangeLog b/ChangeLog
new file mode 100644
index 0000000..23f0232
--- /dev/null
+++ b/ChangeLog
@@ -0,0 +1,26796 @@
+2023-11-06 Machiry Aravind Kumar <makrvcs@gmail.com>
+
+ Handling integer overflow issues
+ Avoiding signed integer overflows by converting size
+ related types to size_t.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2023-10-09 Christine Caulfield <ccaulfie@redhat.com>
+
+ rust: Improve vector initialisation
+ (also silence clippy in rust 1.73)
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2023-10-06 Christine Caulfield <ccaulfie@redhat.com>
+
+ man: Update the corosync_overview manpage
+ The bits about IPv6 were out of date (for knet).
+
+ Added reference to the corosync-*tool utilities so that
+ people know they are there
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2023-10-05 Christine Caulfield <ccaulfie@redhat.com>
+
+ config: Fail to start if ping timers are invalid
+ This required adding a lot of return values to two previously
+ 'void' functions. I did two rather than just the one that was
+ needed because it seemed to make sense to do them both together.
+
+ Although these functions now return errors, they are probably
+ still ignored higher up. this really needs a comprehensive audit.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2023-08-30 Christine Caulfield <ccaulfie@redhat.com>
+
+ rust: Remove some pointless casts
+ As pointed out by clippy in Rust 1.72
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2023-08-09 Christine Caulfield <ccaulfie@redhat.com>
+
+ parser: Allow a non-breaking space as 'whitespace'
+ non-breaking spaces are depressingly easy to enter in some
+ editors and can make a mess of a corosync.conf file, as the
+ character can break keyword names and generate some very strange
+ error messages.
+
+ So here we include it (0xA0) as a valid whitespace character.
+ The (unsigned char) cast is for portability - Intel systems use
+ signed chars so we'd need something there, but this should
+ protect us against unsigned char systems too.
+
+ No attempt is made to protect against UTF-8 characters, that's very
+ much out of scope for this project I suspect.
+
+ ref: https://github.com/corosync/corosync/issues/723
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2023-06-06 Jan Friesse <jfriesse@redhat.com>
+
+ spec: Migrate to SPDX license
+ Both Fedora and openSUSE now recommends to use SPDX shortname format
+ for License.
+
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+2023-05-29 Jan Friesse <jfriesse@redhat.com>
+
+ build: Fix rust make -j build dep for distcheck
+ "Inspired" by similar patch from kronosnet
+ (531ebe195a955d9a1c8b762443ecab3edca95ad4)
+
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+2023-05-23 Jan Friesse <jfriesse@redhat.com>
+
+ rust: Remove tests from check scripts
+ Rust test are equivalent of C tests (so interactive one) and not
+ automated tests, so it shouldn't be executed by make check.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2023-04-24 Christine Caulfield <ccaulfie@redhat.com>
+
+ Rust: Remove obsolete bindgen flag
+ --size_t-is-usize has been deprecated for a while and is
+ removed in bindgen 0.64
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2023-04-03 Christine Caulfield <ccaulfie@redhat.com>
+
+ knet: use knet TRACE logging level if available
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2023-01-27 Christine Caulfield <ccaulfie@redhat.com>
+
+ Rust: 'fix' clippys for Rust 1.67
+ This is clippy getting a bit above itself IMHO
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2023-01-26 Christine Caulfield <ccaulfie@redhat.com>
+
+ rust: Make it work on FreeBSD
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ bindings: Add Rust bindings
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2022-10-24 Jan Friesse <jfriesse@redhat.com>
+
+ totemconfig: Add support for knet_mtu
+ totem.knet_mtu is new configuration option which allows setting
+ of automatic or manual knet MTU.
+
+ Also reload of totem.knet_pmtud_interval is fixed now, so it works when
+ key is deleted (and set back default value).
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2022-07-27 Jan Friesse <jfriesse@redhat.com>
+
+ configure: Modernize configure.ac a bit
+ ... to make 2.71 happy. Also increase minimum version to 2.69 (10 years
+ old version so should be compatible enough).
+
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+2022-03-31 Christine Caulfield <ccaulfie@redhat.com>
+
+ log: Configure knet logging to the same as corosync
+ Before this, all knet messages, including debug, were sent
+ over the pipe from knet to corosync and filtered in corosync.
+ This was obviously a waste, so now we tell knet the logging
+ level we need from it and so only get the messages that the
+ user has requested.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2022-03-30 Jan Friesse <jfriesse@redhat.com>
+
+ logrotate: Use copytruncate method by default
+ The reopen lograte method has two main problems:
+ 1. It does fail when corosync is not running (solvable by
+ adding "|| true")
+ 2. If (for some reason, like SELinux) cfgtool -L fails, logrotate
+ fails and corosync keeps logging into old file. Added "|| true"
+ makes situation even worse because logrotate removes file but
+ corosync keeps logging into it.
+
+ Solution is to install copytruncate logrotate snip by default (and
+ keep reopen config file only for reference).
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2022-03-08 Andreas Grueninger <andreas.grueninger@noemail.com>
+
+ totemconfig: Check uname return value correctly
+ uname in Solaris/Illumos returns non-negative value when succesful.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2022-02-01 Jan Friesse <jfriesse@redhat.com>
+
+ totempg: Fix alignment handling
+ Some platforms requires aligned memory access. For such platforms,
+ special code was added using address modulo 4 to check if aligning is
+ needed or not. This may be problem for 64 bits platforms. Also check in
+ app_deliver_fn was incorrect and always true.
+
+ Solution is to use modulo sizeof pointer and add parentheses to fix the
+ check in app_deliver_fn function.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2022-01-05 Jan Friesse <jfriesse@redhat.com>
+
+ pkgconfig: Export corosysconfdir
+ Useful for external code to easily tell where corosync.conf
+ is (in case someone configured it for /usr/local/etc, ...)
+
+ E.g. pacemaker's crm_report collects corosync.conf, and some
+ of its testing tools generate a corosync.conf for a test cluster.
+
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+2022-01-03 Ferenc Wágner <wferi@debian.org>
+
+ Remove bashism from configure script
+ This was the real problem behind 384d168: Debian experimental now
+ sports a dash with LINENO support, so configure does not fall back to
+ using bash instead, choking on such bash-only constructs. Unfortunately
+ this didn't bail out cleanly, just unexpectedly set link_all_deplibs to
+ no, and the error message
+
+ ./configure: 13158: test: yes: unexpected operator
+
+ stayed unnoticed in the logs. Actually, link_all_deplibs=no is the
+ default in Debian, reducing overlinking and causing confusion overall,
+ see https://debbugs.gnu.org/db/13/13920.html for example.
+
+ I think being explicit about used interfaces has its merit, so now that
+ Corosync has it, it might be advantageous to disable link_all_deplibs
+ by default across the board (after this patch re-enables it as a side
+ effect).
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2021-11-24 Jan Friesse <jfriesse@redhat.com>
+
+ totemudpu: Don't block local socketpair
+ Commit to drop packets from unlisted IPs made ifdown case not working
+ because msg_name is unset for socketpair.
+
+ solution is to drop packets from unlisted IPs only when bind state is
+ BIND_STATE_REGULAR.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2021-11-10 Jan Friesse <jfriesse@redhat.com>
+
+ build: Add explicit dependency for used libraries
+ Don't rely on implicit symbol finding (cs_strerror being most prominent
+ example) but rather use explicit one.
+
+ This makes current debian experimental happy (compile source)
+
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+2021-11-03 Jan Friesse <jfriesse@redhat.com>
+
+ totemsrp: Switch totempg buffers at the right time
+ Commit 92e0f9c7bb9b4b6a0da8d64bdf3b2e47ae55b1cc added switching of
+ totempg buffers in sync phase. But because buffers got switch too early
+ there was a problem when delivering recovered messages (messages got
+ corrupted and/or lost). Solution is to switch buffers after recovered
+ messages got delivered.
+
+ I think it is worth to describe complete history with reproducers so it
+ doesn't get lost.
+
+ It all started with 402638929e5045ef520a7339696c687fbed0b31b (more info
+ about original problem is described in
+ https://bugzilla.redhat.com/show_bug.cgi?id=820821). This patch
+ solves problem which is way to be reproduced with following reproducer:
+ - 2 nodes
+ - Both nodes running corosync and testcpg
+ - Pause node 1 (SIGSTOP of corosync)
+ - On node 1, send some messages by testcpg
+ (it's not answering but this doesn't matter). Simply hit ENTER key
+ few times is enough)
+ - Wait till node 2 detects that node 1 left
+ - Unpause node 1 (SIGCONT of corosync)
+
+ and on node 1 newly mcasted cpg messages got sent before sync barrier,
+ so node 2 logs "Unknown node -> we will not deliver message".
+
+ Solution was to add switch of totemsrp new messages buffer.
+
+ This patch was not enough so new one
+ (92e0f9c7bb9b4b6a0da8d64bdf3b2e47ae55b1cc) was created. Reproducer of
+ problem was similar, just cpgverify was used instead of testcpg.
+ Occasionally when node 1 was unpaused it hang in sync phase because
+ there was a partial message in totempg buffers. New sync message had
+ different frag cont so it was thrown away and never delivered.
+
+ After many years problem was found which is solved by this patch
+ (original issue describe in
+ https://github.com/corosync/corosync/issues/660).
+ Reproducer is more complex:
+ - 2 nodes
+ - Node 1 is rate-limited (used script on the hypervisor side):
+ ```
+ iface=tapXXXX
+ # ~0.1MB/s in bit/s
+ rate=838856
+ # 1mb/s
+ burst=1048576
+ tc qdisc add dev $iface root handle 1: htb default 1
+ tc class add dev $iface parent 1: classid 1:1 htb rate ${rate}bps \
+ burst ${burst}b
+ tc qdisc add dev $iface handle ffff: ingress
+ tc filter add dev $iface parent ffff: prio 50 basic police rate \
+ ${rate}bps burst ${burst}b mtu 64kb "drop"
+ ```
+ - Node 2 is running corosync and cpgverify
+ - Node 1 keeps restarting of corosync and running cpgverify in cycle
+ - Console 1: while true; do corosync; sleep 20; \
+ kill $(pidof corosync); sleep 20; done
+ - Console 2: while true; do ./cpgverify;done
+
+ And from time to time (reproduced usually in less than 5 minutes)
+ cpgverify reports corrupted message.
+
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+2021-10-25 Christine Caulfield <ccaulfie@redhat.com>
+
+ cpghum: Allow to continue if corosync is restarted
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2021-10-18 miharahiro <hmihara@redhat.com>
+
+ man: Fix consensus timeout
+ The consensus timeout is 1.2 * token_timeout,
+ which has been changeg from 1000 to 3000, so change also consensus
+ timeout.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2021-09-13 Jan Friesse <jfriesse@redhat.com>
+
+ logsys: Unlock config mutex on error
+ Thanks Ryan Cai <ycaibb@gmail.com> for reporting the problem.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2021-08-20 Jan Friesse <jfriesse@redhat.com>
+
+ totem: Add cancel_hold_on_retransmit config option
+ Previously, existence of retransmit messages canceled holding
+ of token (and never allowed representative to enter token hold
+ state).
+
+ This makes token rotating maximum speed and keeps processor
+ resending messages over and over again - overloading network
+ and reducing chance to successfully deliver the messages.
+
+ Also there were reports of various Antivirus / IPS / IDS which slows
+ down delivery of packets with certain sizes (packets bigger than token)
+ what make Corosync retransmit messages over and over again.
+
+ Proposed solution is to allow representative to enter token hold
+ state when there are only retransmit messages. This allows network to
+ handle overload and/or gives Antivirus/IPS/IDS enough time scan and
+ deliver packets without corosync entering "FAILED TO RECEIVE" state and
+ adding more load to network.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2021-08-04 Jan Friesse <jfriesse@redhat.com>
+
+ totemconfig: Knet nodeid must be < 65536
+ Knet limits maximum node id to 16-bit type. This was not ensured in
+ corosync and it was possible to set nodeid to value >= 65536 and
+ (surprisingly) most of the things were working quite well because of
+ overflow. corosync-cmapctl -m stats contained knet nodeid in
+ stats.knet. subtree, so for nodeid 65536 result was:
+
+ Can't get value of stats.knet.node0.link0.connected. Error
+ CS_ERR_NOT_EXIST
+
+ Commit implements checking of nodeid and limits it to KNET_MAX_HOST
+ value when knet is used.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ totemconfig: Ensure all knet hosts has a nodeid
+ Nodeid is required for knet for every node. Right now, existence of
+ nodeid is checked only for local for local node, so broaden the test.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2021-08-02 Jan Friesse <jfriesse@redhat.com>
+
+ cfgtool: Use CS_PRI_NODE_ID for formatting nodeid
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ cfgtool: Fix brief mode display of localhost
+ Show 'n' also for first localhost link, so all localhost links
+ are marked consistently with non-brief display.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ cfgtool: Set nodeid indexes after sort
+ Needed for having correct index of localhost
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ totemconfig: Put autogenerated nodeid back to cmap
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ cfgtool: Check existence of at least one of nodeid
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ totemconfig: Do not process totem.nodeid
+ totem.nodeid is relict from times when nodelist was not required and
+ totemsrp was sending whole membership with ip addresses.
+
+ With Corosync 3 ip addresses are no longer sent so
+ it is not possible to find "next" node ip address where to send token
+ (because only nodeid is sent) without having information about all of
+ the nodes stored locally.
+
+ When totem.nodeid was configured it was partly used and other parts
+ (most notably totemudpu_token_target_set) were using autogenerated
+ nodeid. Together it was not possible to create even single node
+ membership.
+
+ Solution is to ignore totem.nodeid completely (and display warning when
+ it is set).
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2021-07-29 Christine Caulfield <ccaulfie@redhat.com>
+
+ knet: Fix node status display
+ Currently if there is a gap in the links (eg link0 is missing)
+ corosync-cfgtool -s will still display the links as 0,1,2,3...
+ even if they are 1,2,5,6...
+
+ Also display the KNET transport type with the link in
+ corosync-cfgtool -s & -n
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2021-07-23 Jan Friesse <jfriesse@redhat.com>
+
+ main: Add support for cgroup v2 and auto mode
+ Support for cgroup v2 is very similar to cgroup v1 just checking (and
+ writing) different file.
+
+ Because of all the problems described later with cgroup v2 new "auto"
+ mode (new default) is added. This mode first tries to set rr scheduling
+ and moves Corosync to root cgroup only if it fails.
+
+ Testing this feature is a bit harder than with cgroup v1 so it's
+ probably worh noting in this commit message.
+
+ 1. Copy some service file (I've used httpd service) and set
+ CPUQuota=30% in the [service] section.
+ 2. Check /sys/fs/cgroup/cgroup.subtree_control - there should be no
+ "cpu"
+ 3. Start modified service
+ 4. Check /sys/fs/cgroup/cgroup.subtree_control - there should be "cpu"
+ 5. Start corosync - It should be able to get rt priority
+
+ When move_to_root_cgroup is disabled (applies only for kernels
+ with CONFIG_RT_GROUP_SCHED enabled), behavior differs:
+ - If corosync is started before modified service, so
+ there is no "cpu" in /sys/fs/cgroup/cgroup.subtree_control
+ corosync starts without problem and gets rt priority.
+ Starting modified service later will never add "cpu" into
+ /sys/fs/cgroup/cgroup.subtree_control (because corosync is holding
+ rt priority and it is placed in the non-root cgroup by systemd).
+
+ - When corosync is started after modified service, so "cpu"
+ is in /sys/fs/cgroup/cgroup.subtree_control, corosync is not
+ able to get RT priority.
+
+ It's worth noting problems when cgroup v2 is used together with systemd
+ logging described in corosync.conf(5) man page.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2021-06-03 Christine Caulfield <ccaulfie@redhat.com>
+
+ stats: fix crash when iterating over deleted keys
+ The libqb map API leaves 'ownership' of the data with the caller
+ but does its own lifetime management, so it can easily happen that
+ map_rm() is called and the data deleted by the caller.
+ But if an iterator is running over that item then the map entry
+ will not get removed (leaving dangling pointers) until later.
+
+ libqb has a hack-y callback that tells the owner when it is safe to
+ delete the allocated memory, so we hook into that. icmap is already
+ using this.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2021-06-02 Jan Friesse <jfriesse@redhat.com>
+
+ man: Add note about single node configuration
+ Internally knet is using just one link for localhost so for single node
+ configuration knet_link_get_link_list returns only one entry. This is
+ propagated to `corosync-cfgtool -s`.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2021-05-21 Jan Friesse <jfriesse@redhat.com>
+
+ Revert "main: Add support for cgroup v2"
+ This reverts commit 57e6b86b53010dd2612b0a6a4e04917673062ecf.
+
+ We are in process of finding better solution so reverting for now.
+
+ Revert "man: Add info about cgroup v2 behavior"
+ This reverts commit 9d3df5696ed6b04b379a2fe643eec1fcd5a4b10d.
+
+ We are in process of finding better solution so reverting for now.
+
+2021-05-19 Jan Friesse <jfriesse@redhat.com>
+
+ man: Add info about cgroup v2 behavior
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ cfg: corosync_cfg_trackstop blocks forever
+ corosync_cfg_trackstop expects reply but that was never sent. Make sure
+ to send reply so corosync_cfg_trackstop works.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2021-05-10 Jan Friesse <jfriesse@redhat.com>
+
+ main: Add support for cgroup v2
+ Support for cgroup v2 is very similar to cgroup v1 just checking (and
+ writing) different file.
+
+ Testing this feature is a bit harder than with cgroup v1 so it's
+ probably worh noting in this commit message.
+
+ 1. Copy some service file (I've used httpd service) and set
+ CPUQuota=30% in the [service] section.
+ 2. Check /sys/fs/cgroup/cgroup.subtree_control - there should be no
+ "cpu"
+ 3. Start modified service
+ 4. Check /sys/fs/cgroup/cgroup.subtree_control - there should be "cpu"
+ 5. Start corosync - It should be able to get rt priority
+
+ When move_to_root_cgroup is disabled, behavior differs:
+ - If corosync is started before modified service, so
+ there is no "cpu" in /sys/fs/cgroup/cgroup.subtree_control
+ corosync starts without problem and gets rt priority.
+ Starting modified service later will never add "cpu" into
+ /sys/fs/cgroup/cgroup.subtree_control (because corosync is holding
+ rt priority and it is placed in the non-root cgroup by systemd).
+
+ - When corosync is started after modified service, so "cpu"
+ is in /sys/fs/cgroup/cgroup.subtree_control, corosync is not
+ able to get RT priority.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2021-04-14 Jan Friesse <jfriesse@redhat.com>
+
+ main: Mark crypto_model key read only
+ ... to be in align with crypto_cypher and crypto_hash.
+
+ Reload (corosync-cfgtool -R) works without any problem and changing of
+ key is not supported anyway,
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ totemconfig: Ensure strncpy is always terminated
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ config: Properly check crypto and compress models
+ Use knet_get_crypto_list to find knet supported crypto models and use
+ them instead of hardcoded list.
+
+ Also fix compression handling. Previously knet_compression_model
+ value was not checked at all and was directly passed to knet.
+
+ Use knet_get_compress_list to find knet supported compress models and
+ use them to check validity of config file and for more informative
+ error message.
+
+ Lastly enhance corosync version display with information
+ about available crypto/compression models.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2021-04-07 Ferenc Wágner <wferi@debian.org>
+
+ man: corosync-cfgtool.8: use proper single quotes
+ Apostrophe as the first character of the input line indicates a
+ request, so groff complained: macro 'onwire'' not defined.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2021-04-06 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ knet: pass correct handle to knet_handle_compress
+ totemknet_configure_compression was using knet_context
+ just to gather the knet handle / instance.
+
+ On first time config knet_contex is not initialized till
+ much later in the code, passing some random garbage pointers
+ to knet_handle_compress, that would crash later trying
+ to acquire a mutex lock.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2021-03-29 Johannes Krupp <johannes.krupp@cispa.saarland>
+
+ totemconfig: fix integer underflow and logic bug
+ Fix integer underflow when computing `namelen` in `nodelist_byname`,
+ always use computed `namelen`.
+ Fixes #626.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2021-03-25 liangxin1300 <XLiang@suse.com>
+
+ totemconfig: change udp netmtu value as a constant
+ Insted of using "magic number" use UDP_NETMTU constant.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2021-03-18 Dan Streetman <ddstreet@canonical.com>
+
+ totemknet: retry knet_handle_new if it fails
+ Retry knet_handle_new without privileged operations if it fails
+
+ knet_handle_new can fail with ENAMETOOLONG if its privileged operations
+ fail, which can happen if we're running as a user process or in an
+ unprivileged container.
+
+ This adds a cmap key 'allow_knet_handle_fallback' that defaults to no,
+ which is the current behavior of exiting with error if the knet_handle
+ can't be created with privileged operations. If the new cmap key is set
+ to 'yes' and the knet_handle creation fails, fallback to creating the
+ handle using unprivileged operations is tried.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2021-03-11 Dan Streetman <ddstreet@canonical.com>
+
+ main: Check memlock rlimit
+ Don't lock all current and future memory if can't
+ increase memlock rlimit.
+
+ If we fail to increase our RLIMIT_MEMLOCK, then locking all our current
+ and future memory is extremely dangerous; once our memory use reaches
+ our RLIMIT_MEMLOCK, memory allocations will start failing, very likely
+ leading to our entire process crashing.
+
+ This can happen if we aren't a privileged process, for example if
+ running as non-root user, or inside an unprivileged container.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2021-03-09 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ configure: drop unnecessary check and define
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ configure: move exec_prefix sanitize
+ Move exec_prefix sanitize closer to prefix. This is not
+ functional change, just group functional tests together.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ configure: drop dead code
+ prefix is sanitized already at the top of configure.ac to /usr,
+ hence the second instance can never hit.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ configure: detect and init pkg-config with macro
+ this also allows to use PKG_CONFIG_* macros immediately
+ in conditional calls
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2021-03-04 Christine Caulfield <ccaulfie@redhat.com>
+
+ main: Close race condition when moving to statedir
+ Found by covscan which also didn't like us 'leaking' the
+ fd to the lockfile. So close that too.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2021-01-14 Jan Friesse <jfriesse@redhat.com>
+
+ init: Use corosync-cfgtool for shutdown
+ ... to trigger cfg shutdown callbacks.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2021-01-14 Christine Caulfield <ccaulfie@redhat.com>
+
+ test: Add testcfg to exercise some cfg functions
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ cfg: Reinstate cfg tracking
+ CFG tracking was removed in 815375411e80131f31b172d7c43625769ee8b53d,
+ probably as a mistake, as part of the tidy up of cfg and the removal of
+ dynamic loading. This means that shutdown tracking (using
+ cfg_try_shutdown()) stopped working.
+
+ This patch restores the trackstart & trackstop API calls (renamed to be
+ more consistent with the exiting libraries) so that shutdown tracking
+ can be used again.
+
+ Change cfg.shutdown_timeout to be in milliseconds rather than seconds
+ nd use libqb macros for conversion.
+
+ Add --force option to corosync-cfgtool -H
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2020-11-26 Jan Friesse <jfriesse@redhat.com>
+
+ cfg: Improve nodestatusget versioning
+ Patch tries to make nodestatusget really extendable. Following changes
+ are implemented:
+ - corosync_cfg_node_status_version_t is added with (for now) single
+ value CFG_NODE_STATUS_V1
+ - corosync_knet_node_status renamed to corosync_cfg_node_status_v1 (it
+ isn't really knet because it works as well for udp(u()
+ - struct res_lib_cfg_nodestatusget_version is added which holds only ipc
+ result header and version on same position as for
+ corosync_cfg_node_status_v1
+ - corosync_cfg_node_status_get requires version and pointer to one of
+ corosync_cfg_node_status_v structures
+ - request is handled in case switches to make adding new version easier
+
+ Also fix following bugs:
+ - totempg_nodestatus_get error was retyped to cs_error_t without any
+ meaning.
+ - header.error was not checked at all in the library
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2020-11-26 Christine Caulfield <ccaulfie@redhat.com>
+
+ cfg: New API to get extended node/link infomation
+ Current we horribly over-use totempg_ifaces_get() to
+ retrieve information about knet interfaces. This is an attempt to
+ improve on that.
+
+ All transports are supported (so not only Knet but also UDP(U)).
+
+ This patch builds best against the "onwire-upgrade" branch of knet
+ as that's what sparked my interest in getting more information out.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2020-11-12 Jan Friesse <jfriesse@redhat.com>
+
+ totemknet: Check both cipher and hash for crypto
+ Previously only crypto cipher was used as a way to find out if crypto is
+ enabled or disabled.
+
+ This usually works ok until cipher is set to none and hash to some other
+ value (like sha1). Such config is perfectly valid and it was not
+ supported correctly.
+
+ As a solution, check both cipher and hash.
+
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2020-11-10 Ferenc Wágner <wferi@debian.org>
+
+ The ring id file needn't be executable
+ At the same time simplify the overwrite logic and stop clearing the
+ umask (which is unexpected and quite pointless here, as applications
+ can't really protect the users from their own pathological settings).
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2020-11-06 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ pkgconfig: export LOGDIR in corosync.pc
+ logdir is configurable at build time and can change
+ from distro to distro. Export the path for pcs to use.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2020-11-02 Jan Friesse <jfriesse@redhat.com>
+
+ spec: Add isa version of corosync-devel provides
+ Also add release to version to match autogenerated corosynclib-devel
+ provides.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2020-10-19 liangxin1300 <XLiang@suse.com>
+
+ totemconfig: remove redundant nodeid error log
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2020-10-15 Aleksei Burlakov <aburlakov@suse.com>
+
+ totemsrp: More informative messages
+ ... when token and consensus timeouts pop.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2020-10-15 Jan Friesse <jfriesse@redhat.com>
+
+ config: Increase default token timeout to 3000 ms
+ Default token timeout of 1000 ms was often changed by users because of
+ other workloads on machine which may make corosync responding a bit
+ later than needed and resulting in token loss.
+
+ 3000 ms was chosen as a compromise between token timeout increase
+ and allow live cluster upgrade (other nodes should receive token
+ by node with new default on time).
+
+ It doesn't affect token token_coefficient so final token timeout still
+ depends on number of configured nodes (just base is higher).
+
+ This change slows down failover a bit so for clusters where failover
+ times are important, please change the token timeout in configuration
+ file corosync.conf as a:
+
+ totem {
+ version: 2
+ token: 1000
+ ...
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2020-10-12 Ferenc Wágner <wferi@debian.org>
+
+ man: votequorum.5: use proper single quotes
+ Backtick and apostrophe are formatted as directional quotes by plain
+ groff, but they behave literally in the body of a man page.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ man: fix typo: avaialable
+ By slightly rewording the documentation of knet_compression_model.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2020-10-12 Jan Friesse <jfriesse@redhat.com>
+
+ tests: Use CS_DISPATCH_BLOCKING instead of cycle
+ Some tests were using dispatch function in CS_DISPATCH_ALL mode
+ without poll/select on fd. This leads to busywait cycle, because
+ CS_DISPATCH_ALL masks CS_ERR_TRY_AGAIN error.
+
+ Simpliest solution is to use CS_DISPATCH_BLOCKING instead and remove
+ while cycle, because CS_DISPATCH_BLOCKING handles CS_ERR_TRY_AGAIN
+ correctly.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ quorum: Add support for nodelist callback
+ Current quorum callback contains only actual view list and there is no
+ way how to find out joined/left nodes. This cannot be emulated by user
+ app, because when corosync restarts before other nodes notices then view
+ list is unchanged (ring id is changed tho).
+
+ Solution is to implement similar callback as for cpg which contains ring
+ id, member list, joined list and left list.
+
+ To implement such callback and keep backwards compatibility,
+ quorum_model_initialize is introduced. Its behavior is similar to
+ cpg_model_initialize. This allows passing model v1, which contains
+ enhanced quorum (full ring id is passed instead of just seq number)
+ and nodelist callbacks.
+
+ To find out which events should be sent by corosync daemon, new message
+ MESSAGE_REQ_QUORUM_MODEL_GETTYPE is used. Quorum library on init was
+ sending MESSAGE_REQ_QUORUM_GETTYPE. Whem model v1 is requested the
+ MESSAGE_REQ_QUORUM_MODEL_GETTYPE is used, which contains model number
+ so corosync knows that client is using model v1 and can send enhanced
+ quorum and nodelist events.
+
+ Nodelist event is (for now) send both in case of change of membership
+ and also when requested, also when CS_TRACK_CURRENT is requested, but
+ then left_list and joined_list is left empty, because they don't make
+ too much sense there.
+
+ New test application testquorummodel is added as an example of new API
+ usage.
+
+ Also during patch developement, I found few bugs here and there, which
+ are also fixed:
+ - quorum_initialize was never returning error code returned by
+ MESSAGE_REQ_QUORUM_GETTYPE call (always returned CS_OK)
+ - Allocated memory in send_library_notification was based
+ on sizeof(unsigned int) instead of mar_uint32_t. That's not wrong,
+ but it make more sense to use sizeof(mar_uint32_t) instead
+
+ (big thanks to Chrissie for englishify the man pages)
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2020-09-30 Christine Caulfield <ccaulfie@redhat.com>
+
+ man: reload during rolling upgrade
+ Make it clear that reloads during a rolling upgrade are not
+ supported.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2020-09-29 Jan Friesse <jfriesse@redhat.com>
+
+ totemsrp: Move token received callback
+ Trigger token received callback only for valid token.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2020-09-24 Jan Friesse <jfriesse@redhat.com>
+
+ common_lib: Remove trailing spaces in cs_strerror
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2020-09-18 liangxin1300 <XLiang@suse.com>
+
+ totemconfig: improve linknumber checking
+ Check whether linknumber larger than INTERFACE_MAX and display error if
+ so.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2020-09-17 liangxin1300 <XLiang@suse.com>
+
+ totemconfig: add interface number to the error str
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ cfg: enhance message_handler_req_lib_cfg_killnode
+ While execute corosync-cfgtool -k <nodeid> to kill node:
+ * Check whether nodeid exists
+ * Check whether the node was joined
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2020-09-03 liangxin1300 <XLiang@suse.com>
+
+ totemconfig: validate totem.transport value
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2020-08-21 liangxin1300 <XLiang@suse.com>
+
+ cmapctl: return error on no result of print prefix
+ return EXIT_FAILURE if no result print for ACTION_PRINT_PREFIX.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ cmapctl: check NULL for key type and value for -p
+ To avoid segmentation fault.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2020-08-20 liangxin1300 <XLiang@suse.com>
+
+ quorumtool: strict check for -o option
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2020-08-19 liangxin1300 <XLiang@suse.com>
+
+ quorumtool: Help shouldn't require running service
+ Do not require corosync running when usage is requested.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2020-08-18 liangxin1300 <XLiang@suse.com>
+
+ cfgtool: Return error when -i doesn't match
+ Give error message and EXIT_FAILURE return code when -i
+ option doesn't match.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2020-08-17 liangxin1300 <XLiang@suse.com>
+
+ man: update output of -s and -b for cfgtool
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ cmapctl: return EXIT_FAILURE on failure
+ For -g and -d option return EXIT_FAILURE when error occurs (most often
+ because key does not exist).
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2020-08-12 liangxin1300 <XLiang@suse.com>
+
+ tools: use util_strtonum for options checking
+ Function atoi is not safe since miss validation;
+ Function strtol is better but need to consider empty string and overflows
+ Function util_strtonum is a safer wrapper of strtoll
+
+ Use util_strtonum to check nodeid option and strict checking condition.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2020-08-11 liangxin1300 <XLiang@suse.com>
+
+ cfgtool: enhancement -a option
+ * Add return code
+ * Give error message when nodeid not exist
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2020-08-07 liangxin1300 <XLiang@suse.com>
+
+ cfgtool: output error messages to stderr
+ ... and standardize the return code
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2020-07-16 Jan Friesse <jfriesse@redhat.com>
+
+ configure: Use default systemd path with prefix
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ build: Use git-version-gen during specfile build
+ Instead of copying parts of git-version-gen for spec target use
+ git-version-gen directly and parse final version into components
+ (rpmver, alphatag, numcomm) and use them.
+
+ Main reason is to simplify code a bit (sed scripts are a bit repetitive
+ tho), reuse the code and also allow building of RPM from dist tarball
+ generated from non-tagged commit or dirty git (not very useful).
+
+ The code relies on fact, that hyphen is never used in tagged release
+ name.
+
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ build: Update git-version-gen
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ spec: Require at least knet 1.18 for crypto reload
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+2020-07-09 Christine Caulfield <ccaulfie@redhat.com>
+
+ config: Allow reconfiguration of crypto options
+ Needs new knet crypto API.
+
+ If it's not available, then fall back to the old
+ API and forbid changing crypto while running.
+
+ To avoid us being dependant on the leader node, each
+ node sends its own crypto_reconfig_phase messages so
+ we can guarantee that the reconfiguration always completes
+ on each node.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2020-05-18 Christine Caulfield <ccaulfie@redhat.com>
+
+ test: Fix cpgtest
+ ... to cope with the max number of group members.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2020-04-24 Christine Caulfield <ccaulfie@redhat.com>
+
+ config: Fix crash when a reload fails twice
+ Have string values stored in char arrays in totem_config
+ so we don't get into a mess with the pointers.
+
+ Also remove vsftype (which hasn't been used since corosync 1)
+
+ Use strncpy even though we know the string is fine. Keep covscan happy
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ config: Don't free pointers used by transports
+ reload failed for UDP[U] because they had saved pointers
+ to the interfaces[] array. so memcpy into that rather then
+ re-allocate it.
+
+ Also, move the check for different IP address families so
+ it also gets run at reload time.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ config: don't reload vquorum if reload fails
+ Fix an 'error: success' stype message by propogating error_string
+ back down the stack.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ cfg: Improve error return to cfgtool -R
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ config: Reorganise the config system
+ To be more reliable & maintainable
+
+ The basic plan here is to fix reloads to be more stable
+ using read/parse/verify/build/commit stages, so that any errors
+ will not leave corosync in an unstable state. This should
+ also make the code more maintainable as currently the verify/commit
+ stages are horribly intertwined.
+
+ Also:
+ - Fix local_node_pos not being updated in the new map during validation
+ (broke adding and removing new nodes in the middle of the list).
+ - Fix reconfiguration so that nodes are indexed by nodeid and not their
+ position in the list. This is an old bug that's just been carried
+ over
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2020-04-22 Jan Friesse <jfriesse@redhat.com>
+
+ Revert "totemip: compare sin6_scope_id and interface_num"
+ This reverts commit efd34df531d1b23d6458dca863a7517b7ac0099d to make
+ master compile after revert of 934c47ed4384daf2819c26306bebba3225807499.
+
+ Revert "totemip: Add support for sin6_scope_id"
+ This reverts commit 934c47ed4384daf2819c26306bebba3225807499 which is
+ causing protocol incompatibility in needle. Master seems to be not
+ affected, but it needs more checking.
+
+2020-03-30 Hideo Yamauchi <renayama19661014@ybb.ne.jp>
+
+ cfgtool: Fix error code as described in MP
+ If all links are connected 0 is returned to the shell, otherwise it's
+ error code 1.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2020-03-26 Christine Caulfield <ccaulfie@redhat.com>
+
+ icmap: icmap_init_r() leaks if trie_create() fails
+ Thanks to Coverity for finding this
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2020-03-24 Jan Friesse <jfriesse@redhat.com>
+
+ votequorum: set wfa status only on startup
+ Previously reload of configuration with enabled wait_for_all result in
+ set of wait_for_all_status which set cluster_is_quorate to 0 but didn't
+ inform the quorum service so votequorum and quorum information may get
+ out of sync.
+
+ Example is 1 node cluster, which is extended to 3 nodes. Quorum service
+ reports cluster as a quorate (incorrect) and votequorum as not-quorate
+ (correct). Similar behavior happens when extending cluster in general,
+ but some configurations are less incorrect (3->4).
+
+ Discussed solution was to inform quorum service but that would mean
+ every reload would cause loss of quorum until all nodes would be seen
+ again.
+
+ Such behaviour is consistent but seems to be a bit too strict.
+
+ Proposed solution sets wait_for_all_status only on startup and
+ doesn't touch it during reload.
+
+ This solution fulfills requirement of "cluster will be quorate for
+ the first time only after all nodes have been visible at least
+ once at the same time." because node clears wait_for_all_status only
+ after it sees all other nodes or joins cluster which is quorate. It also
+ solves problem with extending cluster, because when cluster becomes
+ unquorate (1->3) wait_for_all_status is set.
+
+ Added assert is only for ensure that I haven't missed any case when
+ quorate cluster may become unquorate.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2020-03-13 Jan Friesse <jfriesse@redhat.com>
+
+ quorumtool: exit on invalid expected votes
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ votequorum: Change check of expected_votes
+ Previously value of new expected_votes was checked so newly computed
+ quorum value was in the interval <total_votes / 2, total_votes>. The
+ upper range prevented the cluster to become unquorate, but bottom check
+ was almost useless because it allowed to change expected_votes so it is
+ smaller than total_votes.
+
+ Solution is to check if expected_votes is bigger or equal to total_votes
+ and for quorate cluster only check if cluster doesn't become unquorate
+ (for unquorate cluster one can set upper range freely - as it is
+ perfectly possible when using config file)
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2020-03-04 Jan Friesse <jfriesse@redhat.com>
+
+ cfgtool: Simplify output a bit for link status
+ Display words connected/disconnected instead of 1/0 and show enabled
+ status only when link is not enabled (shouldn't happen).
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2020-02-27 Jan Friesse <jfriesse@redhat.com>
+
+ man: Enhance link_mode priority description
+ Some users found description of priority for passive link_mode
+ confusing (probably because "priority" word is too
+ overloaded) so add some redundancy to make description
+ unambiguous.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ main: Add schedmiss timestamp into message
+ This is useful for matching schedmiss event in stats map with logged
+ event.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2020-02-21 liangxin1300 <XLiang@suse.com>
+
+ totemip: compare sin6_scope_id and interface_num
+ When user configure a specific interface like vlan
+ with the same IPv6 link-local address, Corosync should
+ compare sin6_scope_id with interface_num, to make sure got
+ the right interface to bind
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2020-02-17 Jan Friesse <jfriesse@redhat.com>
+
+ totemip: Really remove totemip_copy_endian_convert
+
+ totemip: Remove unused totemip_copy_endian_convert
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ totemip: Add support for sin6_scope_id
+ sin6_scope_id was not present in totemip structure making impossible to
+ use link-local ipv6 address.
+
+ Patch adds sin6_scope_id and changes convert/copy functions to use it
+ (formally also comparator functions should be changed, but it seems to
+ cause more harm and it is not really needed).
+
+ This makes corosync work with link-local addresses fine for both UDPU
+ and Knet transport as long as interface specification is used (so
+ fe80::xxxx:xxxx:xxxx:xxxx%eth0).
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2020-02-12 Jan Friesse <jfriesse@redhat.com>
+
+ cfgtool: Improve link status display
+ Totemknet is enhanced to use 'n' character for localhost and not adding
+ status, because it is safe to expect that localhost link is always
+ connectd. corosync-cfgtool is enhanced to properly decode 'n', '?' and
+ 'd' characters and display its meaning for extended status. Special
+ characters are also documented in man page.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2020-02-10 Hideo Yamauchi <renayama19661014@ybb.ne.jp>
+
+ totemknet: Change the initial value of the status
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2020-01-23 Jan Friesse <jfriesse@redhat.com>
+
+ stats: Use nanoseconds from epoch for schedmiss
+ Using monotonic time is not working because it doesn't have to match
+ time from epoch.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2020-01-22 Christine Caulfield <ccaulfie@redhat.com>
+
+ stats: Add stats for scheduler misses
+ This patch add a stats.schedmiss.* set of entries that
+ are a record of the last 10 times corosync was not scheduled
+ in time.
+
+ These entries are keypt in reverse order (so stats.schedmiss.0.* is
+ always the latest one kept) and the values, including the timestamp,
+ are in milliseconds.
+
+ It's also possible to use a cmap tracker to follow these events, which
+ might be useful.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2020-01-21 Jan Friesse <jfriesse@redhat.com>
+
+ votequorum: Reflect runtime change of 2Node to WFA
+ When 2Node mode is set, WFA is also set unless WFA is configured
+ explicitly. This behavior was not reflected on runtime change, so
+ restarted corosync behavior was different (WFA not set). Also when
+ cluster is reduced from 3 nodes to 2 nodes during runtime, WFA was not
+ set, what may result in two quorate partitions.
+
+ Solution is to set WFA depending on 2Node when WFA
+ is not explicitly configured.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2020-01-09 Hideo Yamauchi <renayama19661014@ybb.ne.jp>
+
+ cpg: Change downlist log level
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2020-01-07 Ferenc Wágner <wferi@debian.org>
+
+ man: move cmap_keys man page from section 8 to 7
+ Section 8 is for "System administration commands", 7 is "Miscellaneous".
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2019-11-28 Jan Friesse <jfriesse@redhat.com>
+
+ stats: Check return code of stats_map_get
+
+ quorumtool: Assert copied string length
+
+ notifyd: Check cmap_track_add result
+ And assert length of key_name to strcpy.
+
+ cmapctl: Free bin_value on error
+
+ cfgtool: Remove unused callbacks
+
+ cpghum: Remove unused time variables and functions
+
+ votequorum: Assert copied strings length
+
+ totemknet: Assert strcpy length
+
+ totemknet: Check result of fcntl O_NONBLOCK call
+
+ totemconfig: Initialize warnings variable
+
+ sync: Assert sync_callbacks.name length
+
+ totemknet: Don't mix corosync and knet error codes
+ And use correct return code in stats.c.
+
+ stats: Assert value_len when value is needed
+
+ cmap: Assert copied string length
+
+ totemconfig: Reuse already fetched pointer
+ Make code a bit readable and easier to process for coverity.
+
+ logconfig: Remove double free of value
+
+ votequorum: Ignore the icmap_get_* return value
+ Express intention to ignore icmap_get_* return
+ value and rely on default behavior of not changing the output
+ parameter on error.
+
+ totemconfig: Free leaks found by coverity
+
+2019-11-18 Christine Caulfield <ccaulfie@redhat.com>
+
+ icmap: fix the icmap_get_*_r functions
+ Make the icmap*_r functions read from the specified map rather
+ than the global map.
+
+ Also include icmap_get_string_r() which seems to have been missed out.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2019-11-18 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ pkgconfig: Add libqb dependency
+ To make sure libqb dependency is visible across all libraries.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2019-11-08 Jan Friesse <jfriesse@redhat.com>
+
+ Initialize stack allocated memory
+ Some functions allocated memory on stack without clearing memory and
+ then send them on wire. This is not an issue, but valgrind reports this
+ as a problem so it is easy to miss real problem then.
+
+ Solution is to clear stack memory.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2019-10-17 Thomas Lamprecht <t.lamprecht@proxmox.com>
+
+ man: Fix corosync.conf knet pong count default
+ commit 029b8ebad60314d3daa285eb945c55355fade389 changed the default
+ of the KNET_PONG_COUNT from the kronosnet default of 5 to 2, as
+ corosync bring up was deemed to slow.
+
+ The documentation, and the comment stating that the totem config
+ default values match the knet ones were not updated, and thus now out
+ of date.
+
+ Fixhis by noting the correct default of 2 for KNET_PONG_COUNT and
+ note that all but that one are in sync with the korosync defaults in
+ the comment.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2019-10-09 Jan Friesse <jfriesse@redhat.com>
+
+ totemsrp: Reduce MTU to left room second mcast
+ Messages sent during recovery phase are encapsulated so such message has
+ extra size of mcast structure. This is not so big problem for UDPU,
+ because most of the switches are able to fragment and defragment packet
+ but it is problem for knet, because totempg is using maximum packet size
+ (65536 bytes) and when another header is added during retransmition,
+ then packet is too large.
+
+ Solution is to reduce mtu by 2 * sizeof (struct mcast).
+
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ totempg: Check sanity (length) of received message
+ Reviewed-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+2019-10-09 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ build: add option for enabling sanitizer builds
+ --with-sanitizers= option is stricly meant for runtime debugging
+ purposes. Do NOT use in production.
+
+ Please check gcc/clang man pages on how to use ASAN/UBSAN/TSAN.
+
+ Also allow users to specificy SANITIZERS_CFLAGS and SANITIZERS_LDFLAGS
+ for advanced use.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2019-09-10 Jan Friesse <jfriesse@redhat.com>
+
+ totemknet: Add locking for log call
+ Knet callbacks may be called from different thread than main thread. If
+ this happens, log messages may be lost. Most prominent example is when
+ link goes up (logged by main thread) and host_change_callback_fn is
+ called.
+
+ Implemented solution is adding mutex for every log call in totemknet.
+
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+2019-08-27 Jan Friesse <jfriesse@redhat.com>
+
+ man: Fix link_mode priority description
+ ... to match knet source code.
+
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+2019-07-30 Jan Friesse <jfriesse@redhat.com>
+
+ notifyd: Don't dereference NULL key_name
+ This problem shouldn't really happen, but better safe than sorry.
+
+2019-07-15 Jan Friesse <jfriesse@redhat.com>
+
+ totem: Increase ring_id seq after load
+ This patch handles the situation where the leader
+ node (the node with lowest node_id) crashes and is started again
+ before token timeout of the rest of the cluster.
+ The newly restarted node restores the ringid of the old ring from
+ stable storage, so it has the same ringid as rest of the nodes,
+ but ARU is zero. If the node is able to create a singleton membership
+ before receiving the joinlist from rest of the cluster,
+ everything works as expected, because the ring id gets increased
+ correctly.
+
+ But if the node receives a joinlist from another cluster node before
+ its own joinlist, then it continues as it would had it never left
+ the cluster. This is not correct, because the new node should always
+ create a singleton configuration first.
+
+ During the recovery phase, ARUs are compared and because they differ
+ (the ARU of the old leader node is 0), the other nodes
+ try to sent all of their previous messages. This is impossible
+ (even if it was correct), because other nodes have already freed most
+ of those messages. The implementation uses an assert to limit maximum
+ number of messages sent during recovery (we could fix this,
+ but it's not really the point).
+
+ The solution here is to increase the ring_id sequence number by 1 after
+ loading it from storage. During creation of the commit token it is
+ always increased by 4, so it will not collide with an existing
+ sequence.
+
+ Thanks Christine Caulfield <ccaulfie@redhat.com> for clarify commit
+ message.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2019-07-08 Jan Friesse <jfriesse@redhat.com>
+
+ init: Use cpgtool instead of cfgtool
+ Init script used to use corosync-cfgtool -s to wait till
+ corosync accepts ipc connection. Problem with this approach
+ is that error code is returned not only if ipc cannot be initialized,
+ but also when one of the ring is marked as failed, making corosync
+ service not to start. Corosync with one failed ring can work just
+ fine and there is no need to fail startup.
+
+ Patch is changing call of corosync-cfgtool to corosync-cpgtool. Also to
+ make spotting of broken ring easier, corosync-cfgtool -s is called after
+ successful return of the cpgtool, and warning is issued if cfgtool
+ fails.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ notifyd: Fix warning produced by 32-bit compiler
+ time_t is platform dependent real type which is usually long int on
+ 64-bit platform, but only int on 32-bit platform and printing it with
+ %ld generated warning.
+
+ Solution seems to be ether retype time_t to long int or use functions
+ which works with time_t. Later option is used in this patch, which uses
+ localtime and strftime to print time_t value.
+
+ Also code is refactored to remove duplicate calls and add _cs_snmp
+ prefix to prevent snmp_ prefix collision.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ cfgtool: Remove unused code
+ corosync_cfg_ring_status_get returns string status, which is always OK
+ for UDP(U) and detailed status for Knet transport. Previously also
+ FAULTY status was returned for UDP(U) and cfgtool used to return error
+ code back to shell when one of the interfaces was faulty.
+
+ Because FAULTY is now not returned, it's not needed to have code for
+ handling it.
+
+ Also man page was misleading, so it is fixed too.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2019-07-03 Jan Friesse <jfriesse@redhat.com>
+
+ logging: Add CS_PRI_NODE_ID and CS_PRI_RING_ID
+ Previously node id was logged ether as a %d (most often), %u, %x or
+ PRI.32 and ring id ether as %lld, %llx with various separators (., :, /)
+ between rep nodeid and seq. This seems to cause confusion.
+
+ This patch adds macros CS_PRI_NODE_ID, CS_PRI_RING_ID and
+ CS_PRI_RING_ID_SEQ (CS prefix = corosync, PRI modeled in spirit of
+ inttypes.h PRIx32) and makes code use them.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2019-07-02 Jan Friesse <jfriesse@redhat.com>
+
+ vqsim: Fix gitignore
+
+2019-06-28 Jan Friesse <jfriesse@redhat.com>
+
+ totemknet: Disable forwarding on shutdown
+ Disabling forwarding will make knet flush the messages (especially
+ LEAVE one).
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2019-06-17 Jan Friesse <jfriesse@redhat.com>
+
+ totemconfig: Fix compiler warning
+ Compiler is unable to understand relation between members and
+ num_configured and warns about uninitialized members. Instead of
+ initializing members to 0 and (potentially after some code
+ refactor) let code fall to display error message, more explicit method
+ of assert is used.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2019-06-17 Thomas Lamprecht <t.lamprecht@proxmox.com>
+
+ totem: fix check if all nodes have same number of links
+ configured links may not come in order in the interfaces array, which
+ holds an entry for _all_ possible links, not just configured ones.
+
+ So iterate through all interfaces, but skip those which are not
+ configured. This allows to start corosync with a configuration where
+ link 0 is currently not mentioned, as else it was checked but had
+ member_count = 0 from it's default initialization, which then made
+ this code report a false positive for the "Not all nodes have the
+ same number of links" check even on a correct config.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ totem: fix check if all nodes have name attrs in multi-link setups
+ As totem_config->interfaces entries are _all_ possible links and not
+ only the configured ones we cannot trust that interface[0] is
+ configured at the time of checking, and thus has a valid
+ member_count. So set the members variable to the member_count entry
+ from an actually configured interface and loop over that one.
+
+ This fixes a case where the check for the name property on all nodes
+ for multi links was skipped if link 0 was not configured, as then its
+ member_count was 0.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2019-06-14 dkutergin <dmytro.kutergin@harmonicinc.com>
+
+ corosync-notifyd: Add option to disable DNS lookup
+ New configuration option -n is added.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2019-06-14 Jan Friesse <jfriesse@redhat.com>
+
+ totemsrp: Fix warnings produced by gcc 9.1
+ New gcc warn about passing posibly unaligned pointer from packed
+ structure. This shouldn't be problem for x86.
+
+ Implemented solution is to let compiler do its job (compiler knows if
+ pointer is aligned so accessing structure field is safe) and
+ use it together with support for asigning and returning of structure
+ (not a pointer to the structure).
+
+ - srp_addr_copy is removed and replaced by simple assignment
+ - srp_addr_copy_endian_convert is removed and replaced by
+ srp_addr_endian_convert function which takes srp_addr structure and
+ returns endian converted srp_addr structure
+ - functions which accepts srp_addr array are not changed because
+ (luckily) non-aligned pointer is always just one item array and
+ such item is always used as a source pointer so it's possible to use
+ temporary variable
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2019-06-13 Jan Friesse <jfriesse@redhat.com>
+
+ cpg: Move filling of member_list to subfunction
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+ Reviewed-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
+
+ cpg: Add more comments to notify_lib_joinlist
+ And make handling of left_list more generic. Also free skiplist
+ allocated by joinlist_inform_clients function. Last (but not least)
+ remove czechlish founded (should have been pp of "find").
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+ Reviewed-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
+
+2019-06-13 Fabian Grünbichler <f.gruenbichler@proxmox.com>
+
+ cpg: send single confchg event per group on joinlist
+ using a similar approach to
+
+ 43bead364514e8ae2ba00bcf07c460e31d0b1765
+ "Send one confchg event per CPG group to CPG client"
+
+ which did the same for leave events on a network partition.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ cpg: notify_lib_joinlist: drop conn parameter
+ since it is always set to NULL.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2019-06-12 Jan Friesse <jfriesse@redhat.com>
+
+ vqsim: Check length of copied optarg
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ vqsim: Check result of icmap_set_uint32
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ vqsim: Remove unused total_nodes
+ ... and remove unused nodes_in_partition function.
+
+ Also replace TAILQ_FOREACH with goto to while cycle.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ vqsim: Free allocated newvq on error
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ vqsim: Check length of received message
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ vqsim: Check write result
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ vqsim: Do not access unitialized argv[0]
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ totemknet: Initialize return value in setup_nozzle
+ Also add comment why return value is currently not used.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ totemknet: macaddr_str is always set
+ Check for NULL was invalid, because macaddr_str is ether defined in cmap
+ or set to "54:54:01:00:00:00".
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ totemknet: Ignore icmap_get_string result
+ ... and add comment why it is not a bug.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ totemknet: create_nozzle_device simplify check
+ ipaddr existence is checked for being not NULL by caller setup_nozzle.
+ Also ipaddr was passed to reparse_nozzle_ip_address function unchecked
+ so code would crash before reaching the actual check.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ totemip: Use res in totemip_sa_equal
+ Setting res to -1 was not entirely following semantics of "equal"
+ operation. Set it to 0 and return it when families differs makes
+ compiler happy.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ totemconfig: ipaddr_equal use switch
+ Compiler may have problem understanding relation between addr1p and
+ addrlen. Small change makes code a little more readable and compiler
+ happy.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2019-06-10 Jan Friesse <jfriesse@redhat.com>
+
+ configure: Fix GDB_CFLAGS typo
+ GDB_FLAGS (without C) is the correct name of variable
+ to print in the summary.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ man: Add vqsim man page into distributed tarball
+
+2019-06-07 Jan Friesse <jfriesse@redhat.com>
+
+ spec: Add support for user-flags configure option
+ Passing -ggdb3 (or -g3) during compiler may result in corrupted
+ debuginfo files (bug in debugedit - for Fedora filed as a
+ https://bugzilla.redhat.com/show_bug.cgi?id=1708786). Until the bug is
+ fixed it's possible to ether change configure to add -ggdb2/-g2 or use
+ already existing --enable-user-flags option and rely on environment set
+ by rpmbuild.
+
+ Patch implements second option so RPM distros without broken debugedit
+ are not affected.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ man: Enahnce block_unlisted_ips description
+ Thanks Christine Caulfield <ccaulfie@redhat.com> for
+ Englishify and refining the description.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2019-05-31 Jan Friesse <jfriesse@redhat.com>
+
+ man: Enhance corosync.conf mp a bit
+ Fix issues found by Ulrich Windl <Ulrich.Windl@rz.uni-regensburg.de>
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2019-05-30 Fabian Grünbichler <f.gruenbichler@proxmox.com>
+
+ cfgtool: Fix link status display
+ instead of the nodeid, this displayed arbitrary values (usually '1')
+ from other cmap keys under nodelist.node.XX.
+
+ sscanf returns the number of conversions even on mismatch, e.g. it also
+ returns 1 for
+
+ nodelist.node.2.quorum_votes
+ nodelist.node.2.ring0_addr
+ nodelist.node.2.name
+ ...
+
+ instead of just
+
+ nodelist.node.2.nodeid
+
+ which leads to the value of (at least) quorum_votes being stored in
+ nodeid_list in addition to the actual nodeid.
+
+ storing the returned int in a cs_error_t enum also potentially masks
+ errors, so just compare the result with the expectation directly.
+
+ Fixes: c0d14485c3ebdeb2332f7c48acd155163e5b7fc1
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2019-05-29 Jan Friesse <jfriesse@redhat.com>
+
+ knet: Use block_unlisted_ips
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ udpu: Drop packets from unlisted IPs
+ This feature allows corosync to block packets received from unknown
+ nodes (nodes with IP address which is not in the nodelist). This is
+ mainly for situations when "forgotten" node is booted and tries to join
+ cluster which already removed such node from configuration. Another use
+ case is to allow atomic reconfiguration and rejoin of two separate
+ clusters.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2019-05-29 Christine Caulfield <ccaulfie@redhat.com>
+
+ knet: Fix initialising of knet access lists.
+ It needs to be done at both reload and initialize time.
+ Also disable access lists if the config key is removed.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2019-05-29 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ knet: allow corosync to use knet access lists
+ currently knet acl are only available on master
+ but they might be backported
+ to stable1 as they don´t break onwire protocol.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2019-05-28 yuan ren <yren@suse.com>
+
+ man: Enhance token_retransmit description
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2019-05-15 yuan ren <yren@suse.com>
+
+ totemconfig: Fix minimum limit for hold timeout
+ Make sure the retransmit timeout have the lowest limit
+ `MINIMUM_TIMEOUT`. So, the lowest limit of hold should be
+ recalculated.
+
+ Also token timeout and retransmits count should
+ keep a relational expression.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2019-05-13 Christine Caulfield <ccaulfie@redhat.com>
+
+ vqsim: Enhance vqsim
+ 1. Enable scripting of vqsim and add man page
+
+ I've added a 'sleep' command to help with scripting as well as
+ documentation on how to do it.
+
+ 2. Make 'sync' operation much more robust and useful
+
+ Refactored a lot of code to make sure that in sync mode the
+ prompt appears at the 'right' time. What we do is wait for all
+ of the nodes in all partitions to have the same ring_id. If this
+ doesn't happen then the timeout will fire as before.
+
+ 3. Rename binary to corosync-vqsim and add a sub-package for it
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2019-05-02 Christine Caulfield <ccaulfie@redhat.com>
+
+ knet: Fix a couple of errors when adding a new link
+ When adding a new link for the first time you will often see:
+ 1) knet_link_set_ping_timers for nodeid 1, link 1 failed: Invalid
+ argument (22)
+ 2) New config has different knet transport for link 1. Internal value
+ was NOT changed. To reconfigure an interface it must be deleted and
+ recreated. A working interface needs to be available to corosync at all
+ times
+
+ 1) is caused by setting the ping timers twice, once in
+ totemknet_member_add() and once in totemknet_refresh_config().
+ The first time we don't know the value
+ so it's zero and thus display an error. For this we simply check
+ for the zero and skip the knet API call. It's not ideal, but
+ totemconfig needs a lot of reconfiguring itself before we can
+ make this more sane.
+
+ 2) was caused by simply comparing an unconfigured link with
+ a configured one, so OF COURSE, they are going to be different!
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2019-05-02 yuan ren <yren@suse.com>
+
+ totemconfig: fix autogen mcastaddr for ipv6-4
+ When UDP is used as a transport, the error would occur
+ "Multicast address family does not match bind address family"
+ because there is no ipv6 in /etc/hosts specified but using the
+ totem.ip_version: ipv6-4. because
+ the mcastaddr generated (if not specified) only according to
+ the totem.ip_version.
+
+ Solution is to use bindnetaddr (configured or generated from
+ nodelist) addr family.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2019-04-25 Jan Friesse <jfriesse@redhat.com>
+
+ totemconfig: Ensure nodeid is specified for IPv6
+ Thanks Yuan Ren <yren@suse.com> for finding this problem.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2019-04-25 Christine Caulfield <ccaulfie@redhat.com>
+
+ vqsim: Fix vqsim for corosync 3.0
+ A couple of small internal changes in corosync 3.0 broke vqsim.
+ 1) The way the custom config file is specified (no long an env variable)
+ 2) votequorum now needs to know ouZ_node_pos
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2019-04-24 Jan Friesse <jfriesse@redhat.com>
+
+ vqsim: Make vqsim compile
+ Also add vqsim binary to .gitignore.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2019-04-23 Jan Friesse <jfriesse@redhat.com>
+
+ totemconfig: ipaddr_equal check just addr part
+ Checking whole structure is fine for IPv4, but IPv6 contains also scope
+ id, what may be problem for local address. It's possible to use a zone
+ index, but because it's not required when host name is used, it
+ shouldn't be needed when IPv6 address is used.
+
+ Example configuration snip which fails without patch:
+
+ ...
+ nodelist {
+ node {
+ nodeid: 1
+ ring0_addr: fe80::1234:5678:9abc:def1
+ }
+ }
+ ...
+
+ (example succeed when %eth0 is used).
+
+ With patch, zone index is not needed.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2019-04-16 Jan Friesse <jfriesse@redhat.com>
+
+ cpg: Add CPG_REASON_UNDEFINED
+ Previously the reason field for the member_list items
+ in cpg_totem_confchg_fn was unset what may be little confusing.
+
+ Solution is to add a special value CPG_REASON_UNDEFINED and use it for
+ the member_list items.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2019-04-15 Fabian Grünbichler <f.gruenbichler@proxmox.com>
+
+ crypto: re-introduce secauth parameter
+ with the following semantics:
+ - default off
+ - implies crypto_hash SHA256 and crypto_cipher AES256
+ - crypto_* have higher precedence
+ - only applicable for knet, like crypto_*
+
+ this should make upgrading from Corosync 2.x less painful for users that
+ have an explicit secauth=on in their configuration.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2019-04-11 Jan Friesse <jfriesse@redhat.com>
+
+ totemconfig: Remove support for 3des
+ Triple DES is considered as a "weak cipher" since 2016 so there is
+ really no need to support it in the corosync. Thanks to bug in
+ Corosync/Knet/NSS which caused 3des to not work at all,
+ no matter what library was used, we can just remove support for 3des
+ without braking the compatibility.
+
+ Also fix coroparse so:
+ - totem.crypto_type is removed (this is 1.x construct which was not used
+ even in 2.x)
+ - Add checking of totem.crypto_model.
+ - Enumarate possible values for crypto_model, crypto_cipher and
+ crypto_hash error messages
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ keygen: Reflect change in knet
+ Knet commit 1cb36f0cffd4559971826ca4774a88c5b05882fb reduced minimal
+ key length to 1024-bit. Keygen should keep compatibility with already
+ released 3.0.[0-1] so default key length should be 2048 bits. It's
+ possible to use -s argument to generate shorter key - keygen respects
+ minimum/maximum as defined by knet.
+
+ Also fix man page to reflect this change.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2019-04-05 Fabian Grünbichler <f.gruenbichler@proxmox.com>
+
+ set totem.keyfile and totem.key to RO
+ so that we get the nice log message when attempting to modify them at
+ runtime, just like for totem.crypto_* and co.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2019-04-04 Jan Friesse <jfriesse@redhat.com>
+
+ Revert "init: Enable StopWhenUnneeded"
+ This reverts commit 03d9321bc80887d4578744c26c05d61e2d9d4278.
+
+ Reverted because when corosync service is not enabled and corosync
+ is executed by "systemctl start corosync" it is then immediately
+ shutdown because of "Unit not needed anymore. Stopping.".
+
+ This is really not expected behavior.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2019-04-01 yuan ren <yren@suse.com>
+
+ totemsrp: Word spelling mistake
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2019-02-26 Jan Friesse <jfriesse@redhat.com>
+
+ coroparse: Fix compiler warning
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ configure: Do not autodetect nozzle
+ Nozzle is part of kronosnet but it is independent library. Enabling it
+ when detected without ability to turn it off is not in line with
+ other libraries.
+
+ Solution is to use same method as for other libraries - add
+ --enable-nozzle to configure script and add support for this option into
+ spec file.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2019-02-26 Christine Caulfield <ccaulfie@redhat.com>
+
+ nozzle: Add support for libnozzle devices
+ A nozzle device is a pseudo ethernet device that routes network
+ traffic through a channel on the corosync knet network (NOT cpg or any
+ corosync internal service) to other nodes in the cluster. It allows
+ applications to take advantage of knet features such as multipathing,
+ automatic failover, link switching etc.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2019-02-15 Jan Friesse <jfriesse@redhat.com>
+
+ quorumtool: Fix exit status codes
+ 1. Use EXIT_SUCCESS and EXIT_FAILURE when possible
+ 2. For -s option return EXIT_SUCCESS when no problem appeared and node
+ is quorate, EXIT_FAILURE if problem appeared and exit code 2
+ (EXIT_NOT_QUORATE) when no problem appeared but node is not quorate.
+ 3. Document exit codes in the man page
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2019-02-14 Jan Friesse <jfriesse@redhat.com>
+
+ corosync-cfgtool: Fix -i matching
+ Previously it was required to use link id together with IP address (ex.
+ "0 127.0.0.1") as a -i parameter.
+
+ This was reported as not very user friendly. Solution is to split
+ returned interface name and try match link id and ip address
+ separately.
+
+ Also fix typo in description of parameter -s.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2019-02-06 Ferenc Wágner <wferi@debian.org>
+
+ build: Use the AWK variable provided by configure
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ build: Use the SED variable provided by configure
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ configure.ac: AC_PROG_SED is already present
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ corosync.conf.5: typography fixes
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ corosync.conf.5: fix grammar
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2019-02-04 Christine Caulfield <ccaulfie@redhat.com>
+
+ cfgtool: Improve link status display
+ Now show the nodeids properly, rather than node indexes which were
+ annoying and unhelpful.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2019-01-18 Jan Friesse <jfriesse@redhat.com>
+
+ doc: Update INSTALL file
+ - Add LibQB and Knet links
+ - Remove old (pre udpu) config file example
+ - Change corosync.conf man page to contain useful information about
+ token timeout
+
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2019-01-11 Jan Pokorný <jpokorny@redhat.com>
+
+ init: Enable StopWhenUnneeded
+ It shall be a rule of thumb not to combine "application stack"
+ components run under particular init/supervision mechanism and
+ run by whatever other means (without transitive relationships
+ like when corosync's client runs from other pacemaker that is
+ itself started through systemd) when there's a directed graph
+ of reliance between them (sans constrained corner cases like
+ when of such components is a kernel module).
+
+ And corosync on its own is just a service provider that only
+ appears useful when utilized as a basic building block for
+ application specific distributed environments.
+
+ Therefore, we may assume whenever corosync gets started by the
+ means of systemd, it's because of a mechanized attempt to satisfy
+ declared dependency of some such corosync's client that is about
+ to be started under the service manager realms (directly or, by
+ induction, through the same triggering mechanism indirectly).
+ Hence, when there's no such client around anymore (unless
+ this dependant is being restarted at the moment, see below)
+ corosync shall rather shutdown as well.
+
+ In the past, there was an issue with systemd regarding said
+ inflicted restart of the dependant/client, but that's resolved
+ as of v236:
+ https://github.com/systemd/systemd/commit/
+ deb4e7080db9dcd2a1d51ccf7c357f88ea863e54
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2019-01-11 Jan Friesse <jfriesse@redhat.com>
+
+ totemip: Use AF_UNSPEC for ipv4-6 and ipv6-4
+ AF_UNSPEC returns different results than AF_INET/AF_INET6, because of
+ nsswitch.conf search is in order and it stops asking other
+ modules once current module success.
+
+ Example of difference between previous and new code when ipv6-4 is used:
+ - /etc/hosts contains test_name with an ipv4
+ - previous code called AF_INET6 where /etc/hosts failed so other methods
+ were used which may return IPv6 addr -> result was ether fail or IPv6
+ address.
+ - new code calls AF_UNSPEC returning IPv4 defined in /etc/hosts ->
+ result is IPv4 address
+
+ New code behavior should solve problems caused by nss-myhostname.
+
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+2019-01-03 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ [totemknet] update for libknet.so.2.0.0 init API
+ more changes are to be expected on this front as the API evolves in
+ knet master.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2019-01-03 Ferenc Wágner <wferi@debian.org>
+
+ Config version must be specified
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ Don't declare success early
+ Here we're very far from entering the main loop, even farther from
+ sending the READY notification to systemd. This sounded awkward:
+
+ systemd[1]: Starting Corosync Cluster Engine...
+ corosync[827]: [MAIN ] Corosync Cluster Engine ('2.99.5'):
+ started and ready to provide service.
+ corosync[827]: [MAIN ] Corosync built-in features: dbus monitoring
+ watchdog augeas systemd xmlconf snmp pie relro bindnow
+ corosync[827]: [MAIN ] parse error in config: No interfaces defined
+ corosync[827]: [MAIN ] Corosync Cluster Engine exiting with status 8
+ at main.c:1378.
+ systemd[1]: corosync.service: Main process exited, code=exited,
+ status=8/n/a
+ systemd[1]: corosync.service: Failed with result 'exit-code'.
+ systemd[1]: Failed to start Corosync Cluster Engine.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ More natural error messages
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2018-12-14 Jan Friesse <jfriesse@redhat.com>
+
+ main: Rename run_dir to state_dir
+ system.run_dir was a little bit unfortunate and confusing name. Rename
+ to state_dir makes more evident what is content of this directory. To
+ keep setting consistent with code, get_run_dir is changed to
+ get_state_dir.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ totemconfig: Enhance totem.ip_version
+ Originally totem.ip_version was used to force ip version used by totem.
+ With Knet this variable didn't make too much sense so it was not used.
+
+ Sadly rely only on DNS resolver order doesn't always work (RFC is quite
+ complicated, but if IPv6 is not configured then IPv4 is preferred), what
+ we tried to solve by forcing IPv6 and only if that fails, use IPv4.
+
+ Sadly this collides with nss_myhostname which is able to return every
+ local address and today system usually have at least one autogenerated
+ link-local IPv6 address so it is able to "overwrite" /etc/hosts.
+
+ Solution is to enhance totem.ip_version and use it also for Knet.
+ totem.ip_version is now just a flag for resolver and can have four
+ states: ipv4 (only IPv4 is used), ipv6 (only IPv6 is used), ipv4-6 (ask
+ IPv4 first and if it fails ask for IPv6) and ipv6-4 (ask IPv6 first and
+ if it fails ask for IPv4). Default for Knet and UDPU transports is
+ ipv6-4, for UDP it's ipv4, because autogenerated mcast addr doesn't play
+ too well with ipv6-4.
+
+ So everywhere where nss_myhostname becomes problem, it's just possible
+ to set totem.ip_version to ipv4-6.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2018-12-13 Jan Friesse <jfriesse@redhat.com>
+
+ totemip: Add debug information to totemip_parse
+ It's required to create TOTEM logsys subsys before totemip_parse is used
+ (so before totem_config_read). Logsys is not yet fully initialized, but
+ it's good enough.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ totemconfig: Add IPs to family mismatch error
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2018-12-11 Christine Caulfield <ccaulfie@redhat.com>
+
+ config: Look up hostnames in a defined order
+ Current practice is to let getaddrinfo() decide which address we get
+ but this is not necessarily deterministic as DNS servers won't
+ always return addresses in the same order if a node has
+ several. While this doesn't deal with node names that have
+ multiple IP addresses of the same family (that's an installation issue
+ IMHO) we can, at least, force a definite order for IPv6/IPv4 name
+ resolution.
+
+ I've chosen IPv6 then IPv4 as that's what happens on my test system (
+ using /etc/hosts) and it also seems more 'future proof'.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2018-12-11 Ferenc Wágner <wferi@debian.org>
+
+ Fix corosync.conf.5 manpage typos
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2018-12-10 Christine Caulfield <ccaulfie@redhat.com>
+
+ man: Add some information about address resolution
+ to corosync.conf(5)
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2018-12-10 Jan Friesse <jfriesse@redhat.com>
+
+ totemconfig: Really use totemip_parse results
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2018-12-06 Christine Caulfield <ccaulfie@redhat.com>
+
+ man: Add instructions for adding/removing nodes
+ This replaces the 'cmaptool' method previously documented
+ in cmap_keys.8
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ config: Disallow corosync-cmapctl updates of nodelist
+ It didn't work anyway (the config system requires whole links
+ to be configured at once) and caused crashes.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2018-12-03 Christine Caulfield <ccaulfie@redhat.com>
+
+ config: Report IP addr/nodename parse errors back
+ Corosync used to just ignore parse errors so that un-resolved names
+ could cause silent failures. We now always check the result from
+ totemip_parse() and at least print something in syslog.
+
+ There's also a little get-out here that allows you to correct
+ a bad node address without having to destroy and recreate the
+ whole link. I'm being nice to you.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2018-11-29 Jan Friesse <jfriesse@redhat.com>
+
+ coroparse: Remove unused cs_err initialization
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ cpghum: Check cpg_local_get return code
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ testcpg2: Check cpg_dispatch return code
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2018-11-16 Jan Friesse <jfriesse@redhat.com>
+
+ notifyd: Delete registered tracking keys
+ Forward port of needle 70fd66767494872b93018949d685f19482cd5bec by Hideo
+ Yamauchi <renayama19661014@ybb.ne.jp>.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ stats: Fix delete of track
+ When cmap_track_delete was called to stats map (cmap created with
+ CMAP_MAP_STATS parameter) result was always ERR_BAD_HANDLE.
+
+ It turned out that corosync part of cmap is always calling icmap
+ function to get user data (where required hdb handle is stored)
+ instead of generalized map_fns.
+
+ After fixing this issue, valgrind showed error about jump depending on
+ unitialized data in stats_map_track_delete. Solution seems to be always
+ initialize tracker->events (so not only when track_type is add or
+ delete).
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2018-11-15 Jan Friesse <jfriesse@redhat.com>
+
+ init: Fix init script to work with containers
+ Previously init scripts were not using pid file so pidof was used. This
+ is usually not a problem, but when containers are used it may result to
+ killing improper instance when issued on host.
+
+ Solution is to always use pidfile.
+
+ Also try to use LSB complaint status codes.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ main: Remove COROSYNC_RUN_DIR
+ Remove last used environment variable (reasons similar to removal of
+ COROSYNC_MAIN_CONFIG_FILE).
+
+ This environment variable was never documented, so document it properly.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ man: Describe nodelist.node.name properly
+ Old description is no longer true, because with knet transport name got
+ new and very important role.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ main: Remove COROSYNC_TOTEM_AUTHKEY_FILE
+ Remove another environment variable (reasons similar to removal of
+ COROSYNC_MAIN_CONFIG_FILE).
+
+ Also properly document both totem.keyfile and totem.key.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ main: Replace COROSYNC_MAIN_CONFIG_FILE
+ COROSYNC_MAIN_CONFIG_FILE environment variable was quite well hidden
+ and it was never used by init script. It also makes quite hard to debug
+ possible problems.
+
+ Replace it by -c option.
+
+ Also patch makes use of configuration file path as a base for uidgid.d
+ directory, so it's no longer needed to keep uidgid.d in sysconfdir.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ main: Move sched paramaters to config file
+ The reason for this change is, that number of corosync CLI options
+ kind of exploded and scheduler based one are really beter to be kept in
+ config file.
+
+ Nice side-effect of this move is better "integration" with systemd,
+ because currently used EnvironmentFile should be really used for
+ environment and not that much for passing extra options to CLI.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2018-11-07 Jan Friesse <jfriesse@redhat.com>
+
+ configure: move to AC_COMPILE_IFELSE
+ from AC_PREPROC_IFELSE which is strongly discouraged.
+
+ Our detection system was very weak and recent versions of clang did
+ show that PREPROC_IFELFE (cpp) would enable warning options that
+ the compiler does not support (clang).
+
+ Use a full compilation test to detect what works and what doesn't.
+
+ Based on knet patch 88491f27375a9e8aceb946853a1abf4d23ebb8f3.
+
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+2018-10-29 Jan Friesse <jfriesse@redhat.com>
+
+ logsys: Make hires timestamp default
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ logsys: Support hires timestamp
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ totemconfig: Fix logging of freed string
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2018-10-25 Christine Caulfield <ccaulfie@redhat.com>
+
+ config: Allow generated nodeis for UDP & UDPU
+ The conversion to the new srp_addr format broke the feature where
+ UDP/UDPU nodes could get their nodeids generated from the IP address.
+
+ A big part of this was the removal of mandatory ring0_addr - it was used
+ as a placeholder when reading down the nodelist. I replaced this with
+ nodeid thinking that nodeid was now mandatory, forgetting this use case.
+ So the compare on "ring0_addr" or "nodeid" is now replaced with a more
+ robust check that we're only reading keys from the same node_pos once,
+ this was needed in votequorum.c as well as totemconfig.c
+
+ Another tidying side-effect of this patch is that the nodeid generation
+ is now all in a single routine in totemconfig.c and not shared between
+ it and totemip.c.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2018-10-22 Jan Friesse <jfriesse@redhat.com>
+
+ config example: Migrate to newer syntax
+ Default config is knet with nodelist so extra udpu example is no longer
+ needed.
+
+ XML variant of corosync config never got expected usage, so delete
+ example config too.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2018-10-16 Jan Friesse <jfriesse@redhat.com>
+
+ log: Implement support for reopening log files
+ Feature depends on existence of libqb function qb_log_file_reopen.
+
+ New function call is added into CFG service API. This function is
+ used by corosync-cfgtool which now accepts -L parameter.
+
+ Finally, logrotate "postrotate" script is calling
+ corosync-cfgtool -L to notify corosync, instead of using
+ copytruncate option.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ totemconfig: Replace strcpy by strncpy
+ Formally not needed, because totemip_print should not return string
+ longer than INET6_ADDRSTRLEN, but static analysis tools are not capable
+ of such conclusion.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2018-10-15 Christine Caulfield <ccaulfie@redhat.com>
+
+ config: Fix crash in reload if new interfaces are added
+ This is a bug I seem to have introduced in
+ 429209f4aa3c55504a49833e0004489f241e7819 where we compare links
+ for changes. if a new node was added on an existing link then it
+ was compared against a non-existant one in the previous configuration.
+ We now only compare nodes that are in both interfaces.
+
+ As I needed min() for this function, I moved it from individual
+ .c files into util.h so we only have one copy.
+
+ And the error message was fixed.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2018-10-04 Jan Friesse <jfriesse@redhat.com>
+
+ man: Fix default knet_pmtud_interval to match code
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2018-09-27 Jan Friesse <jfriesse@redhat.com>
+
+ build: Remove totempg shared library leftovers
+ Because totempg is not distributed it doesn't make sense to distribute
+ totem header files. Also pkgconfig file should not be created any more.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2018-09-25 Jan Friesse <jfriesse@redhat.com>
+
+ build: Do not compile totempg as a shared library
+ Instead of compiling totempg as a shared library, compile all totem code
+ directly into corosync binary.
+
+ Main idea of having totempg which may be
+ used in other projects was nice, but never really finished (and as far
+ as I know no project were ever really using it). So at the end of the
+ day, we've end with huge amount of problems (need to pass new arguments
+ thru X layers, hard debugging, ...) without any real benefit.
+
+ For a future version, we may consider to revisit idea of split totemsrp
+ into well tested library without unrelated bits like transports/ip/...
+
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2018-09-24 Ferenc Wágner <wferi@debian.org>
+
+ man: Fix typo conains -> contains
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ man: Fix typo connnections -> connections
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2018-09-17 Jan Friesse <jfriesse@redhat.com>
+
+ build: Remove NSS dependencies
+ Complete removal of NSS from corosync tree. Most of the changes are
+ in build system and cpgverify had to be rewritten to use crc32 instead
+ of sha1.
+
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ cts: Remove CTS
+ There are several reasons for removal of CTS:
+ 1. It's not actively maintained
+ 2. It's quite hard to setup
+ 3. It has hard to fix bug in it's design (syslog messages are thrown by
+ rsyslog (configurable), journald (configurable) or when rsyslog is
+ used together with journald (non configurable)) so test
+ can fail just because of lost message.
+ 4. It depends on pacemaker CTS, which is changed quite often
+ 5. CTS itself is great tool for Pacemaker
+ (shutdown/startup of the node), but Corosync has a slightly
+ different needs
+ 6. Bin Liu <bliu@suse.com> made a heroic effort to port it to Python 3
+ (huge thanks), but it's still not fully complete
+
+ All and all, if somebody is interested in maintaining CTS code, please
+ create repository similar to corosync flatiron cts and let us know.
+
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2018-09-13 Jan Friesse <jfriesse@redhat.com>
+
+ man: Fix crypto_hash and crypto_cipher defaults
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2018-09-07 Jan Friesse <jfriesse@redhat.com>
+
+ coroparse: Fix newly introduced warning
+ Small fix for a problem introduced by "coroparse: Use key_name for error
+ message" patch.
+
+2018-09-07 Chris Walker <cwalker@cray.com>
+
+ Add option to force cluster into GATHER state
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2018-09-06 Jan Friesse <jfriesse@redhat.com>
+
+ coroparse: Use key_name for error message
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ coroparse: Add file name and line to error message
+ It's just much easier to find out what is happening when message like
+
+ parser error: /etc/corosync/corosync.conf:39: Unexpected closing brace
+
+ is logged instead of
+
+ parser error: Unexpected closing brace
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ coroparse: Be more strict in what is parsed
+ Corosync parser is not very clever, but it is able to detect more errors
+ without too much code.
+
+ 1. Check if section name is not empty (just '{' character)
+ 2. Check if there is no extra characters after opening bracket '{'
+ 3. Check if there is no extra characters after or before closing bracket
+ '}'
+ 4. Check if line is opening section, closing section or key/value
+
+ So following examples are reported as error:
+
+ totem {
+ version: 2
+ }}}}}}}}}}
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ coroparse: Fix remove_whitespace end condition
+ When remove_whitespace function parameter is single character string
+ with whitespaces (like a:) then colon is not removed. Reason is end
+ condition end != start, which is valid for empty string, but invalid in
+ case described above. Solution is to check if *end is '\0'.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ coroparse: Check icmap_set results
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ coroparse: Return error if config line is too long
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2018-09-05 Jan Friesse <jfriesse@redhat.com>
+
+ notifyd: Propagate error to exit code
+ When it's impossible to dispatch cmap/quorum messages exit code of
+ corosync-notifyd shouldn't be success.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2018-09-03 Jan Friesse <jfriesse@redhat.com>
+
+ git-version-gen: Fail on UNKNOWN version
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ build: Support for git archive stored tags
+ Attempt to solve problem with git archive generated tarballs
+ (used for example by github when release is downloaded) which are no
+ longer git tree and (in contrast to officially released tarballs) also
+ doesn't contain .tarball-version file so git-version-gen script simply
+ cannot obtain valid version info.
+
+ Solution is based on using gitattributes which is instructs git to
+ replace string in the .gitarchivever file by known ref names.
+ git-version-gen is enhanced to support this file and tries to parse
+ any string which looks like "tag: v[0-9]+.[0-9]+.[0-9]". If such string
+ is found it's used as a version. This file is used as a last attempt and
+ other methods (.tarball-version, git abbrev) have precedence.
+
+ Based on idea stated by Jan Pokorný <jpokorny@redhat.com>.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2018-08-20 Ferenc Wágner <wferi@debian.org>
+
+ man: fix cmap key name runtime.config.totem.token
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2018-08-14 Jan Friesse <jfriesse@redhat.com>
+
+ Remove libcgroup
+ Libcgroup is deprecated and not shipping with new distributions
+ (OpenSuSE is one example). Solution is to have a partial implementation
+ of required functionality of libcgroup in the corosync code.
+
+ Patch uses hardcoded cgroup mount point, because most of the systems are
+ now systemd and systemd is also using hardcoded mountpoint (see
+ https://github.com/systemd/systemd/blob/master/src/core/mount-setup.c)
+
+ Configuration option --enable-cgroup is gone, because it's not needed
+ any longer.
+
+ Big thanks to Christine Caulfield <ccaulfie@redhat.com> for example of
+ simplified implementation of cgroup management code primitives.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2018-08-14 Jan Pokorný <jpokorny@redhat.com>
+
+ systemd: prevent redundancy in journal
+ Originating from a dual sink (stderr and syslog).
+
+ Annotated example from "journalctl -b --no-hostname -u corosync":
+
+ Aug 14 00:27:45 corosync[5203]: [MAIN ] Corosync Cluster
+ Engine ('2.99.3'): started and ready to provide service.
+ ^ from syslog source
+ Aug 14 00:27:45 corosync[5203]: notice [MAIN ] Corosync Cluster
+ Engine ('2.99.3'): started and ready to provide service.
+ ^ from stderr source
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2018-08-14 Chris Walker <cwalker@cray.com>
+
+ Add token_warning configuration option
+ Token_warning is used to present information about
+ when the token was last received.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2018-08-13 Jan Friesse <jfriesse@redhat.com>
+
+ corosync-notifyd: Rename global local_nodeid
+ To prevent warning in functions where local_nodeid is also passed as
+ local parameter.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ totemsrp: Add assert into memb_lowest_in_config
+ Add assert when there are no members in token_memb structure so
+ non-existing member is not accessed (token should always have
+ at least one member).
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ totemconfig: Enlarge error_string_response
+ ... so error_reason can be fully included into parse error message.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ ipc_glue: Fix strncpy in pid_to_name function
+ Trailing zero is always added so there is no need to have a warning
+ about unterminated destination string.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ cmap: Fix strncpy warning in cmap_iter_next
+ cmap_iter_next in contrast of it's icmap counterpart copies key name
+ into user preallocated space. In the worst case, key name may be
+ CMAP_KEYNAME_MAXLEN, so cmap_iter_next then need CMAP_KEYNAME_MAXLEN +
+ additional byte to store zero. strncpy was copying only
+ CMAP_KEYNAME_MAXLEN characters so there was possibility of unterminated
+ string.
+
+ Patch solves this by using memcpy and always add trailing zero.
+ Documentation was improved suggesting minimum size of keyname buffer to
+ be CMAP_KEYNAME_MAXLEN + 1.
+
+ Also sam and quorumtool were using too short buffer so they are fixed too.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ util: Fix strncpy in setcs_name_t function
+ Trailing zero is always added so there is no need to have a warning
+ about unterminated destination string.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ totemknet: Free instance on failure exit
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2018-08-09 Jan Friesse <jfriesse@redhat.com>
+
+ spec: Add explicit gcc build requirement
+ Also remove %clean macro which is not needed for ages.
+
+2018-08-09 Chris Walker <cwalker@cray.com>
+
+ Add option for quiet operation to corosync-cmapctl
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2018-07-12 Jan Friesse <jfriesse@redhat.com>
+
+ totemudpu: Pass correct paramto totemip_nosigpipe
+ Fixes compilation on (at least) FreeBSD.
+
+2018-07-12 Bin Liu <bliu@suse.com>
+
+ totemudpu: Add local loop support
+ This patch intends to solve long time ifdown corosync problem. Idea is
+ to use local socket for sending both unicast and multicast messages if
+ interface is down.
+
+ Together with testing what is current bind state it's possible to keep
+ pretending existence of old IP address instead of rebinding to localhost
+ what breaks a lot things badly.
+
+ Heavilly based on Yu, Zou <zouyu@shiqichuban.com> work and it's
+ basically port of UDP patch created by
+ Jan Friesse <jfriesse@redhat.com>.
+
+ (ported from needle 96354fba72b7e7065610f37df0c0547b1e93ad51)
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2018-07-03 Christine Caulfield <ccaulfie@redhat.com>
+
+ config: Fail config validation if not all nodes have all links
+ KNET requires that all links be full-mesh (this may change in the future
+ but almost certainly not before knet 2.0), so enforce this in the
+ config.
+
+ Also avoid a potential div-by-0 error if the local node is not fully
+ configured either.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ config: Enforce use of 'name' node attribute in multi-link clusters
+ If the local host does not have a 'name' attribute and the cluster
+ has more than one link then fail the validation test.
+
+ I'm open to the idea of checking all of the nodes in the nodelist
+ if necessary. It seems overkill as each node will check its own
+ entry though.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2018-07-02 Christine Caulfield <ccaulfie@redhat.com>
+
+ totemconfig: Check for things that cannot be changed on the fly
+ There are a few things in the interface that cannot be changed on the
+ fly. Warn about them and tell the user that these things need to be done
+ in two steps and why.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2018-07-02 Jan Friesse <jfriesse@redhat.com>
+
+ Fix snprintf warnings
+ Compiler shows warnings about possible not large enough buffer, so check
+ snprintf return value properly.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ init: Use existing env variable from sysconf
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ upstart: Remove notifyd upstart unit
+ Hopefully this is last upstart bit.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2018-07-02 Christine Caulfield <ccaulfie@redhat.com>
+
+ knet: Don't try to create loopback interface twice
+ It wasn't hardmful, but it generated an annoying message
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ knet: Fix knet log buffer size
+ knet sends log messages as struct knet_log_msg, not a string
+ of KNET_MAX_LOG_MSG_SIZE (which is only part of that structure).
+ So we were both losing and corrupting messages.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2018-04-30 Jan Friesse <jfriesse@redhat.com>
+
+ cpg: Inform clients about left nodes during pause
+ Patch tries to fix incorrect behaviour during following test-case:
+ - 3 nodes
+ - Node 1 is paused
+ - Node 2 and 3 detects node 1 as failed and informs CPG clients
+ - Node 1 is unpaused
+ - Node 1 clients are informed about new membership, but not about Node 1
+ being paused, so from Node 1 point-of-view, Node 2 and 3 failure
+
+ Solution is to:
+ - Remove downlist master choose and always choose local node downlist.
+ For Node 1 in example above, downlist contains Node 2 and 3.
+ - Keep code which informs clients about left nodes
+ - Use joinlist as a authoritative source of nodes/clients which exists
+ in membership
+
+ This patch doesn't break backwards compatibility.
+
+ I've walked thru all the patches which changed behavior of cpg to ensure
+ patch does not break CPG behavior. Most important were:
+ - 058f50314cd20abe67f5e8fb3c029a63b0e10cdc - Base. Code was significantly
+ changed to handle double free by split group_info into two structures
+ cpg_pd (local node clients) and process_info (all clients). Joinlist
+ was
+ - 97c28ea756cdf59316b2f609103122cc678329bd - This patch removed
+ confchg_fn and made CPG sync correct
+ - feff0e8542463773207a3b2c1f6004afba1f58d5 - I've tested described
+ behavior without any issues
+ - 6bbbfcb6b4af72cf35ab9fdb4412fa6c6bdacc12 - Added idea of using
+ heuristics to choose same downlist on all nodes. Sadly this idea
+ was beginning of the problems described in
+ 040fda8872a4a20340d73fa1c240b86afb2489f8,
+ ac1d79ea7c14997353427e962865781d0836d9fa,
+ 559d4083ed8355fe83f275e53b9c8f52a91694b2,
+ 02c5dffa5bb8579c223006fa1587de9ba7409a3d,
+ 64d0e5ace025cc929e42896c5d6beb3ef75b8244 and
+ b55f32fe2e1538db33a1ec584b67744c724328c6
+ - 02c5dffa5bb8579c223006fa1587de9ba7409a3d - Made joinlist as
+ authoritative source of nodes/clients but left downlist_master_choose
+ as a source of information about left nodes
+
+ Long story made short. This patch basically reverts
+ idea of using heuristics to choose same downlist on all nodes.
+
+ (ported from needle 9c2a97f4f96b9639d07e2a9fe378c28ab1963191)
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2018-04-25 Chris Lamb <lamby@debian.org>
+
+ man: Make the manpages reproducible
+ Whilst working on the Reproducible Builds effort [0], we noticed
+ that corosync could not be built reproducibly.
+
+ This is because, whilst it uses SOURCE_DATE_EPOCH[1], the output
+ varies depending on the current timezone.
+
+ (The LC_ALL is not needed as we only use %Y-%m-%d)
+
+ This was originally filed in Debian as #896441.
+
+ [0] https://reproducible-builds.org/
+ [1] https://reproducible-builds.org/specs/source-date-epoch/
+ [2] https://bugs.debian.org/896441
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2018-04-23 Jan Friesse <jfriesse@redhat.com>
+
+ totemsrp: Fix leave message regression
+ Leave message in totem is just join message where leaving member is
+ excluded from member list and included in fail list. It also contains
+ special nodeid in header.nodeid and system_from.nodeid fields.
+
+ Before "totem: Use nodeid ONLY in srp_addr" fix, most of the functions
+ were using system_from addresses and not nodeid, which was used only in
+ one specific case for memb_consensus_set function.
+
+ After the patch, addresses are gone and only nodeid is used. Result is,
+ that leaving node nodeid is not added into local fail list
+ (my_faillist) so node is unable to reach consensus till token timeout,
+ which starts new gather process.
+
+ Solution is to send valid leaving node nodeid in system_from.nodeid and
+ handle specific case for memb_consensus_set in memb_join_process.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ totemsrp: Log proc/fail lists in memb_join_process
+ These information are useful and with trace log level they should not be
+ too much irritating.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ totemsrp: Fix srp_addr_compare
+ There is regression caused by "totem: Use nodeid ONLY in srp_addr" patch
+ in srp_addr_compare function. This function should be usable with qsort,
+ so it should return values less than, equal to or greater than zero. It
+ was however returning only zero or negation of a zero. Final results
+ were unable to reach consensus in following test case:
+ - 3 node cluster
+ - start nodes 1, 2, 3
+ - shutdown node 3
+ - start node 3
+ - shutdown node 2
+ - start node 2
+ - shutdown node 1
+
+ After this steps, node 2 and 3 were unable to reach consensus.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2018-04-23 Ferenc Wágner <wferi@debian.org>
+
+ tools: don't distribute what we can easily make
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2018-04-23 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ Drop all references to SECURITY file
+ File was removed by 6bdf0962ad035ac659bcbf36a918fe39931ed75d.
+ Patch fixes master branch build again.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2018-04-20 Jan Friesse <jfriesse@redhat.com>
+
+ SECURITY: Remove SECURITY file
+ Basically no information from SECURITY file is valid.
+
+ Library interface and related uidgid are better described in manpages.
+
+ LibNSS is not directly used any longer.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2018-04-20 Ferenc Wágner <wferi@debian.org>
+
+ NSS_NoDB_Init: the parameter is reserved, must be NULL
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ Fix typo: defualt -> default
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ Fix typo: sucesfully -> successfully
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2018-04-12 Jan Friesse <jfriesse@redhat.com>
+
+ totemsrp: Check join and leave msg length
+ If number of proc_list, failed_list or active members is too high it
+ may be impossible to put them into message, which is allocated on the
+ stack what results in stack corruption.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ totemsrp: Implement sanity checks of received msgs
+ Sanity checkers are used to prevent crashing because of
+ accessing unallocated memory.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2018-04-11 Rytis Karpuška <rytisk@neurotechnology.com>
+
+ cpg: Handle fragmented message sending interrupt
+ It turns out that there are some legitimate cases where fragmented
+ messages might be interrupted during sending (e.g. CS_ERR_TRY_AGAIN or
+ as in my case: CS_ERR_INTERRUPT). This creates a situation where
+ LIBCPG_PARTIAL_FIRST is sent multiple times before receiving
+ LIBCPG_PARTIAL_LAST.
+
+ Solution is to drop incomplete message and start assembly of new message
+ as libcpg should have reported error during sending of that
+ incomplete message.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2018-03-16 Jan Friesse <jfriesse@redhat.com>
+
+ totem: Display IP of sender
+ To make finding victim of incompatible messages easier, IP of sender is
+ logged. Propagating IP in layers makes patch slightly larger.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ totemsrp: Add magic and version into header
+ Magic number (0xC070) together with version in every packet
+ is used for detecting that other node is really
+ Corosync 3.x.
+
+ Endian_detector field is removed and magic number is now
+ used instead.
+
+ If received packet magic number differs, guessing is used to show more
+ about the source (Corosync 2.3+, 2.2 are quite reliable, Knet and
+ unencrypted Corosync 2.1/2.0/1.x/OpenAIS are semi-reliable and encrypted
+ Corosync 2.1/2.0/1.x/OpenAIS are quite unreliable).
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2018-03-16 Christine Caulfield <ccaulfie@redhat.com>
+
+ knet: Fix display of links with unconfigured link0
+ because totemknet always configures link0 as loopback even
+ if it's not known to corosync, we need to filter it
+ out when returning the link status, as things get misaligned
+ in cfg.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2018-03-02 Jan Friesse <jfriesse@redhat.com>
+
+ main: Set errno before calling of strtol
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ quorumtool: Don't set our_flags without v_handle
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ sam_test_agent: Remove unused assignment
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ blackbox: Quote subshell result properly
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ init: Quote subshell result properly
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2018-03-01 Christine Caulfield <ccaulfie@redhat.com>
+
+ cfgtool: Don't assume link ID is a single char
+ For the moment link-ids are a single digit, but that could change and
+ the tools shouldn't be quite so fragile. So parse the interface_name
+ properly by looking for the space between the linkID and the IP.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ knet: Always use link0 for loopback
+ Even if it's not used for anything else.
+
+ Also, make cfgtool show the correct link ID when links are not
+ contiguous
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ totem: Fix debug warnings printed by knet
+ Fix crash introduced a couple of commits ago in iface_get
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ config: Allow use of ring0_addr
+ Allow ring0_addr to be used in place of 'name' for
+ backwards compatibility
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ config: Update message when local host isn't found
+ Make the message more representative of what's going on.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ cfg: Fix cfg_get_node_addrs so that DLM works
+ Also update copyright dates
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ totem: Return interface count correctly
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ totem: Use nodeid ONLY in srp_addr
+ This shrinks the srp_addr (and consequently every packet sent by
+ corosync) so that instead of containing loads of IP addresses to
+ identify a node, it just sends the nodeid.
+
+ This then allows us to make ring0 optional and replaceable when running
+ knet.
+
+ It also means that we need some other way of identifying the local
+ node in corosync.conf, so the nodelist.node.name entry is now mandatory
+ and is mapped to the local host using the same algorithm as used in
+ cman.
+
+ This code needs LOTS of testing as it touches a huge amount of totemsrp
+ and totemconfig.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2018-02-14 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ [rpm] use rpm macros to identify build distro
+ thanks Honza for spotting it
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ [rpm] fixup corosync.spec.in to build on opensuse
+ - move dbus-devel and nss-devel BuildRequires to file based depedency.
+ Those 2 BR have different names in OpenSUSE vs Fedora/RHEL/Centos.
+ This is kind of controversial as most distribution prefers a package
+ based build depedency, but the rpm version that supports
+ BuildRequires: foo || bar
+ is only available in rawhide and tumbleweed (aka no stable releases
+ are shipping it yet).
+ In order to build rpms in CI and have some level of flexibility
+ with upstream spec file, we need to compromise a bit.
+
+ - add explicit --docdir
+ OpenSUSE does not ship docs in the normal dir and their rpm macro
+ does not appear to set it for us.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2018-02-09 Rytis Karpuška <rytisk@neurotechnology.com>
+
+ totempg: Fix corrupted messages
+ Commit 899cb299831fea479ca8bc64d99fb1fce215d795 changed copy_len
+ to iovec[i].iov_len, assuming,
+ copy_len is always the same as iovec[i].iov_len under those
+ circumstances, but it missed the possability of small message being
+ partly put at the end of packet, which cuts this message in two parts
+ and therefore making copy_len not equal to iovec[i].iov_len.
+
+ This is revert of 899cb299831fea479ca8bc64d99fb1fce215d795
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2018-02-08 Rytis Karpuška <rytisk@neurotechnology.com>
+
+ totempg: use iovec[i].iov_len instead of copy_len
+ To be more explicit that we are copying whole message.
+
+ Related to 0ebae6b47d39940c62dcbd9185b9af2f265a47ff.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ totempg: Fix fragmentation segfault
+ The problem was that two or more messages were concatenated
+ together during fragmentation in mcast_msg() function. In specific case,
+ message of just short of 1MB was provided for mcast_msg() and it
+ happened so, that the remainder (212 bytes to be exact) left some free
+ space in packet, therefore branch
+
+ if ((copy_len + fragment_size) <
+ (max_packet_size - sizeof (unsigned short))) {
+ ...
+
+ was selected and this was the last mesage in provided iovec.
+ Then, on the second call, came another big message (about 300KB ) and
+ during fragmentation mcast.fragmented was set to 1.
+
+ On the other end, while receiving messages, due to missing
+ mcast.fragmentation==0 those two messages were concatenated and
+ therefore assembly->data array overflowed overwriting linked list
+ pointers and offset (which happened to be set to 0 and that 300KB
+ message was being copied from the beginning again).
+ After whole 300KB message has been sent, mcast.fragmentation==0 arrived
+ and totempg_deliver_fn() tried to move assembly structure to
+ assembly_list_free list, but as linked list pointers has been overriden,
+ segfault occured.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2018-02-05 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ [build] fix build with non-standard knet location
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ [man] fix regression introduced by 7162e75dcf81b7e475536e3060bf5e9312cd43b8
+
+2018-01-30 Christoph Berg <myon@debian.org>
+
+ Man: Move overview mp to sections 3 and 7 from 8
+ The _overview manpages are not actually commands and hence do not belong
+ into manpage section 8. Move corosync_overview to section 7
+ ("Miscellaneous") and the other *_overview pages to section 3 as they
+ contain API documentation (cf. string(3) for precedence of
+ multi-function manpages).
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2018-01-30 Jan Friesse <jfriesse@redhat.com>
+
+ logging: Close before and open blackbox after fork
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ logging: Make blackbox configurable
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2018-01-26 Andrey Ter-Zakhariants <at1984z@live.com>
+
+ corosync-notifyd: improve error handling
+ Better handling of errors in _cs_cmap_members_key_changed().
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2018-01-25 Jan Friesse <jfriesse@redhat.com>
+
+ spec: Modernize spec to comply with newest Fedora
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ build: Remove support for upstart
+ Upstart files were already mostly removed but not from spec file and
+ configure.ac.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ build: Replace -lknet with autoconf generated vars
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ build: Remove rdma/ibverbs
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ qdevice: Remove qdevices
+ corosync-qdevice and corosync-qnetd now has a new home
+ https://github.com/corosync/corosync-qdevice
+
+ This will allow us to better react on actual needs of quite independent
+ projects.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2018-01-18 Christine Caulfield <ccaulfie@redhat.com>
+
+ config: Don't fudge port numbers
+ When I was adding knet I wanted the port numbers to default to the
+ base port number + the linknumber.
+
+ However I seem to have messed this up such that any port number
+ specified in the config file has the link number added to it. Which
+ is almost certainly not what people would expect.
+
+ This patch sets it right. If a port number is not specified
+ then 5405+linknumber is used. If a port number IS specified
+ then that actual number is used.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2018-01-15 Christine Caulfield <ccaulfie@redhat.com>
+
+ knet: Allow ping_timers to be auto-configured
+ knet ping_timers are auto-configured according to token value.
+
+ This patch also fixes some knet config bugs that resulted in defaults
+ not being applied when values were removed from corosync.conf.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2018-01-15 Bin Liu <bliu@suse.com>
+
+ cts: Make code compatible with Python 3
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ corosync-notifyd: make SNMP work again
+ rrp_faulty_fn in notify_callbacks no longer exists, and now become
+ link_faulty_fn, and also link_faulty_fn needs 5 arguments while
+ rrp_faulty_fn needs 4.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2018-01-11 yuskiida <yusk.iida@gmail.com>
+
+ build: Add the headers necessary for RPM build
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2018-01-09 Christine Caulfield <ccaulfie@redhat.com>
+
+ config: if local node addr is wrong, fail with a sensible message
+ If no valid local address is found in corosync.conf then corosync
+ exits with: "parse error in config: No multicast port specified"
+
+ This is because of the config change for knet that always populates
+ the interfaces. The old error of "no interfaces found" was only
+ slightly better anyway IMHO.
+
+ This patch adds an explicit check that local_node_pos has been
+ set in icmap and uses that to determine if a valid local address
+ has been found.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2018-01-09 Jan Friesse <jfriesse@redhat.com>
+
+ totemknet: Drop truncated packets on receive
+ This is backport of part of "totemudpu: Scale receive buffer" patch.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ totemudp: Make use of UDP_RECEIVE_FRAME_SIZE_MAX
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ totemudpu: Export and rename UDPU_FRAME_SIZE_MAX
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ totemconfig: Fix UDP autogeneration of mcast addr
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ totemudpu: Scale receive buffer
+ Receive buffer should be based on PROCESSOR_COUNT_MAX and not static
+ buffer.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2018-01-05 Christine Caulfield <ccaulfie@redhat.com>
+
+ config: Allow selection of crypto_model
+ KNET has options for nss or openssl crpyto libraries, make this
+ available to corosync.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2018-01-04 Rytis Karpuška <rytisk@neurotechnology.com>
+
+ libcpg: Fix issue with partial big packet assembly
+ Packet assembly is done seperately for each nodeid, pid pair, therefore
+ multiple packets are not mixed into single buffer.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2018-01-02 Bin Liu <bliu@suse.com>
+
+ qdevice: mv free(str) after port validation
+ in the previous code of qdevice_net_instance_init_from_cmap:
+ host_port = strtol(str, &ep, 10);
+
+ free(str);
+
+ if (host_port <= 0 || host_port > ((uint16_t)~0) || *ep != '\0')
+
+ before free, *ep is '\0'. But after free, *ep changed to 'U', so mv
+ free behind the comparison.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2017-12-22 Toki Winter <toki@linuxfoundation.org>
+
+ corosync.aug: Add missing options
+ Knet related options are not yet included.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2017-12-22 Christine Caulfield <ccaulfie@redhat.com>
+
+ config: Allow links to have different ip_versions
+ knet allows links to have different IP versions - proivided they
+ all match per link. So don't force them all to be the same.
+
+ I've added a check here to make sure that all nodes on the same
+ link are using the same IP version.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2017-12-05 Bin Liu <bliu@suse.com>
+
+ Fix compile errors in qdevice and vqsim on FreeBSD
+ Some header files need to be specified on FreeBSD, otherwise there
+ are compile errors. These files does not affect Linux compilation.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2017-12-01 Christine Caulfield <ccaulfie@redhat.com>
+
+ cmapctl: mention the Clear stats option in usage message
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2017-12-01 Bin Liu <bliu@suse.com>
+
+ corosync-cfgtool: refactor cli parameters handling
+ use the idea from corosync-cmapctl to set ACTION and params in the first
+ swtich, and add another swtich to call function based on ACTION and the
+ params.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ wd: fix snprintf warnings
+ When running ./configure --enable-watchdog, gcc 7.2.1 will report
+ warnings for snprintf. This patch fixes the warnings.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2017-11-30 Christine Caulfield <ccaulfie@redhat.com>
+
+ totemsrp: Revert totemsrp_get_ifaces() changes
+ In my enthusiasm for removing code while integrating knet I
+ also deleted the correct code for returning IP address for a node,
+ so that only the IP addres of the local node was ever returned.
+
+ This commit restores the the previous code.
+
+ Also, because we always return INTERFACE_MAX interfaces now (they don't
+ have to be contiguous) set ss_family to zero if that interface is not
+ in use so that downstream apps know and don't display a lot of 0.0.0.0
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2017-11-30 Jan Friesse <jfriesse@redhat.com>
+
+ man: Add note about corosync not using name option
+
+2017-11-30 Jan Pokorný <jpokorny@redhat.com>
+
+ corosync.conf: publicize nodelist.node.name
+ It was discovered that pacemaker has been occassionaly relying on
+ those items configured in corosync.conf (and documenting so), while
+ backpropagation got stuck somewhere. As the option is deemed generally
+ beneficial, rectify this gap now and make it standard,
+ public part of the configuration space, possibly also for other
+ client SW to use now.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2017-11-29 Bin Liu <bliu@suse.com>
+
+ man: fixes for corosync.conf man page
+ 1. multicast address/port is only for UDP
+ 2. change kronosnet to Kronosnet
+ 3. nodeid must be set with KNET, not UDPU
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ cmapctl: add "-m" option into help message
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ totemconfig: remove duplicate aes256 test
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2017-11-27 Bin Liu <liu4480@126.com>
+
+ fix output format for corosync-cfgtool with knet (#283)
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2017-11-16 Jan Friesse <jfriesse@redhat.com>
+
+ sync: Call sync_init of all services at once
+ This patch solves situation which can happen very rearly:
+ - Node B is running
+ - Node A is started and tries to create singleton membership. It also
+ initialize service S which tries to send message during initialization
+ - Just before node A finished move to operational state, it gets
+ Node B multicast message so moves to gather state
+ - Node A and B creates membership and moves to operational state and
+ sync is started
+ - Node A and B receives message sent by node A during initialization of
+ service S
+ - Node A exits before sync of service is finished
+
+ In this situation, node B may never execute sync_init for
+ service S. So node B service S is not aware of existence of node A but
+ it received message from it.
+
+ Similar situation can theoretically also happen during merge.
+
+ Solution is to change flow of sync, so now it looks like:
+
+ - Build service_list
+ - Call sync_init for all local services
+ - Send service_list
+ - Receive service_list from all members and send barier
+ - For all services:
+ - Receive barier
+ - Call sync_activate if this is not first service
+ - Call sync_process for next service or finish sync if previous
+ this service is the last one
+ - Send barier
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ sync: Remove unneeded determine sync code
+ Code was used for compatibility with old sync v1 (in needle this was
+ deleted and previous version 2 became v1), and it's no longer needed.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2017-11-16 Christine Caulfield <ccaulfie@redhat.com>
+
+ stats: Add some missing knet stats
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2017-11-14 Jan Friesse <jfriesse@redhat.com>
+
+ man: Add note about qdevice parallel cmds start
+
+2017-11-14 Jan Pokorný <jpokorny@redhat.com>
+
+ man: corosync-qdevice: some more stylistics
+ Following the well-used scheme:
+ - expressly given defaults: italics (underline in standard terminals)
+ - key cross-references: bold (as well as the originals)
+
+ + fix missing paragraph delimiters
+ + s/what/which/ and s/on/one/ where appropriate
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2017-11-10 Ferenc Wágner <wferi@debian.org>
+
+ systemd: corosync-qdevice can not run without corosync
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2017-11-09 Jan Pokorný <jpokorny@redhat.com>
+
+ man: corosync-qdevice: fix formatting vs. punctuation
+ Previously, some enumerations were hard to follow, as they were marked
+ up all at once, including punctuation and connectives. Also mark up
+ some expressly given defaults.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2017-11-09 Ferenc Wágner <wferi@debian.org>
+
+ configure: kill off INITWRAPPERSDIR
+ When configured for systemd, don't install the SysV init scripts at all.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ corosync-qdevice: send startup notification to systemd
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ corosync-qnetd: send startup notification to systemd
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ Send corosync-notifyd startup notification to systemd
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ Make systemd stop corosync-notifyd if corosync is stopped
+ Otherwise is just exits successfully (which should probably be fixed
+ eventually), leading to confusion.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2017-11-09 Jan Friesse <jfriesse@redhat.com>
+
+ corosync.spec: Add system-devel build requirement
+ Reviewed-by: Ferenc Wágner <wferi@debian.org>
+
+2017-11-09 Ferenc Wágner <wferi@debian.org>
+
+ Send corosync startup notification to systemd
+ This enables starting the daemon directly in the service file, because
+ dependent units won't be started until initialization is complete.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2017-11-08 Jan Friesse <jfriesse@redhat.com>
+
+ quorumtool: Use full buffer size in snprintf
+ Thanks Bin Liu <bliu@suse.com> for this patch.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ cpghum: Mark print/log functions with printf attr
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ cpg_test_agent: Fix snprintf compiler warnings
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ sam: Fix snprintf compiler warnings
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2017-11-06 Jan Friesse <jfriesse@redhat.com>
+
+ coroparse: Do not convert empty uid, gid to 0
+ When uid (or gid) value was empty string it was incorrectly converted to
+ 0. Solution is to check input string emptines.
+
+ Thanks Bin Liu <bliu@suse.com> for reporting the bug.
+
+ Reviewed-by: Bin Liu <bliu@suse.com>
+
+2017-11-03 Christine Caulfield <ccaulfie@redhat.com>
+
+ cmapctl: Add option to clear the stats
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ stats: Don't display errors when reading knet stat
+ Only add the knet handle stat keys if we are actually running knet. This
+ prevents errors occurring when iterating through all of the stats keys
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2017-11-03 Bin Liu <liu4480@126.com>
+
+ make the output of "corosync-cfgtool -s" more readable (#269)
+
+2017-11-01 Bin Liu <bliu@suse.com>
+
+ cfg: nodeid should be unsigned int
+ nodeid in struct req_lib_cfg_get_node_addrs is "unsigned int",
+ so the function corosync_cfg_get_node_addrs should have its param
+ "nodeid" to be unsigned int.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ quorumtool: remove duplicated help message
+ Option "-p" was included twice, so remove one of them.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2017-11-01 Jonathan Davies <jonathan.davies@citrix.com>
+
+ man: fix cpg_mcast_joined.3.in
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2017-10-31 Christine Caulfield <ccaulfie@redhat.com>
+
+ man: Add stats.clear keys to the cmap_keys man pg
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ stats: Add cmap key to clear the various stats.
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2017-10-31 Ferenc Wágner <wferi@debian.org>
+
+ Use RuntimeDirectory instead of tmpfiles.d
+ This reverts part of commit 32123f6bb2ebc4f9ac7865945cc85a9c9b903dc6.
+
+ A simple directive is a much lighter solution to the same problem, and
+ automatically follows the specified User. I copied the 0770 modes from
+ the corresponding init scripts; they could use a little documentation.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2017-10-30 Bin Liu <bliu@suse.com>
+
+ totemconfig: generate mcast icmap items for UDP
+ Generating mcastaddr and mcastport in icmap make
+ sense only for UDP transport.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2017-10-30 Ferenc Wágner <wferi@debian.org>
+
+ Use static case blocks to determine distro flavor
+ This is a configure-time decision, avoid live filesystem checks.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ configure: add --with-initconfigdir option
+ Default value is /etc/sysconfig and resulting
+ INITCONFIGDIR is used to reduce duplication in init system
+ integration code.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2017-10-30 Bin Liu <bliu@suse.com>
+
+ totemconfig: add nodeid check for knet
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2017-10-25 Ferenc Wágner <wferi@debian.org>
+
+ man: support SOURCE_DATE_EPOCH
+ Make reproducible builds possible by supporting
+ https://reproducible-builds.org/specs/source-date-epoch/
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2017-10-25 Bin Liu <bliu@suse.com>
+
+ man:fix in corosync-qdevice.8
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2017-10-24 Bin Liu <bliu@suse.com>
+
+ man: must set nodeid for knet in nodelist
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2017-10-23 Jan Pokorný <jpokorny@redhat.com>
+
+ logsys: Avoid redundant callsite section checking
+ Previously, corosync executable was repeatedly (proportionally to the
+ count of LOGSYS_DECLARE_SUBSYS macro applications involved in the
+ constituent source files) checking the same for no gain in the pre-main
+ startup. This is not needed since nothing changes with static data
+ shared withing the same program space (it may have been a different
+ story once upon a time if loadable modules were in use), so make that
+ happen in (one-off per executable) LOGSYS_DECLARE_SYSTEM instead.
+
+ Libqb offers it's own ready-made macro to that
+ effect, simply to isolate the inner percularities from the library user
+ (that should not be required to understand anything about the orphan
+ sections and respective autocreated symbols to denote their boundaries).
+ As it is compile-time conditionalized in the same way, just use it
+ directly instead. As a value added, corosync will be kept up to date
+ about the possibly growing set of the logging-sanity checks as it gets
+ compiled with newer and newer libqb versions (their header files, for
+ that matter).
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2017-10-23 Christine Caulfield <ccaulfie@redhat.com>
+
+ config: Fix memory leak
+ totem_volatile_config_set_string_value was not properly freeing memory.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ knet: Add support for knet compression
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2017-10-20 Jan Friesse <jfriesse@redhat.com>
+
+ qdevice: Add support for heuristics
+ Heuristics are set of commands executed locally on startup, cluster
+ membership change, successful connect to corosync-qnetd and optionally
+ also at regular times. When all commands finish successfully
+ (their return error code is zero) on time, heuristics have passed,
+ otherwise they have failed. The heuristics result is sent to
+ corosync-qnetd and there it's used in calculations to determine which
+ partition should be quorate.
+
+ Right know, there are some problems (bugs):
+ - Regular heuristics is supported only by ffsplit. This is not a
+ problem for clusters with power fencing, but deployments where
+ non-quorate partition continues to operate may see this as a problem.
+ - Qdevice-tool status doesn't contain detailed information about
+ heuristics.
+ - Qdevice-tool doesn't have a possibility to trigger heuristics
+ re-execute.
+
+ Thanks Chrissie Caulfield for Englishify the man pages.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2017-10-18 Keisuke MORI <kskmori@intellilink.co.jp>
+
+ Spec: fix arch-qualified dependencies
+ needed along with commit 30af25294e019678c4f31e3368b19266f69b8254
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2017-10-11 Jan Friesse <jfriesse@redhat.com>
+
+ cmap: Remove noop highest config version check
+
+2017-10-11 Jonathan Davies <jonathan.davies@citrix.com>
+
+ cmap: don't shutdown highest config_version node
+ Scenario:
+ 1. node A starts corosync with config_version = 2, nodelist = {A, B}
+ 2. node B starts corosync with config_version = 1, nodelist = {A, B}
+
+ corosync.conf(5) says the config_version option is "used to prevent
+ joining old nodes with not up-to-date configuration."
+
+ So expected outcome is:
+ * corosync on node A remains alive
+ * corosync on node B exits
+
+ Actual outcome is:
+ * corosync on node A exits
+ * corosync on node B exits
+
+ Explanation of actual behaviour:
+ * Host A will have cmap_my_config_version = 2 but
+ cmap_highest_config_version_received = 1, so will shutdown in
+ cmap_sync_activate because these are not equal.
+ * Host B will have cmap_my_config_version = 1 but
+ cmap_highest_config_version_received = 2, so will shutdown in
+ cmap_sync_activate because these are not equal.
+
+ Instead, node A should consider its own config_version in the
+ calculation of the highest config_version, i.e.
+ cmap_highest_config_version_received = 2, and so not shutdown
+ in cmap_sync_activate.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2017-10-02 Kazunori INOUE <inouekazu@intellilink.co.jp>
+
+ totemudp: Remove memb_join discarding
+ This is already implemented in totemsrp in much cleaner way (added
+ by commit ab8942f6260fde93824ed2a18e09e572b59ceb25).
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2017-09-26 Edwin Torok <edvin.torok@citrix.com>
+
+ votequorum: make atb consistent on nodelist reload
+ When the cluster changes from even sized to odd sized corosync
+ disables auto-tie-breaker if wait_for_all is not enabled.
+ However when changing from odd sized to even sized it doesn't reenable
+ it, causing auto_tie_breaker to be inconsistent across the cluster:
+ the newly added node and any nodes that restart corosync
+ will have it, but all the previously running nodes won't.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2017-09-22 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ totem: Remove unnecessary NSS headers
+ Also fix corosync.spec.in to depend on libknet.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2017-09-21 Christine Caulfield <ccaulfie@redhat.com>
+
+ config: Allow dynamic link configuration
+ Now we are using knet, it's possible to dynamically add, remove and
+ reconfigure links on the fly.
+
+ Also print 'n' for non-existant knet links. This will show up
+ only on loopback links >0. But it looks better than 'status ='
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2017-09-19 Masse Nicolas <nicolas.masse@stormshield.eu>
+
+ totemudp: Retry if bind fails
+ If bind call fails it's retried for BIND_MAX_RETRIES.
+ If it's still unsuccessful, corosync exists instead
+ of working incorrectly.
+
+ Slightly modified by reviewer.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2017-09-14 Ferenc Wágner <wferi@debian.org>
+
+ corosync.conf.5: watchdog support is conditional
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ wd: default to not using a watchdog
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2017-09-12 Ferenc Wágner <wferi@debian.org>
+
+ wd: remove extra capitalization typo
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ corosync.conf.5: add warning about slow watchdogs
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2017-09-11 Jonathan Davies <jjd27@dani.uk.xensource.com>
+
+ totemknet: fix debug message typo
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2017-09-11 Ferenc Wágner <wferi@debian.org>
+
+ corosync.conf.5: Fix watchdog documentation
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ wd: fix typo
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2017-08-31 Khem Raj <raj.khem@gmail.com>
+
+ Include fcntl.h for F_* and O_* defines
+ Fixes errors like
+ utils.c:95:22: error: use of undeclared identifier 'O_WRONLY'
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2017-08-23 Christine Caulfield <ccaulfie@redhat.com>
+
+ stats: add knet 'handle' stats
+ knet handle stats show compression and crypto statistics. With these
+ you can see the effectiveness of compression and the overheads of both
+ crypto and compression.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2017-08-22 Christine Caulfield <ccaulfie@redhat.com>
+
+ main: use syslog & printf directly for early log messages
+ libqb seems funny about logging things before its fully configured.
+ This corosync commit didn't help either:
+ 8b6bd86a55b8bda9f3a8ff67bdff908263976fa3
+
+ So to make sure that messages about the config file not being opened
+ get delivered to the user/syslog we send them directly.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2017-08-14 Christine Caulfield <ccaulfie@redhat.com>
+
+ totempg: Allow space for incoming overflow
+ totempg needs to store the current message + any
+ overflow for the next message which can be up to (nearly) the MTU size.
+ in knet that's large, but for UDP it's just 1500.
+
+ The reason we've never seen it before is because the actual max message
+ size is 1024 less than 1MB and after all the headers are stripped out the overflow is
+ usually 1024 bytes or less.
+ The 1024*1024 size of the assembly buffer is large enough to hold a max message (1047552) +
+ 1024 bytes of a new UDP message. So we never saw any problems.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2017-08-11 Chrissie Caulfield <ccaulfie@redhat.com>
+
+ cpghum: Add options to change flood start/mult/end sizes (#237)
+ I ran out of sensible short options for cpghum so added some long
+ ones to cope with them.
+
+ Also added is the ability to specify most size values in a sensible format
+ eg 64M for 64 Megabytes or 48K for 48 Kilobytes.
+
+ Strictly those are MiB and KiB of course, but I'm old-fashioned.
+
+2017-08-04 Chrissie Caulfield <ccaulfie@redhat.com>
+
+ totemknet: Use knet's LOOPBACK transport (#236)
+ knet now has a built-in LOOPBACK transport so use that
+ rather than special-casing it for ourself.
+
+2017-08-03 Christine Caulfield <ccaulfie@redhat.com>
+
+ CFG: Remove ring-reenable code
+ RRP doesn't exist any more so all the ring re-enable code is redundant.
+
+ I've removed it from the library and all the code that does anything,
+ but I've left the hole in the IPC just in case old libraries are
+ hanging around.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2017-08-01 Jan Friesse <jfriesse@redhat.com>
+
+ main: Add support for libcgroup
+ When corosync is started in environment where it ends in cgroup without
+ properly set rt_runtime_us it's impossible to get RT priority.
+
+ Already implemented workaround is to use higher non-RT priority.
+
+ This patch implements another solution. It moves corosync into root cpu
+ cgroup. Root cpu cgroup hopefully has enough RT budget.
+
+ Another solution was mentioned on ML
+ https://lists.freedesktop.org/archives/systemd-devel/2017-July/039353.html
+ but this means to generate some "random" values.
+
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+ (cherry picked from commit c56086c701d08fc17cf6d8ef603caf505a4021b7)
+
+2017-07-27 Christine Caulfield <ccaulfie@redhat.com>
+
+ stats: Add map with on-demand statistics
+ Icmap is factored out so it's possible to add other
+ maps for cmap. API call to switch maps from application
+ end is added.
+
+ Corosync-cmapctl is enhanced with -m option.
+
+ Stats contains all statistics previously found in runtime.connections,
+ runtime.services and runtime.totem prefixes together with new knet
+ related. All stats are read only.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2017-07-14 Christine Caulfield <ccaulfie@redhat.com>
+
+ ipc: Check for the libraries sending invalid message IDs
+ If the library sent an invalid (ie too high) message ID to
+ corosync, then it could cause the daemon to crash.
+
+ Now we check the message ID before indexing the function array
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2017-07-10 Jan Friesse <jfriesse@redhat.com>
+
+ main: Add option to set priority
+ Option -P takes numeric value with same meaning
+ as nice or values min / max, meaning maximal / minimal priority (so
+ minimal / maximal nice value).
+
+ Scheduler / priority setting is moved in code so it is now executed
+ after logsys is configured so errors are logged.
+
+ Setting maximal priority is also used as fallback when realtime
+ scheduling is requested and sched_setscheduler fails.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+ (cherry picked from commit a008448efb2b1d45c432867caf08f0bcf2b4b9b0)
+
+2017-07-03 Jan Friesse <jfriesse@redhat.com>
+
+ totemknet: Prevent dead-loop in log_flush_messages
+
+ corosync-keygen: Display number of needed bits
+ Instead of currently read bits, number of already read bits is
+ displayed to let the user know how long it's needed to "press keys"
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ totemknet: Flush knet log messages
+ When initialization fails knet logs messages into pipe. Previously they
+ were never processed. Solution is to add log_flush_messages which takes
+ care to call log_deliver_fn.
+
+ Call of log_flush_messages is also added to totemknet_finalize because
+ this removes log pipe fd from qb_loop so similar problem can happen.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ corosync-keygen: Make less-secure default
+ /dev/urandom is good enough for crypto keys and it's not blocking. If
+ superb randomness is really needed, it's possible to use newly added
+ option -r.
+
+ Also manpage is reworked a bit to use .nf instead of many .br.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ corosync-keygen: Adapt to knet key sizes
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ totemconfig: Make crypto work again
+ Knet needs longer key and supports various key lengths. Split
+ TOTEM_PRIVATE_KEY_LEN into TOTEM_PRIVATE_KEY_LEN_MIN and
+ TOTEM_PRIVATE_KEY_LEN_MAX (both using KNET_*_KEY_LEN).
+
+ Fix incorrect "Could only read..." message.
+
+ Make sure key is properly initialized/zeroed.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2017-06-29 Christine Caulfield <ccaulfie@redhat.com>
+
+ knet: Compile with latest knet API
+ extra parameter added to knet_link_get_status()
+
+2017-06-15 Jan Friesse <jfriesse@redhat.com>
+
+ totem: Propagate totem initialization failure
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2017-06-09 Christine Caulfield <ccaulfie@redhat.com>
+
+ totemknet: Use new knet_link_set_config() API
+ TC_PRIO_INTERACTIVE is now a link option in knet, so we have
+ to provide it at link config time.
+
+ This needs the latest knet git to compile as this is an updated API.
+
+2017-05-29 Michael Jones <jonesmz@jonesmz.com>
+
+ coroapi: Use size_t for private_data_size
+ Unsigned int and size_t represent two different concepts.
+
+ Same problem was present in ipc_glue.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2017-05-26 Christine Caulfield <ccaulfie@redhat.com>
+
+ votequorum: Report errors from votequorum_exec_send_reconfigure
+ If votequorum_exec_send_reconfigure() returns an error (ie the
+ packet could not be sent) then we should either return it to the
+ sender (for a library call) or, for an internal call, log it.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2017-05-25 Christine Caulfield <ccaulfie@redhat.com>
+
+ cpghum: remove space after delimiter
+ machine-readable stats do not need extra spaces!
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ cpghum: Add interim RTT to cpghum
+ when -f is selected the interim stats show the RTTs for that
+ size of packet.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2017-05-23 Michael Jones <jonesmz@jonesmz.com>
+
+ configure: Enable C99 language standard
+ Also disable some obsolete warnings.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2017-05-18 Jan Friesse <jfriesse@redhat.com>
+
+ main: Display reason why cluster cannot be formed
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2017-05-18 Hideo Yamauchi <renayama19661014@ybb.ne.jp>
+
+ notifyd: Add the community name to an SNMP trap
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2017-05-15 Christine Caulfield <ccaulfie@redhat.com>
+
+ cpghum: Add machine-readable output
+ and fix a few small counter bugs.
+
+2017-05-11 Chrissie Caulfield <ccaulfie@redhat.com>
+
+ test: Fold cpgbench into cpghum (#205)
+ * test: Fold cpgbench into cpghum
+
+ cpgbench and cpghum share a lot of code & concepts so it makes
+ sense to merge them into a single test program that can both
+ benchmark and sanity check CPG.
+
+ Signed-off-by: Christine Caulfield <ccaulfie@redhat.com>
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2017-05-09 Christine Caulfield <ccaulfie@redhat.com>
+
+ knet: Allow space for encapsulated messages
+
+2017-04-25 Andrew Price <anprice@redhat.com>
+
+ Main: Call mlockall after fork
+ Man page of mlockall is clear:
+ Memory locks are not inherited by a child created via fork(2) and are
+ automatically removed (unlocked) during an execve(2) or when the
+ process terminates.
+
+ So calling mlockall before corosync_tty_detach is noop when corosync is
+ executed as a daemon (corosync -f was not affected).
+
+ This regression is caused by ed7d054e552b4cb2a0cb502b65f84310ce6da844
+ (setprio for logsys/qblog was correct, mlockall was not).
+
+ Solution is to move corosync_mlockall call on correct place.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2017-04-21 Michael Schwarz <michi.schwarz@gmail.com>
+
+ Fix typos in README.recovery
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2017-04-20 Bin Liu <bliu@suse.com>
+
+ coroparse: Use readdir instead of readdir_r
+ readdir_r is deprecated in glibc 2.24 in favor of readdir (which became
+ thread safe). Also because corosync never calls read_uidgid_files_into_icmap
+ in muliple threads, no problem should appears even with libc where
+ readdir is thread-safe.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ totemknet: Handle logpipe creation failure
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ wd: Report error when close of wd fails
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ Qnetd lms: Use UTILS_PRI_RING_ID printf format str
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ cpghum: Fix printf of size_t variable
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2017-04-11 Christine Caulfield <ccaulfie@redhat.com>
+
+ totemknet: Got back to recvmsg() from recvmmsg()
+ The kernel team have recommended us not to use recvmmsg and as it
+ confers no particular speed advantage (especially given the extra
+ memory consumption) I'm going back to single message recvmsg() again.
+
+2017-04-11 Bin Liu <bliu@suse.com>
+
+ totemconfig: Prefer nodelist over bindnetaddr
+ In a two-node cluster, I 've one node configured with open-vswtich:
+ 5: br-fixed: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue
+ state UNKNOWN group default
+ inet 192.168.124.88/24 scope global br-fixed
+ inet 192.168.124.87/24 scope global secondary br-fixed
+ inet 192.168.124.83/24 brd 192.168.124.255 scope global secondary
+ tentative br-fixed
+ inet 192.168.124.89/24 scope global secondary br-fixed
+
+ while I use 192.168.124.83 in node list of corosync.conf with udpu, and
+ the bind_addr is 192.168.124.0. After upgrading corosync on this node,
+ the it uses 192.168.124.88 instead of 192.168.124.83. As we can see:
+
+ corosync-cfgtool -s
+ Printing ring status.
+ Local node ID 1084783704
+
+ corosync-quorumtool -s
+ Membership information:
+ Nodeid Votes Name
+ 1084783697 1 d52-54-77-77-01-02
+ 1084783699 1 d52-54-77-77-01-01 (local)
+
+ while the other node can only see itself:
+ corosync-cfgtool -s
+ Printing ring status.
+ Local node ID 1084783697
+ RING ID 0
+ id = 192.168.124.81
+ status = ring 0 active with no faults
+
+ corosync-quorumtool -s
+ Membership information:
+ Nodeid Votes Name
+ 1084783697 1 d52-54-77-77-01-02.virtual.cloud.suse.de (local)
+
+ this patch will check if there are both nodelist and bindnetaddr and if
+ so, display warning and use nodelist information.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2017-04-11 Christine Caulfield <ccaulfie@redhat.com>
+
+ knet: Close libknet down cleanly at shutdown
+ By tidily shutting down knet in totekmknet_finalize we
+ make sure all the links are cleanly taken down and,
+ more importantly for us, the corosync LEAVE message gets
+ sent so we don't get fenced on a clean exit.
+
+2017-04-07 Christine Caulfield <ccaulfie@redhat.com>
+
+ man: Document -a option to corosync-quorumtool
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2017-04-07 Jan Friesse <jfriesse@redhat.com>
+
+ cpghum test: Improve error codes
+ Return error when unknown option is found. Also return error code 2 if
+ one of send/crc/length/sequence error happened. Finally make sure abort
+ returns same error code and not 999 (what is nonsense code anyway).
+
+2017-04-04 Christine Caulfield <ccaulfie@redhat.com>
+
+ quorumtool: Add option to show all node addresses
+ New -a option shows all of the names/ip address of nodes
+ in a multi-homed environment.
+
+2017-03-14 Christine Caulfield <ccaulfie@redhat.com>
+
+ cpghum: Stop cpghum from reporting fake CRC errors
+
+2017-03-10 Bin Liu <bliu@suse.com>
+
+ logconfig: Do not overwrite logger_subsys priority
+ logfile_priority and syslog_priority could be modified by
+ logging.logger_subsys.{logfile_priority|syslog_priority}. which could
+ lead to the following output(which are at notice level):
+
+ corosync[21419]: [QUORUM] Using quorum provider corosync_votequorum
+ corosync[21419]: [QUORUM] Members[1]: 1084777643
+ corosync[21419]: [QUORUM] This node is within the primary component
+ and will provide service.
+ corosync[21419]: [QUORUM] Members[3]: 1084777563 1084777584 1084777643
+
+ even the syslog_priority is warning. This patch could avoid the
+ overwrite.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2017-03-02 Christine Caulfield <ccaulfie@redhat.com>
+
+ totem: Fix buffer sizes
+ knet needs buffers to be KNET_MAX_PACKET_SIZE or messages will
+ get lost or corrupted.
+
+ UDPU packets shouldn't be that big so I introduced UDP_FRAME_SIZE_MAX
+ for that transport.
+
+2017-02-27 Christine Caulfield <ccaulfie@redhat.com>
+
+ main: Don't ask libqb to handle segv, it doesn't work
+ segv should be handled by corosync, libqb is not the
+ place to be handling emergency signals.
+
+ This currently requires the head of libqb git tree to
+ generate a blackbox & coredump in the event of a segfault,
+ but it's better than the write() spin that currently happens.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2017-02-24 Jan Friesse <jfriesse@redhat.com>
+
+ Logsys: Change logsys syslog_priority priority
+ LibQB adds default "*" syslog filter so we have to set syslog_priority
+ as low as possible so filters applied later in
+ _logsys_config_apply_per_file takes effect.
+
+2017-02-24 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ knet: improve logging messages by adding knet subsystem
+
+2017-02-17 Christine Caulfield <ccaulfie@redhat.com>
+
+ cpghum: Add abort_on_error option
+
+2017-02-16 Christine Caulfield <ccaulfie@redhat.com>
+
+ cpghum: Add min rtt and print stats every alarm
+
+2017-02-15 Christine Caulfield <ccaulfie@redhat.com>
+
+ cpghum: Add Round Trip Time (RTT) reporting
+
+2017-02-14 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ knet: Change nodeids to knet_node_id_t for new knet compatibility
+ after some feedback on github, people prefers to have the option
+ to support up to 64K node_id's.
+
+ libknet added knet_node_id_t to mask the size and type, currently
+ set to uint16_t.
+
+2017-02-13 Christine Caulfield <ccaulfie@redhat.com>
+
+ knet: Fix MTU sizes & allow transport config in corosync.conf
+ Corosync layers don't need to know the knet MTU size - this way
+ corosync fragments buffers only when they get larger than the
+ KNET buffer size (64K) and knet fragments below that based on
+ the actual MTU and transport considerations.
+
+ It is also now possible to configure knet to use UDP or SCTP
+ transports in corosync.conf. This is currently done per-link
+ so if you have more than 1 link you need several interface{}
+ stanzas inside totem{} to make it use other than the default
+ of UDP. if it's useful I might add the option of a global
+ default.
+
+2017-02-11 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ knet: PMTUd data_mtu already accounts for IP and knet header overheads
+ provide some more space for data and small (+1% perf boost)
+
+ knet: switch from write to sendto()
+ this provides another 9.6% performance boost on 2 node clusters
+
+2017-02-03 Christine Caulfield <ccaulfie@redhat.com>
+
+ knet: Change nodeids to 8 bit for new knet compatibility
+ I've also put an assert in totemknet_member_add() to check
+ for invalid nodeids. Later on we need to fix the rest of the
+ corosync code to only use 8bit nodeids (or force people to use
+ UDPU if they want large nodeids).
+
+2017-01-18 Adrian Vondendriesch <adrian.vondendriesch@credativ.de>
+
+ doc: document watchdog_device parameter
+ Commit 8d8d4a936ab73d8449a3574f969b17a90ef9428e introduced the
+ configuration parameter resources.watchdog_device. This commit
+ introduces the resources section and watchdog_device parameter in
+ corosync.conf.5.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2017-01-16 Christine Caulfield <ccaulfie@redhat.com>
+
+ knet: Fix member_remove to shut down existing links first
+
+2017-01-10 Jan Pokorný <jpokorny@redhat.com>
+
+ Spec: make internal dependencies arch-qualified
+ To prevent any mismatch of this kind for sure.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ Spec: drop unneeded dependency
+ corosynclib-devel doesn't need to have a dependency on corosync package.
+
+ It's expected that libraries are still working properly (e.g. indicating
+ errors to their users) when there's no corosync process around in that
+ moment, and from this perspective it doesn't matter whether it is
+ installed at all for some purposes, especially having linkage with them
+ in mind.
+
+ Note that the inverse dependency, main corosync package on corosynclib,
+ is already there (not strictly needed, likely just to enforce package
+ version match -- otherwise RPM's dependency generator will handle this
+ on its own using SONAMEs -- hence the comments to that effect are also
+ added), so breaking this symmetry:
+ - is supposed to be harmless modulo cases that should be fixed to
+ express explicit dependency on corosync's runtime anyway
+ (but only for runtime, i.e., Requires as opposed to BuildRequires)
+ - will effectively enable more lightweight get-build-deps-and-build
+ process for programs linking with corosynclibs (e.g. pacemaker),
+ as corosync package won't need to be installed needlessly
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2017-01-03 Christine Caulfield <ccaulfie@redhat.com>
+
+ knet: Reduce default pong count to 2 for faster startup
+ The default PONG_COUNT of 5 made corosync slow to connect to other
+ nodes.
+ This helps.
+
+2016-12-22 Christine Caulfield <ccaulfie@redhat.com>
+
+ totemknet: Make it compile with kronosnet git master
+
+2016-12-12 Bin Liu <bliu@suse.com>
+
+ Qdevice: fix spell errors in qdevice
+ There are somwe spell errors in qdevice-net-algo-test.c,
+ qnetd-algo-2nodelms.c, qnetd-algo-test.c qnetd-algo-ffsplit.c
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2016-12-05 Takeshi MIZUTA <miz.take4@gmail.com>
+
+ Remove redundant header file inclusion
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2016-12-05 Richard B Winters <rik@mmogp.com>
+
+ Remove deprecated doxygen flags
+ Running 'doxygen -u Doxyfile.in' in the source root produces the
+ following results:
+
+ - SYMBOL_CACHE_SIZE at line 301 has become obsolete. This tag
+ has been removed.
+ - SHOW_DIRECTORIES at line 507 has become obsolete. This tag
+ has been removed.
+ - HTML_ALIGN_MEMBERS at line 881 has become obsolete. This tag
+ has been removed.
+ - USE_INLINE_TREES at line 1067 has become obsolete. This tag
+ has been removed.
+ - XML_SCHEMA at line 1311 has become obsolete. This tag has been
+ removed.
+ - XML_DTD at line 1317 has become obsolete. This tag has been
+ removed.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2016-12-05 yuusuke <yusk.iida@gmail.com>
+
+ upstart: Add softdog module loading example
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2016-12-05 Bin Liu <bliu@suse.com>
+
+ Totempg: remove duplicate memcpy in mcast_msg func
+ In function mcast_msg of totempg.c, line 923, there is a memcpy call in
+ "else" branch, and also another memcpy out of the "else" branch, while
+ the two calls have the same parameters. It is possibleto remove the memcpy
+ in "else" branch.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2016-12-01 Takeshi MIZUTA <miz.take4@gmail.com>
+
+ man: Modify man-page according to command usage
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2016-11-28 Ferenc Wágner <wferi@niif.hu>
+
+ init: Add doc URIs to the systemd service files
+ These are used by systemctl help.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2016-11-28 Ferenc Wágner <wferi@debian.org>
+
+ Fix typo: Destorying -> Destroying
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2016-11-28 Takeshi MIZUTA <miz.take4@gmail.com>
+
+ man: Fix typos in man page
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2016-11-23 Takeshi MIZUTA <miz.take4@gmail.com>
+
+ totempg: totempg_groups_join return valid error
+ totempg_groups_join() is called by sync_init().
+ sync_init() judge that totempg_groups_join() failed if return code of
+ totempg_groups_join() is -1.
+ Therefore, the return code should return in -1 when
+ totempg_groups_join() fails.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2016-11-21 yuusuke <yusk.iida@gmail.com>
+
+ systemd: Delete unnecessary soft_margin
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2016-11-17 Christine Caulfield <ccaulfie@redhat.com>
+
+ knet: Support reload of link parameters
+
+2016-11-15 Takeshi MIZUTA <miz.take4@gmail.com>
+
+ list: Unify the list processing with qb_list func
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2016-11-15 Christine Caulfield <ccaulfie@redhat.com>
+
+ knet: Allow configuration of more params
+ knet_pmtud_interval &
+ knet_pong_count
+
+2016-11-14 Chrissie Caulfield <ccaulfie@redhat.com>
+
+ knet: Don't lose log messages when knet gets busy (#165)
+
+2016-11-07 Jan Friesse <jfriesse@redhat.com>
+
+ libvotequorum: Bump version
+
+2016-10-27 Jan Friesse <jfriesse@redhat.com>
+
+ list: Replace for_each by safe version where need
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ list: Remove list.h
+ List.h is no longer needed.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2016-10-27 Michael Jones <jonesmz@jonesmz.com>
+
+ list: Replace uses of list.h with qblist.h
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2016-10-23 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ [build] Fix build on RHEL7.3 latest
+ header inclusion have changed
+
+2016-10-17 HideoYamauchi <renayama19661014@ybb.ne.jp>
+
+ Change a type of NodeID.
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2016-10-13 Christine Caulfield <ccaulfie@redhat.com>
+
+ vqsim: Fix Makefile.am
+ Make it conditional on BUILD_VQSIM being defined
+
+ configure: Remove RDMA (again)
+ How did that creep back in again?
+
+ vqsim: Add Quorum simulator program
+ vqsim is a small program that allows node up/down/split/join
+ operations to be simulated without the use of an actual cluster.
+
+2016-10-13 Jan Friesse <jfriesse@redhat.com>
+
+ Build: Fail configure if knet is not installed
+ Libknet is now requirement.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2016-10-13 Christine Caulfield <ccaulfie@redhat.com>
+
+ totem: add totemknet.[ch]
+ it seems git is better at deleting files than adding them
+
+2016-10-12 Michael Jones <jonesmz@jonesmz.com>
+
+ cfg: Prevents use of uninitialized buffer
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2016-10-11 Christine Caulfield <ccaulfie@redhat.com>
+
+ totem: Add Kronosnet transport.
+ This is a big update that removes RRP & MRP from the codebase
+ and makes knet the default transport for corosync. UDP & UDPU
+ are still (currently) supported but are deprecated. Also crypto
+ and mutiple interfaces are only supported over knet.
+
+ To compile this codebase you will need to install libknet from
+ https://github.com/fabbione/kronosnet
+
+ The corosync.conf(5) man page has been updated with info on the new
+ options. Older config files should still work but many options
+ have changed because of the knet implementation so configs should
+ be checked carefully. In particular any cluster using using RRP
+ over UDP or UDPU will not start as RRP is no longer present. If you
+ need multiple interface support then you should be using the knet transport.
+
+ Knet brings many benefits to the corosync codebase, it provides support
+ for more interfaces than RRP (up to 8), will be more reliable in the event
+ of network outages and allows dynamic reconfiguration of interfaces.
+ It also fixes the ifup/ifdown and 127.0.0.1 binding problems that have
+ plagued corosync/openais from day 1
+
+2016-10-06 HideoYamauchi <renayama19661014@ybb.ne.jp>
+
+ coropase: Set a poll_period value for wd monitor
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2016-09-13 Christine Caulfield <ccaulfie@redhat.com>
+
+ votequorum: simplify reconfigure message handling
+ As we now have update_node_expected_votes(), we can use that
+ when receiving a new EXPECTED_VOTES value from another node
+ rather than having our own loop.
+
+ votequorum: Don't update expected_votes display if value is too high
+ If expected_votes was set via the library but the calculation
+ decides it's too high, then an error is correctly returned but
+ the value is still set in the nodes' expected_votes field and
+ turns up in the corosync-quorumtool display.
+
+ This patch separates out the quorum calculation from the updating
+ of expected_votes per node to prevent this from happening.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2016-09-12 Ferenc Wágner <wferi@niif.hu>
+
+ Fix various typos
+ occured -> occurred
+ parantheses -> parentheses
+ configuraton -> configuration
+ aquire -> acquire
+ retrive -> retrieve
+ prefered -> preferred
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2016-09-02 Ferenc Wágner <wferi@niif.hu>
+
+ init: corosync and cman aren't system facilities
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ conf: be explicit about the mcast src/dst ports
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2016-08-30 Jan Friesse <jfriesse@redhat.com>
+
+ Qnetd LMS: Fix two partition use case
+ Solves situation when in 2 node cluster tie-breaker node dies. Because
+ code contains two bugs, other node got NACK instead of ACK.
+
+ - Algo timer is not stack, so calling abort and schedule in timer
+ callback without setting reschedule is noop.
+ - It's needed to check not only what current node thinks about
+ membership, but also what other nodes thinks. If views diverge -> wait.
+
+ Thanks Christine Caulfield <ccaulfie@redhat.com> for fixing the English
+ in the comments somewhat.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2016-08-12 Christine Caulfield <ccaulfie@redhat.com>
+
+ man: mention qdevice incompatibilites in votequorum.5
+
+2016-08-09 Jan Friesse <jfriesse@redhat.com>
+
+ Man: Fix corosync-qdevice-net-certutil link
+
+2016-08-04 Jan Friesse <jfriesse@redhat.com>
+
+ Spec: Qdevice require same version of corosync
+
+ Config: Flag config uidgid entries
+ Uidgid entries parsed from configuration files now has prefix
+ (uidgid.config.) so they are distinguishable from dynamically added
+ entries. Entries added from config file are pruned on reload if no
+ longer exists in config file (dynamic one stays unaffected). Also whole
+ uidgid.config. prefix is made read only.
+
+ This make PCMK work again after configuration reload is called.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2016-08-04 Bin Liu <bliu@suse.com>
+
+ cts: Make it run with pacemaker-1.13+
+ There are changes in pacemaker-cts which corosync-testagents denpends
+ on. With these changes, corosync-testagents can not run. This patch
+ fixes the issues, and makes corosync-testagents run.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2016-08-01 HideoYamauchi <renayama19661014@ybb.ne.jp>
+
+ Low: totemsrp: Addition of the log.
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2016-07-12 Christine Caulfield <ccaulfie@redhat.com>
+
+ qdevice: some more small man page fixes
+ including mentioning corosync-qdevice(5) on the
+ votequorum(5) and corosync.conf(5) pages.
+
+ Thanks to Jan Pokorný for reporting these.
+
+2016-07-07 Christine Caulfield <ccaulfie@redhat.com>
+
+ qdevice: Fix 'tie_breaker' in man page
+ the tie_breaker option was incorrectly listed as
+ tie-breaker on the man page.
+
+2016-06-30 Jan Friesse <jfriesse@redhat.com>
+
+ Qdevices: Include required files in tarball
+
+ Qdevice: Include man pages in tarball
+
+ tmpfiles.d: Install only when required
+
+2016-06-30 Christine Caulfield <ccaulfie@redhat.com>
+
+ Qdevice: Englishify man pages
+
+2016-06-29 Jan Friesse <jfriesse@redhat.com>
+
+ Qdevice: Add corosync-qdevice man page
+
+ Qdevice: Add more man pages
+
+2016-06-28 Jan Friesse <jfriesse@redhat.com>
+
+ Qdevice: Fallback mkdir of /var/run sundirectory
+
+ Qdevice: Enhance delay before reconnect
+
+ Qdevice: Handle /var/run on tmpfs
+
+ Qdevice: Reconnect on algo or tb differs error
+
+ qdevice: Add qdevice-tool and qnetd-tool man pages
+
+ Qdevice: Make ffsplit algorithm default
+
+ Qdevice: Add sysconfig example
+
+ Fix few bugs found by coverity
+
+ Qdevice: Fix errors found by coverity
+
+ Qnetd: Execute qnetd as non root user
+
+ Qdevice: Adjust path to final location
+
+ Qdevice: Add qnetd configure option
+ Qnetd is no longer build as a part of --qneable-qdevices. Instead
+ --enable-qnetd is used.
+
+2016-06-28 Christine Caulfield <ccaulfie@redhat.com>
+
+ quorum: revert patch that adds qdevice (node 0) to quorum callback
+ Revert patch 9f54f0a1fad7dad42c55562a50dfb9d773e6a660 as it causes
+ more troubles than it solves. Code that uses the quorum nodelist
+ to get a list of actual nodes in the cluster for communication
+ break using this as well as the display from corosync-quorumtool
+
+2016-06-28 Jan Friesse <jfriesse@redhat.com>
+
+ Qdevice-net: Make duplicate node id err non-fatal
+ It can happen because qnetd not yet handled disconnect of client.
+
+ Qnetd: ffsplit: Add no active clients heuristic
+ On 50:50 split, ffsplit algorithm now prefers partition with
+ higher number of active clients. Tie-breaker is used only if both
+ partitions have same number of active clients.
+
+ Qdevice: Allow master_wins
+
+ Qnetd: ffsplit: Enhance ffsplit
+ 50:50 split algorithm now works in following way:
+ - On client configuration change, membership change or disconnect wait
+ till membership is stable (= all client configuration node list are
+ equal, and all partitions has equal information).
+ - Choose best partition >= 50%
+ - If no such partition exists, send NACK to all clients
+ - Send NACK to all clients who should receive NACK
+ - After all clients who should receive NACK confirm vote reception, send
+ ACK to all clients who should get ACK
+
+ This ensures that there are never two partitions with ACK and it has
+ much better behavior than previous version, because if tie-breaker
+ partition is not connected, other partition gets ACK.
+
+ Qdevice: Send ring id in more messages
+ To prevent receiving vote from old membership ring id is sent to server
+ during init and replied back to client in every node list,
+ ask for vote reply and vote info messages.
+
+ Qdevice: Remove unused variable
+
+ Qdevice: Wait for ring id before executing model
+
+ Qnetd: Make sure all header files are in final tar
+
+ Qdevice: Add initial version of ffsplit
+ For now it's doing same job as atb.
+
+ Qnetd: Return errors in test algorithm
+
+ Qnetd: Implement cluster algorithm data
+
+ Qdevice: Fix qdevice-net-certutil quickstart
+ Last part (import p12 files on other nodes) were not implemented.
+
+ Qnetd: Split cluster-list
+
+ Qnetd: Store result vote of ask_for_vote correctly
+ Previously unitialized vote was stored.
+
+ Qdevice: Correct API comments
+ Also after votequorum node list is received and qnetd is connected,
+ default vote is changed to WAIT_FOR_REPLY. This make much more sense
+ because it ensures qdevice doesn't vote with new ring id until qnetd
+ sends reply.
+
+ Qdevice: Add expected votes notify callback API
+
+ Qdevice: Do not call cmap_dispatch in sync
+ When corosync is during sync operation cmap_dispatch blocks.
+
+ Qdevice: Add advanced settings
+ All previously defined defaults are now configurable via -S option.
+
+ qnetd: Add warning to test algorithm
+
+ Qnetd: Add advanced settings
+ All previously defined defaults are now configurable via -S option.
+
+ qdevice: Ensure to exit if ipc socket is closed
+ When ipc socket was closed before poll and new connection got same fd as
+ original IPC socket, shutdown didn't work. Solution is to check if IPC
+ socket is active during poll array create.
+
+ Qdevice: Add IPC clients
+
+ qnetd: Add support for IPC list command
+
+ qdevice: Make sure qdevice exists on corosync exit
+
+ Add qdevice into spec file
+
+ Make sure all qdevice files are packaged
+
+ Split qnetd certutil to qnetd and qdevice-net part
+
+ Qnetd: Add local IPC
+ Basic commands shutdown and status are implemented.
+
+ Qdevice: Quote str func compatible with simple_lex
+
+ Qdevice: Improve simple lex and add unit test
+ Simple lex now support backslashes and quotes. Behavior is
+ similar to shell.
+
+ Qdevice: Support for IPC status cmd in net model
+
+ qdevice certutil: Increase default cert validity
+
+ Qnetd: Don't fall if TLS is disabled
+
+ Qnetd: Log client in IP address:port format
+
+ Qdevice: Don't abrt if IPC connect isn't accepted
+ Also sending buffer is increased from testing value 2 to 1024.
+
+ Qdevice: Implement status command
+
+ Qdevice: Allow compiler warn about unhandled case
+ Remove default case where switch selection is made on top of enum value.
+
+ Qdevice: Add format macro for nodeid, ring, ...
+
+ qdevice: Properly free IPC data on exit
+
+ qdevice: Implement shutdown command
+
+ qdevice: Add dynar prepend
+
+ qdevice: Sending error (output) in IPC
+
+ qnetd: Fix logging function va_arg handling
+
+ qdevice: Add vcatf to dynar-str
+
+ qdevice: Fix cluster-list test
+
+ qdevice: Add functions to manipulate dynar string
+
+ qdevice: Add public prealloc function to dynar
+
+ qdevice: Make simple-lex locale independent
+ Simple-lex is going to be used in protocol so it's not good idea to
+ depend on locale.
+
+2016-06-28 Christine Caulfield <ccaulfie@redhat.com>
+
+ quorum: Return qdevice nodeid in the quorum callbacks (if active).
+
+2016-06-28 Jan Friesse <jfriesse@redhat.com>
+
+ qdevice: Improve socket based IPC
+
+ qnetd: Factorize qnetd-poll-array to generic unit
+
+ qdevice: Add preliminary version of IPC
+
+ qdevice: Add qdevice service scripts
+ Also fix qnetd systemd service.
+
+ qdevice: Remove compiler warning
+
+ qdevice: Unregister votequorum tracking on exit
+
+ qdevice: Add support for daemonize
+ Also local unix socket is now created. In future this is going to be
+ used for qdevice-tool, for now it's used only for handling SIGINT and
+ SIGTERM.
+
+ qdevice-net: Add option to force ip version
+
+ qnetd: Add dead peer (client) detection
+
+ qdevice timer-list: Add reschedule operation
+
+ qdevice: Wait a while before reconnect
+ It's viable to give qnetd a little time before client tries reconnect.
+
+ qnetd: Replace err by qnetd_log on some places
+ err should be used only before qnetd log is fully initialized.
+
+ qnetd: Validate tie-breaker, algo and node dup
+ If new client request tie-breaker or algo which differes from rest of
+ cluster, error message is sent back. Also it's checked if node is not
+ duplicate by comparing node id.
+
+2016-06-28 Christine Caulfield <ccaulfie@redhat.com>
+
+ qdevice-lms: improvements to LMS algorithm
+ Use the new timers to get better response from LMS when the network
+ splits, this also closes a race where the remote side could go inquorate
+ before we confirmed the vote.
+
+ Add client-side (qdevice-net) code to cope with a detached qnetd if we
+ are quorate and have wait_for_all enabled. THat situation will now
+ keep quorum.
+
+2016-06-28 Jan Friesse <jfriesse@redhat.com>
+
+ qdevice: Allow delete timer withing it's callback
+
+ qdevice: Force send of heartbeat
+ Previously client was not force to use heartbeat. Because we have to be
+ able to detect dead client in qnetd, heartbeat setting is now forced.
+ Insted of set_option message, heartbeat is force to exists in init
+ message. This also means that
+ QDEVICE_NET_INSTANCE_STATE_WAITING_SET_OPTION_REPLY can be removed and
+ client is considered as connected after init_reply is received. So
+ currently, set_option is not used (but implementation of these two
+ messages still exists).
+
+ qdevice: Improve timer-list
+ Timer-list is now more efficient and as a side-effect it's possible to
+ add/delete timer in callback.
+
+ qnetd: Add support for qnetd algo timer
+ Algo timer is simplified timer designed for qnetd algorithm. Instead of
+ full timer only one can exists per client. Workflow is:
+ - In one of algorithm callbacks qnetd_client_algo_timer_schedule is
+ called
+ - On timeout .timer_callback is called (for example
+ qnetd_algo_test_timer_callback). It's possible to set send_vote and
+ result_vote to send vote info to client
+ - It's possible to discard timer by calling
+ qnetd_client_algo_timer_abort
+
+ Timer is automatically deleted on client disconnect.
+
+ To make all this possible, qnetd main loop now has support for
+ timer-list (main_timer_list). To be able to handle error and disconnect
+ client from timer callback, client has schedule_disconnect. If this is
+ set to 1, client is disconnected on current call of poll loop.
+
+ qdevice-net: Allow connect to choose lists to send
+ Also disconnect and connect can now affect vote timer.
+
+ qnetd-algo-utils: Remove goto
+
+ qdevice-net: Support tls required and fix leaks
+
+ qdevice tlv: Remove default/return code redundancy
+
+ qdevice-net: Free send buffer on error (leak)
+
+ qnetd: Return lock file fd
+
+ qdevice-net: Ensure to free non blocking client
+
+ Refactor qdevice-net
+ - corosync-device-net as binary is gone. Replacement is
+ corosync-qdevice
+ - corosync-qdevice has support for multiple models (only net is
+ currently implemented)
+ - Completelly redesign qdevice-net main loop.
+ - Connect is non blocking
+ - Cmap and Votequorum events are handled even before connect to
+ qnetd. Algorithm gets send_node_list and vote set so it's not needed
+ to check connection status and also vote_timer is running and voting
+ until something changes (configuration or votequorum node list)
+ - If connect fails, algorithm_disconnected with new reason
+ CANT_CONNECT_TO_THE_SERVER is called
+ - Logging for qdevice is based on libqb logging functions. Also
+ logging configuration from corosync.conf is now used and dynamic
+ changes of configuration are handled.
+ - Added qdevice_net_algorithm_config_node_list_changed
+ - Changed qdevice_net_algorithm_votequorum_node_list_notify in respect
+ of adding send_node_list so it's similar to other functions.
+
+2016-06-28 Christine Caulfield <ccaulfie@redhat.com>
+
+ votequorum: Allow wait_for_all with qdevice
+
+ qnetd: Use ring_id, not client->last_ring_id in algorithms
+ ring_id should only be copied into the client structure after the
+ algorithm has run (so the last one is also available), so fix the
+ algorithms to use the passed-in ring_id where available.
+
+ Also tidy some debug logging in algo-lms
+
+ qnetd-algo: Fix list traversal corruption when freeing partitions.
+ TAILQ_* doesn't have a safe iterator for use when freeing entries, so the
+ only safe way of doing it (without assuming implementation) is to
+ restart the iterator after freeing the structure.
+
+2016-06-28 Jan Friesse <jfriesse@redhat.com>
+
+ Improve qdevice
+ - Add support for cmap node list configuration change
+ - Add client side algorithms
+ - Check if currently received ring id in membership message
+ equals to last sent ring id
+ - Send config node list only if config node list really changes and not
+ after every reload
+ - Add tlv_ring_id_eq (replacing qnetd_algo_rings_eq) so it's usable in
+ client
+ - Move debug logs from algo-test into qnetd-log-debug.c and call them in
+ proper places (= logs are now algorithm independent)
+ - Fix memory leak in msg
+
+2016-06-28 Christine Caulfield <ccaulfie@redhat.com>
+
+ qnetd-algo: Refactor common routines
+ Move several commonly used routines into their own
+ qnetd-algo-utils.[ch] files and change over to using
+ the ring_id held in the client structure rather than
+ managint it ourself.
+
+ qnetd: Add ring_id to client structure
+
+ algo-lms: some tidying
+
+2016-06-28 Jan Friesse <jfriesse@redhat.com>
+
+ qnetd: Make proper support for ipv4/6
+ - Add option for forcing ip version 4 or 6
+ - Choose new default port. It's now 5403. Exactly one less than used by
+ corosync.
+ - Fix compiler warning
+
+ qnetd: Add init script
+
+ qnetd: Refactor
+
+ qnetd: Really daemonize
+
+2016-06-28 Christine Caulfield <ccaulfie@redhat.com>
+
+ qdevice: qnetd_algo_lms: Fix nominated tie_breaker node
+
+ qnetd: lms: Add support for other tie_breaker options.
+
+ qnetd: Add tie_breaker options to 2nodelms
+
+2016-06-28 Jan Friesse <jfriesse@redhat.com>
+
+ qdevice: Add tie_breaker option
+ Tie-breaker can be used in algorithm to decide if algorithm should
+ prefer highest, lowest or some concrete node id.
+
+ qnet: Add TLV_VOTE_NO_CHANGE
+ State used for informative only callbacks (quorum node list) and
+ possibly informative only callbacks (configuration node list). Client
+ doesn't change cast vote timer state.
+
+ qnet: Migrate to new votequorum API
+
+2016-06-28 Christine Caulfield <ccaulfie@redhat.com>
+
+ qdevice: 2nodelms: don't split-brain when the primary node comes back.
+
+ qnetd: lms: Fix search for node/ring_id check
+ We were looking for us in other node lists, rather than
+ others in our nodelist.
+
+ Also, remove debug print in votequorum.c
+
+ votequorum: Fix up quorum/nodelist callbacks
+ This patch tidies the two state change callbacks and explains them
+ in the man page:
+
+ The difference between votequorum_nodelist_notification_t and
+ votequorum_quorum_notification_t is subtle but important.
+ The 'nodelist' callback is sent at the start of a cluster state
+ transition and contains the new ring_id and only the list of
+ nodes that are included in the sync state - ie only active nodes. No
+ quorum information is included this callback because it is not
+ available at that time.
+
+ The 'quorum' callback is sent after the cluster state transition has
+ completed and does contain quorum information.
+ In addition, the nodelist contains a list of all nodes known to
+ votequorum (whether up or down) and their state as well
+ as information about the quorum device attached (if any). quorum
+ callbacks will not be sent for qdevice up and down
+ events unless they affect quorum.
+
+2016-06-28 Jan Friesse <jfriesse@redhat.com>
+
+ qnetd: Some small improvements
+
+ qnetd: Improve logging
+
+2016-06-28 Christine Caulfield <ccaulfie@redhat.com>
+
+ votequorum: split callbacks into nodelist and quorum
+ This split is needed for qdevice, so that it gets the ring_id and
+ nodelist as part of the sync process and not afterwards - when quorum
+ has been calculated.
+
+ As this is and unsupported API I'm not too worried about breaking
+ existing code - all the clients I know of are using the quorum API
+ anyway as they should be.
+
+2016-06-28 Jan Friesse <jfriesse@redhat.com>
+
+ qdevice-net: Copy correct ring id in votequorum cb
+
+2016-06-28 Christine Caulfield <ccaulfie@redhat.com>
+
+ qnetd: Add LMS algorithm
+ Only lightly tested so far
+
+2016-06-28 Jan Friesse <jfriesse@redhat.com>
+
+ Improve qdevice-net
+ - Add cast vote timer (qdevice-net now really votes)
+ - In sync phase it's impossible retreive cmap config version so it's no
+ longer sent in membership node list
+ - Refactor qdevice-net
+
+2016-06-28 Christine Caulfield <ccaulfie@redhat.com>
+
+ votequorum: make corosync_quorumtool show full ring_id
+ Add the ring leader node_id to corosync_quorumtool. This is
+ only shown when votequorum is active
+
+ qnetd: move 2nodelms algo files to the right directory
+ No, I don't know how that happened.
+
+ qdevice-net: add a 2node Last Man Standing algorithm Signed-off-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2016-06-28 Jan Friesse <jfriesse@redhat.com>
+
+ qdevice-net: Implement missing messages handlers
+
+ qnetd-certutil: Fix master node variable
+
+ corosync-qnetd-certutil: Delete tabs
+
+ corosync-qnetd-certutil: Delete dev comment
+
+2016-06-28 Christine Caulfield <ccaulfie@redhat.com>
+
+ qnetd: Move algorithms_register into qnetd-algorithms.c
+ and fix qnetd_algorithm_vote_info_reply_received
+
+2016-06-28 Jan Friesse <jfriesse@redhat.com>
+
+ corosync-qnetd-certutl: Improvements
+ - Location of certificates is now correctly set depending on operation
+ (qnetd/node)
+ - Added quick start mode
+
+2016-06-28 Christine Caulfield <ccaulfie@redhat.com>
+
+ qnetd: Make it easier to add algorithms
+ Put the algorithms into an array of structure pointers
+ (a bit like corosync services) so we can easily add more
+ without having huge switch statements.
+
+ I haven't added any code to the client end that parses the
+ name into the enum. Yet.
+
+ Don't attempt to free a string we haven't been given.
+
+2016-06-28 Jan Friesse <jfriesse@redhat.com>
+
+ qnetd: Improvements
+ - Move adding client to cluster to init phase instead of preinit
+ - Implement missing ask for vote and vote info messages
+ - Fix cluster name memory leak
+ - Refactor unexpected message handler to one generic function
+ - Move qnetd_client_send_err to new file
+ - Add qnetd_client_send_vote_info
+
+ qnetd: Add skel of ffsplit algo and cluster list
+
+ Qnetd improvements
+ - Complete config and membership node list callbacks
+ - Add client disconnect callback
+ - Always send msg_seq_num in node list
+ - Store config and last membership node list
+
+ Qnet improvements
+ - Support for membership node list
+ - Initial support for "pluggable" algorithms
+
+ Qdevices-net improvements
+ - Implement node list
+ - Implement send buffer list
+ - Add nodelist message type
+ - Add ring_id, config_version, data_center_id, node_state, node_info,
+ node_list_type and vote msg options
+
+2016-06-28 Christine Caulfield <ccaulfie@redhat.com>
+
+ votequorum: Make display of qdevice more intuitive.
+ corosync-quorumtool displays the votes of the qdevice whether
+ or not it is active. This is confusing because if it is not active
+ then the display looks like there is a vote being contributed to
+ quorum when there is not.
+
+ This patch displays 0 for qdevice votes if the device is present
+ (but inactive) and adds the votes after the name. If the device is
+ contributing votes then they are displayed as normal.
+
+2016-06-28 Jan Friesse <jfriesse@redhat.com>
+
+ Improve qnet
+
+ Initial commit of qdevice net
+
+ config: get_cluster_mcast_addr error is not fatal
+
+2016-06-27 bliu <bliu@suse.com>
+
+ low:typo fix in sam.h
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2016-06-22 Ferenc Wágner <wferi@niif.hu>
+
+ Fix typo: Diabled -> disabled
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ Fix typo: alocated -> allocated
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ Fix typo: retrive -> retrieve
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ Fix typo: aquire -> acquire
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ Fix typo: Uknown -> Unknown
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ Fix typo: interger -> integer
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ Fix typo: funtion -> function
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ cmap_track_add.3.in: fix typo: bellow -> below
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2016-05-27 Christine Caulfield <ccaulfie@redhat.com>
+
+ logconfig: Fix logging reload disabling logfiles
+ In my previous logconfig patch, adding a subsys so the
+ logging stanzas could disable logging to a file, because
+ the subsys closed the file used by the main logging.
+
+ This patch only applies defaults to higher-level logging and
+ non-deprecated keys.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2016-05-27 yuusuke <yusk.iida@gmail.com>
+
+ wd: Warn if values are out of range
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ parser: WD Read type correctly from corosync.conf
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2016-05-24 Christine Caulfield <ccaulfie@redhat.com>
+
+ Add some more RO keys
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ Reapply config defaults corosync.conf reload
+ There were several places where defaults were not restored
+ if the keys were removed from corosync.conf and the file reloaded.
+
+ This patch adds those back so that reloading corosync.conf
+ has the expected effect when keys are deleted.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2016-05-17 Jan Friesse <jfriesse@redhat.com>
+
+ schedwrk: Cleanup and make it work on PPC BE
+ Schedwrk is passing hdb handle (64-bit) to
+ totempg_callback_token_create as a context. Context is defined to be
+ pointer, so there is conversion function which stores 64-bit hdb_handle
+ into pointer. Potentially, pointer can be 32-bit. This means, check
+ part of hdb is discarded (and have to get special no_check value in
+ schedwrk_do) later. This works quite well on 32-bit Little-Endian
+ system. Sadly on Big-Endian system, check partition of hdb is stored
+ instead of value. Result is error of hdb_handle_get call.
+
+ Proposed solution is to pass handle pointer to
+ totempg_callback_token_create as context. This means full hdb (check +
+ value) can be used in schedwrk_do (easier detection of memory
+ corruption).
+
+ Main reason for this patch is to remove usage of pointer as integer
+ value.
+
+ Small drawback of given solution is that handle pointer must be memory
+ allocated on heap or static memory, making API more bug-prone. Current
+ usage of schedwrk API across corosync always use memory in .text
+ section (safe), so it's not a problem.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ cmapctl: Handle corosync errors in print_key func
+ print_key handles only CS_ERR_TRY_AGAIN error. If different error is
+ returned, print_key loops forewer.
+
+ Solution is to handle all errors.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2016-05-12 Michael Jones <jonesmz@jonesmz.com>
+
+ Adds doxygen stubs to include directory
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2016-05-03 Michael Jones <jonesmz@jonesmz.com>
+
+ Add clang-format configuration file
+ This .clang-format file is written for clang-format version 3.7.1
+
+ I've attempted to set the options for clang-format so that the
+ difference between the current code, and the result of the clang format
+ call is as small as possible.
+
+ Unfortunately, clang-format doesn't yet have the ability to handle every
+ single possible formatting option, so it's not perfect yet.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2016-05-03 Valentin Vidic <Valentin.Vidic@CARNet.hr>
+
+ wd: make watchdog device configurable
+ Add configuration option resources.watchdog_device allowing runtime
+ selection of watchdog device. Useful for newer servers having more
+ than one watchdog available (IPMI and iTCO).
+
+ Special value "off" disables watchdog in configuration rather than
+ just using build options. Useful when watchdog device is needed
+ elsewhere (SBD cluster stonith service).
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2016-05-03 Christine Caulfield <ccaulfie@redhat.com>
+
+ logging: Use our own version of basename
+ basename() function has some potentially odd issues on
+ other platforms.
+
+ So, to be safe, here's an internal version.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2016-04-26 Christine Caulfield <ccaulfie@redhat.com>
+
+ logsys: fix TOTEM logging when corosync built out of tree
+ If corosync is built out-of-tree (passing --srcdir to configure) then
+ TOTEM logging doesn't print anything.
+
+ This is caused by the source filenames (from __FILE__ at compilation
+ time) having the configured path in them - in this example
+ ../corosync/exec/totemudp.c etc. The list of totem source filenames
+ passed to libqb logging facility only has the basenames so the filenames
+ never match up as libqb does an exact string match.
+
+ I looked into fixing this in libqb but it causes a regression. We can't
+ simply basename() __FILE__ at the point of calling log_printf as it's i
+ common also to use __FILE__ to generate the logging source, and
+ using basename() on both removes the distinction between similarly named
+ files from different directories which could be a requirement.
+
+2016-04-22 Christine Caulfield <ccaulfie@redhat.com>
+
+ parser: Make config file parser more hierarchy
+ pass 'state' down the stack so that the state of the
+ hierarchy doesn't get lost when there are unexpected items
+ in the config hierarchy.
+
+ Don't bother setting 'state' on SECTION_END as there's no point
+ now we're going back up the stack.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2016-04-07 Jan Friesse <jfriesse@redhat.com>
+
+ totemconfig: Explicitly pass IP version
+ If resolver was set to prefer IPv6 (almost always) and interface section
+ was not defined (almost all config files created by pcs), IP version was
+ set to mcast_addr.family. Because mcast_addr.family was unset (reset to
+ zero), IPv6 address was returned causing failure in totemsrp.
+ Solution is to pass correct IP version stored in
+ totem_config->ip_version.
+
+ Patch also simplifies get_cluster_mcast_addr. It was using mix of
+ explicitly passed IP version and bindnet IP version.
+
+ Also return value of get_cluster_mcast_addr is now properly checked.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2016-02-24 Jan Friesse <jfriesse@redhat.com>
+
+ cpg: Handle ipc error in cpg_zcb_alloc/free
+ - Error returned by coroipcc_msg_send_reply_receive is now correctly
+ handled.
+ - If munmap fails, error is set to proper value and handle is put back
+ into handle_db
+
+2016-02-24 Athira Rajeev <atrajeev@linux.vnet.ibm.com>
+
+ cpg: Memory not unmapped in cpg_zcb_free
+ Function in cpg_zcb_alloc (from code lib/cpg.c) creates
+ /dev/shm/corosync_zerocopy-XXXXX and does mmap
+
+ The memory is allocated by corosync service (function zcb_alloc
+ in exec/cpg.c) also and both shares this memory via mmap
+ (uses MAP_SHARED in mmap call)
+
+ Corosync calls unlink which deletes the file from /dev/shm while
+ closing the file descriptor, but unmap is not happening correctly
+ while calling cpg_zcb_free.
+
+ So:
+ - still the deleted file holds the memory
+ - As munmap is not happening correctly, the number of mappings per
+ process gets exceeded and corosync dies with ENOMEM
+
+ From gdb, the size passed to munmap appears to be zero and address
+ looks wrong. Also in the code return code of munmap is not checked.
+
+ The patch adds check for:
+ - munmap return code and getting correct address for munmap
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2016-02-10 Jan Friesse <jfriesse@redhat.com>
+
+ totempg: Fix memory leak
+ Previously there were two free lists. One for operational and one for
+ transitional state. Because every node starts in transitional state and
+ always ends in the operational state, assembly was always put to normal
+ state free list and never in transitional free list, so new assembly
+ structure was always allocated after new node connected.
+
+ Solution is to have only one free list.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+ Reviewed-by: Steven Dake <stdake@cisco.com>
+
+2016-01-27 Richard B Winters <rik@mmogp.com>
+
+ Fix spelling error in binary corosync
+ - Changed paramater to parameter in exec/logcconfig.c
+
+ Change-Id: I8a24b0ef5c6621dc6c19d7decbdfe7a255afd10d
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ Fix spelling error in binary corosync-cfgtool
+ - Changed reenable to re-enable in tools/corosync-cfgtool.c
+
+ Change-Id: I0457bf3040a454a44f0d8343dd2cd8bf8fad16e0
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ Fix spelling error in manual sam_overview 8
+ - Changed usefull to useful
+
+ Change-Id: I2d7872b21e889202cd2b7752db4c76f18fffa95d
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2016-01-27 Jan Friesse <jfriesse@redhat.com>
+
+ cmap_keys.8: Fix spelling and grammar errors
+ - "There are informations" changed to "There is information"
+ - Other occurrences of informations changed to information
+
+ Original patch was created by Richard B Winters <rik@mmogp.com>, so
+ thanks for it.
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+2016-01-27 Richard B Winters <rik@mmogp.com>
+
+ Fix spelling errors in manual corosync.conf 5
+ - dont to don't
+ - overriden to overridden
+ - informations to information
+
+ Change-Id: If6644694d750c30ba9f5f43b4eb852485613d64a
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ Fix grammer error in manual votequorum_trackstart
+ "allows to" was updated to read "allows one to"
+
+ - With a subject it's grammatically correct.
+
+ Change-Id: I9559e31c780e211b651744c6eaa056ce8d4c3db1
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ Add section in manual title for cpg_zcb_free 3
+ Change-Id: Ib80face38dce0345e649297d16cf8a63c5b0e8c1
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ Add section in manual title for cpg_zcb_alloc 3
+ Change-Id: I8c5d6af915203533c80e4eaa574e305a46d74815
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ Fix incorrect spelling of retrieve from retreive
+ Corrected the spelling of retrieve, where it was spelled as retreive.
+
+ - There were two cases of this mispelling; one
+ upper-case and one lower-case
+
+ Change-Id: Ic97fd210d8d3ae7e568e5a2e5d97c6220d2ff628
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2016-01-05 Jan Friesse <jfriesse@redhat.com>
+
+ Update corosync.spec source link
+
+ Update gitignore files
+
+ Remove all links to old ML
+
+2016-01-04 Ruben Kerkhof <ruben@rubenkerkhof.com>
+
+ totemsrp: Fix clang warning (tautological compare)
+ gsfrom is always >= 0
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ configure.ac: Make location of .pc overrideable
+ FreeBSD stores them in /usr/local/libdata/pkgconfig
+
+ This allows us to remove some local hooks in the process.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ Remove a few unused variables and functions
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ configure.ac: We don't need no C++ compiler
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ configure.ac: Remove deprecated AC_PROG_LIBTOOL
+ AC_PROG_LIBTOOL is deprecated version of LT_INIT. Because LT_INIT is
+ called we can remove it.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ configure.ac: Remove AC_PROG_RANLIB
+ It was obsoleted by libtool and we don't use ranlib standalone.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ configure.ac: make foreign apply to all Makefiles
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ Remove unused, obsolete check
+ From autoconf info Obsolete Macros:
+
+ "These days, it is portable to assume C89, and that signal
+ handlers return void, without needing to use this macro or RETSIGTYPE."
+
+ And we indeed assume so.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2015-12-16 Ruben Kerkhof <ruben@rubenkerkhof.com>
+
+ Fix detection of qb_log_thread_priority_set
+ This fixes detection of libqb function qb_log_thread_priority_set
+ if it was installed outside of the standard library search
+ path, in my case /opt.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ cpghum: Fix type of recv_crc
+ Fixes build on FreeBSD which doesn't have ulong
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ Check for fdatasync
+ If we don't have it, fall back to fsync
+
+ Fixes the build on FreeBSD
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ Fix detection of warning flags for clang
+ Using ./configure CC=clang, the following flags are detected
+ as supported:
+
+ checking whether clang supports "-Wgnu89-inline"... yes
+ checking whether clang supports "-Wno-strict-aliasing"... yes
+
+ Which results in a lot of warnings during make:
+
+ warning: unknown warning option '-Wunsigned-char'
+ [-Wunknown-warning-option]
+ warning: unknown warning option '-Wgnu89-inline'
+ [-Wunknown-warning-option]
+
+ Clang doesn't support these flags, but the compile check returns a
+ warning, not an error:
+
+ configure:16649: checking whether clang supports "-Wunsigned-char"
+ configure:16662: clang -E -Wunsigned-char conftest.c
+ warning: unknown warning option '-Wunsigned-char'
+ [-Wunknown-warning-option]
+ 1 warning generated.
+ configure:16662: $? = 0
+ configure:16663: result: yes
+
+ Use -Wunknown-warning-option -Werror if supported
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2015-11-27 Hideo Yamauchi <renayama19661014@ybb.ne.jp>
+
+ quorum: Display node id as unsigned int.
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2015-11-23 Jan Friesse <jfriesse@redhat.com>
+
+ cts: InitClusterManager is now BootCluster
+ This is forward port of flatiron-cts
+ fbe1721e676eafd1f25f470234b646904f54e3f3.
+
+ Thanks to bliu <bliu@suse.com> for pointing out.
+
+2015-11-16 Christine Caulfield <ccaulfie@redhat.com>
+
+ totemudp: Move udp bind() so that multicast works with IPv6
+ It seems that the IPv6 multicast parameters only take effect when bind()
+ is called, so I've moved the mcast recv socket bind() to the bottom of
+ totemudp_build_sockets_ip().
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2015-11-13 Hideo Yamauchi <renayama19661014@ybb.ne.jp>
+
+ cfgtool: Display nodeid as unsigned int
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2015-10-22 Christine Caulfield <ccaulfie@redhat.com>
+
+ votequorum: Don't send multiple callbacks when nodes join
+ This patch aligns the votequorum callbacks so that they are
+ the same as the quorum ones. Previously it was quite common
+ for votequorum to send one callback for every node in the cluster
+ when a single new node joined (because it sent one for every
+ nodeinfo message it received).
+
+ This new system makes much more sense in itself and being
+ consistent with the internal quorum is also an advantage!
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2015-09-18 Ferenc Wágner <wferi@niif.hu>
+
+ man: Add synopsis for cpg_zcb_alloc and free
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ man html index: Update index
+ - add link to cmap_keys(8)
+ - remove link to cpg_groups_get(3)
+ - add missing cpg_* and votequorum_qdevice_* functions
+ - corosync-fplay has already been removed by ab32894
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2015-08-28 Ferenc Wágner <wferi@niif.hu>
+
+ votequorum: Make sure cs_error_t is defined
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2015-08-26 Ferenc Wágner <wferi@niif.hu>
+
+ Close Doxygen group in include/corosync/cmap.h
+ This avoids warning: end of file while inside a group.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ Doxygen fix for cmap_iter_next()
+ Remove the extra cmap_ prefix of the iter_handle parameter.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ configure: Correct help entry for logdir
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ totmesrp: Fix typo in log message
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ configure: typo in include
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ man page: Correct option letter for DBus
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2015-07-14 Christine Caulfield <ccaulfie@redhat.com>
+
+ wd: fix setting of watchdog timeouts
+ Fix setting of initial watchdog timeout, and also changing of timeout.
+
+ Remove redundant starting of timer in exec_init_fn
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2015-07-02 Jason HU <huzhijiang@gmail.com>
+
+ CFG: Prevent CFG orignating messages during SYNC
+ During SYNC, corosync-cfgtool -R/-H commands can pass through IPC then
+ send totem messages. This may corrupts
+ assembly_list_inuse/assembly_list_free if those messages are recedived
+ after SYNC is done.
+
+ The solution is marking related CFG APIs as
+ CS_LIB_FLOW_CONTROL_REQUIRED.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2015-06-22 Jan Friesse <jfriesse@redhat.com>
+
+ Don't link with libz when not needed
+ Commit 8cc8e513633a1a8b12c416e32fb5362fcf4d65dd added check for libz
+ resulting in linking with lib z for all libraries. This is not expected
+ behavior. Patch solves it by making defining automake conditional so
+ cpghum is linked only if libz is available and LIBS variable is not
+ modified at all.
+
+ Log: Add logrotate configuration file
+ In cman era corosync was depending on logrotate file distributed by
+ cman. It's good idea to logrotate also on systems without cman (new
+ clusters).
+
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ Add note about rrp active beeing unsupported
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2015-06-18 Christine Caulfield <ccaulfie@redhat.com>
+
+ votequorum: Fix auto_tie_breaker behaviour in odd-sized clusters
+ auto_tie_breaker can behave incorrectly in the case of a cluster
+ with an odd number of nodes. It's possible for a partition to
+ have quorum while the other side has the ATB node, and both will
+ continue working. (Of course in a properly configured cluster one side
+ will be fenced but that becomes an indeterminate race .. just what ATB
+ is supposed to avoid).
+
+ This patch prevents ATB from running in a partition if the 'other'
+ partition might have quorum, and also mandates the use of wait_for_all
+ in clusters with an odd number of nodes so that a quorate partition
+ cannot start services or fence an existing partition with the tie
+ breaker node.
+
+ Signed-Off-By: Christine Caulfield <ccaulfie@redhat.com>
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2015-06-12 Christine Caulfield <ccaulfie@redhat.com>
+
+ totemsrp: Improve logging of left/down nodes
+ This patch from Hideo Yamauchi improves the logging of
+ whether nodes leave the cluster cleanly or uncleanly,
+ making it easier to determine if a node ws shut down
+ by the operator. There is also the possibility that a
+ LEAVE message could get missed (due to the node being
+ in flush state) so this can also make that clearer.
+
+ The modifications are as follows.
+
+ Change 1) I added the list which maintained LEAVE node to totemsrp.
+ Change 2) I added registration, a search, the handling of to clear LEAVE
+ node.
+ Change 3) I added the output to log.
+ Change 4) I changed an output level of the log.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2015-04-17 Christine Caulfield <ccaulfie@redhat.com>
+
+ totem: Log a message if JOIN or LEAVE message is ignored
+ As per recent email thread, this patch adds a log message if a JOIN or
+ LEAVE message is discarded while corosync is flushing the receive queue.
+
+ While ignoring a JOIN message is harmless (it will be resent), ignoring
+ a LEAVE message can cause a longer state transition as it is treated as
+ a node crashing rather than leaving gracefully, so the system admin
+ might be confused as to the cause.
+
+ Unfortunately, we can't (at the totemudp level) distinguish between JOIN
+ or LEAVE messages without a lot more protocol-specific code creeping in
+ the lower layer so the message is left ambiguous.
+
+2015-04-10 Christine Caulfield <ccaulfie@redhat.com>
+
+ totemconfig: Check for duplicate nodeids
+ Having duplicate nodeids in corosync.conf can play havoc with a cluster,
+ so (as suggested by someone on this list) here is some code to check
+ that all nodeids are unique. Even if a nodeid is not specified it will
+ check to be sure that the ID generated from the IP address (ipv4 only)
+ does not clash with one that is provided.
+
+ It logs all non-unique nodeids to syslog, but only the last is reported
+ on the command-line to the user which should be enough to get them to
+ check further. At startup this will cause corosync to fail to start.
+
+2015-03-16 Christine Caulfield <ccaulfie@redhat.com>
+
+ quorum: don't allow quorum_trackstart to be called twice
+ If quorum_trackstart() or votequorum_trackstart() are called twice with
+ CS_TRACK_CHANGES then the client gets added twice to the notifications
+ list effectively corrupting it. Users have reported segfaults in
+ corosync when they did this (by mistake!).
+
+ As there's already a tracking_enabled flag in the private-data, we check
+ that before adding to the list again and return an error if
+ the process is already registered.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2015-03-10 Jan Friesse <jfriesse@redhat.com>
+
+ Really add cpghum
+
+2015-03-05 Christine Caulfield <ccaulfie@redhat.com>
+
+ cpg: Add support for messages larger than 1Mb
+ If a cpg client sends a message larger than 1Mb (actually slightly
+ less to allow for internal buffers) cpg will now fragment that into
+ several corosync messages before sending it around the ring.
+
+ cpg_mcast_joined() can now return CS_ERR_INTERRUPT which means that the
+ cpg membership was disrupted during the send operation and the message
+ needs to be resent.
+
+ The new API call cpg_max_atomic_msgsize_get() returns the maximum size
+ of a message that will not be fragmented internally.
+
+ New test program cpghum was written to stress test this functionality,
+ it checks message integrity and order of receipt.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2015-03-05 Andrey N. Groshev <greenx@yandex.ru>
+
+ totemsrp: Format member list log as unsigned int
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2015-03-02 Christine Caulfield <ccaulfie@redhat.com>
+
+ Don't allow both two_node and auto_tie_breaker in corosync.conf
+ The two_node and auto_tie_breaker options are incompatible as they
+ specify conflicting methods of determining the quorate half of a cluster
+ partition.
+
+ This patch detects this error in corosync.conf, issues a message and
+ disables two_node if auto_tie_breaker is present.
+
+ Signed-Off-By: Christine Caulfield <ccaulfie@redhat.com>
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ Votequorum: Fix auto_tie_breaker default
+ The default for auto_tie_breaker should be 'lowest' - which is what it
+ was before the extended ATB functionality of auto_tie_breaker_node was
+ added, and what the documentation states.
+
+ However this was broken so that if auto_tie_breaker_node was not
+ specified then auto_tie_breaker itself was ignored. This patch fixes
+ that.
+
+ It also fixes a typo in a comment.
+
+ Signed-Off-By: Christine Caulfield <ccaulfie@redhat.com>
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2015-01-21 Jan Friesse <jfriesse@redhat.com>
+
+ Handle adding and removing UDPU members atomically
+ When config file is reloaded with removed UDPU member, internal icmap
+ index of nodelist.node can change. This can result in removal and then
+ adding back node. This, with UDPU alive filtering (where member is by
+ default considered as not a member) makes corosync not sending messages
+ to such members resulting in new membership creation.
+
+ Solution is to properly test which members were really deleted and added
+ (instead of relying on internal and dynamic naming of icmap hash table
+ key name).
+
+ Also trully dynamic add and remove node (via cmap) is now handled by
+ same function so totem_config->interfaces is now updated properly.
+
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+2015-01-20 Jan Friesse <jfriesse@redhat.com>
+
+ corosync_ring_id_store: Use safer permissions
+ corosync_ring_id_store should use same (safer) permissions as
+ corosync_ring_id_create_or_load for (eventually) newly created ringid
+ file.
+
+ Credit to Sjerek for finding this problem.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2015-01-15 Jason <huzhijiang@gmail.com>
+
+ totem: Ignore duplicated commit tokens in recovery
+ In active rrp mode, commit tokens are treated as mcast data messages,
+ thus, rrp directly delivers them to srp layer by active_mcast_recv().
+ This will result in duplicated commit tokens being received by srp from
+ different heartbeat links. If node is in recovery state and has already
+ sent out the initial orf token, those duplicated commit tokens will
+ cause message_handler_memb_commit_token() to send initial orf token
+ again! This is wrong because it resets the orf token content in
+ instance->orf_token_retransmit, which breaks the token retransmission
+ state.
+
+ Furthermore, by sending those initial orf tokens again and again,
+ it may lead active_token_recv() to drop some subsequent orf tokens.
+ It is OK for rrp because srp will do token retransmission,
+ but as said above, srp retransmission state has already been broken,
+ so finally we meet a "token lost in recovery state" condition caused
+ by software. If token timeout value is large, then it will takes long
+ time to create a new ring.
+
+ This can be reproduced by having two noded set to active rrp mode, with
+ two heartbeat links. Then with one node always on, let the other one do
+ stop/start again and again. It has a low probability to reproduce.
+ In theory, I think, the more heartbeat links used, the more easily it
+ can be reproduced.
+
+ This problem can be resolved by letting
+ message_handler_memb_commit_token() to ignore duplicated commit tokens
+ in recovery state if node (the ring representation) has already sent
+ out the initial orf token.
+
+ Different from prev take, this version do not depends on stored token
+ data but uses originated_orf_token in totemsrp_instance to remember
+ if initial orf token has been already originated for current membership.
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2015-01-14 Jan Friesse <jfriesse@redhat.com>
+
+ Log auto-recovery of ring only once
+ Make sure to log auto-recovery of ring only once. Every
+ MESSAGE_TYPE_RING_TEST_ACTIVATE receive is logged, but with lower
+ priority and more detailed information.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2015-01-05 Jan Friesse <jfriesse@redhat.com>
+
+ Set RR priority by default
+ Experience with larger production clusters showed that setting RR
+ priority for corosync is viable for prevent random fencing, ...
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ automake: Check minimum automake version
+ Corosync needs automake version at least 1.11. Patch adds minimum
+ version check.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2014-12-08 Jason <huzhijiang@gmail.com>
+
+ Reset timer_problem_decrementer on fault
+ After a heartbeat link's FAULTY and its auto re-enable,
+ active_instance->timer_problem_decrementer did not reset to zero. So in
+ the next timer_function_active_token_expired() round,
+ active_timer_problem_decrementer_start() will not be called. This will
+ result in that the active_instance->counter_problems of this link can
+ not be decreased any more. Cause rrp lose the ability to tolerate
+ network fluctuation.
+
+ This problem can be reproduced by the following sequence:
+ 1) Set RRP in active mode, configure at least 2 heartbeat links.
+ 2) Unplug one link till corosync-cfgtool -s shows it is FAULTY.
+ 3) Re-plug this link then corosync-cfgtool -s shows it is active with
+ no faults.
+ 4) Unplug this link again but quicky re-plug it before it becomes
+ FAULTY.
+ 5) Finally, you can see corosync-cfgtool -s shows it is in
+ "Incrementing problem counter" state despite it currently is physically
+ healthy.
+
+ It can be solved by not forget to reset timer_problem_decrementer to
+ zero in active_timer_problem_decrementer_cancel().
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2014-11-24 Jan Friesse <jfriesse@redhat.com>
+
+ config: Ensure mcast address/port differs for rrp
+ When using multiple interfaces, it's necessary to use different
+ multicast address/port pair for each interface to make
+ rrp work correctly. This is now checked in parser.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ config: Process broadcast option consistently
+ Broadcast option is global but in config set in interface section. When
+ more interfaces are defined, only broadcast from last section was used.
+
+ Solution is to use broadcast whenever at least one interface use
+ broadcast.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ config: Make sure user doesn't mix IPv6 and IPv4
+ Checking code was there, sadly not correct, so it was possible to enter
+ one bindnet addr as IPv4 and second as IPv6. Fix is trivial.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2014-10-13 Jan Friesse <jfriesse@redhat.com>
+
+ man page: Improve description of token timeout
+ With introduction of token_coefficient, token timeout defined in
+ configuration file may be no longer reflect real token timeout, what may
+ be confusing.
+
+ Enhanced description hopefully fix that.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ Store configuration values used by totem to cmap
+ Some totem configuration values (like token, consensus, ...) are ether
+ computed or default value is used. It's hard to find out, what
+ value is really used.
+
+ Solution is to store values in cmap.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2014-10-13 Christine Caulfield <ccaulfie@redhat.com>
+
+ manpage: Fix English
+ While I was looking at the above man page changes I thought I'd review
+ the rest of it. So here are some more English fixes for the cmap_keys.8
+ man page
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2014-10-08 Jan Friesse <jfriesse@redhat.com>
+
+ init: Don't wait for ipc if corosync doesn't start
+ Init script now checks return code of executing corosync command. If it
+ fails, ipc_wait section is skipped, resulting in much faster failure of
+ init script.
+
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+2014-10-01 Jan Friesse <jfriesse@redhat.com>
+
+ Adjust MTU for IPv6 correctly
+ MTU for IPv6 is 20 bytes larger then IPv4. This fact was not taken into
+ account so IPv6 packets were larger then MTU resulting in fragmentation.
+
+ Solution is to substract correct IP header size.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2014-09-06 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ [crypto] fix crypto block rounding/padding calculation
+ libnss is "weird" in this respect as some block sizes are hardcoded,
+ others need to be determined dynamically.
+
+ For AES we need to use the values we know since GetBlockSize would
+ return errors, for 3des (that hopefully nobody is using) the value
+ returned by GetBlockSize is 8, but let's use the call into libnss
+ to avoid possible conflicts with distro patching or older versions.
+
+ Now, given the correct block size, the old calculation simply added
+ block size to the hdr_size. This is not sufficient.
+
+ We use _PAD encryption methods and we need to take that into account.
+
+ _PAD is calculated given the current input buf len and rounded up
+ to block size boundary, then block_size is added.
+
+ Ideally we would do that on a per packet base but current transport
+ infrastructure doesn't allow it yet.
+
+ So round up the hdr_size to double the block_size reported by the
+ cipher.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2014-08-26 Jan Friesse <jfriesse@redhat.com>
+
+ totemudpu: Send msgs to all members occasionally
+ To follow spec it's needed to send messages to all nodes (not only
+ active members) from time to time to detect merge.
+
+ This is needed in situations when totemsrp merge timer isn't running
+ (because there is enough messages sent by processors) to detect merge.
+
+ Example scenario:
+ - 3 nodes, all of them running cpgverify
+ - One node is isolated (iptables for example)
+ - Node is un-isolated
+
+ Without this commit, node will not merge as long as the cpgverify is
+ running.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ totemudpu: Implement member_set_active
+ Member active is used for sending "multicast" messages only to members
+ of ring. This reduces network load if some nodes are intentionally down.
+ Only regular multicast message load is reduced (messages sent by
+ totemudpu_mcast_noflush_send), because special messages (like hold
+ cancel, join message, ...) still have to be send to all members to
+ ensure correct behavior.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ totemrrp: Implement *_membership_changed
+ All *_membership_changed calls totemnet_member_set_active passing 1 as
+ active parameter for joined nodes and 0 for left nodes.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ totemnet: Add totemnet_member_set_active
+ totemnet_member_set_active together with transport specific
+ member_set_active makes possible for totemnet (and more interestingly
+ transport) to be informed about membership changes.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ totem: Inform RRP about membership changes
+ Services are informed about membership changes, but if same information
+ is needed inside totemrrp or totemnet, it's impossible to gather this
+ information.
+
+ Patch makes this possible for now only for RRP with empty callbacks.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2014-08-25 Jan Friesse <jfriesse@redhat.com>
+
+ Makefile: Do not install TODO file
+
+ TODO: Remove TODO file
+ TODO file has many problems like it's not updated regularly, it's not
+ updated at all in already distributed tarballs, ...
+
+ All relevant RFEs were filled at github as issues with flag "TODO file
+ convert" so file can finally be removed from git.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2014-08-22 Christine Caulfield <ccaulfie@redhat.com>
+
+ corosync-quorumtool: add sort options
+ Adds a -o<a|i|n> option to corosync-votequorum so that the nodes list
+ can be sorted by Address, node Id or Name. The default remains IP
+ address.
+
+ Signed-Off-By: Christine Caulfield <ccaulfie@redhat.com>
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2014-08-18 Christine Caulfield <ccaulfie@redhat.com>
+
+ YKD: Fix loading of YKD quorum module
+ Although YKD is currently unsupported, untested and decprecated it's
+ handy for testing things in the quorum module.
+
+ This patch allows YKD to actually load without an error. It does not fix
+ anything else in the service!
+
+ Also remove vsftype and its reference to YKD being the preferred and
+ default provider from the corosync.conf man page,
+ as that hasn't been true for a considerable time.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2014-08-15 Christine Caulfield <ccaulfie@redhat.com>
+
+ quorumtool: Sort output by nodeid
+ corosync-quorumtool prints the node listing by IP address
+ (as passed back to it from corosync) but this can be
+ counter-intuitive if the node IDs aren't in the same
+ order as the IP addresses. This patch sorts the nodes
+ by node ID so that the output is easier for humans to
+ parse.
+
+ Reviewed-By: Jan Friesse <jfriesse@redhat.com>
+
+2014-08-12 Christine Caulfield <ccaulfie@redhat.com>
+
+ votequorum: Add cmap key to reset wait_for_all
+ It's possible in a two_node cluster (and others but it's more likely
+ with just two) that a node could be booted up after downtime or failure
+ and the other node is not available for some reason. In this case it
+ would not be allowed to proceed because wait_for_all is enforced.
+
+ This patch provides a cmap key to clear this flag in the desperate
+ situation where that becomes necessary. It should only be used with
+ extreme caution and will be wrapped up in pcs which should also check
+ that fencing has been run.
+
+ Signed-Off-By: Christine Caulfield <ccaulfie@redhat.com>
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2014-08-12 Jason HU <huzhijiang@gmail.com>
+
+ Cancel token holding while in retransmition
+ When there is no other activty on ring but only retransmition, and
+ token is in hold mode, the retransmition will become slow. More over,
+ if the retransmition is always fail but token rotation works well, then
+ it takes quite a lone time
+ (fail_to_recv_const * token_hold = 2500 * 180ms = 450sec) for the
+ retransmit requester to meet the "FAILED TO RECEIVE" condition to
+ re-construct a new ring.
+
+ This problem can be solved by checking if retransmits are present
+ before going into hold. If a node is the retransmit requester or
+ the resender, it set my_token_held to 0 to speed up retransmition
+ and omit further unnecessary sending of token_hold_cancel signal.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2014-08-05 Jan Friesse <jfriesse@redhat.com>
+
+ votequorum: Make qdev timeout in sync configurable
+ Configuration option quorum.device.sync_timeout is available for setting
+ qdevice poll timeout for synchronization phase. Default value is 30
+ sec.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ testvotequorum2: Opt for polling with old ringid
+ Option -F is added to force sending old ringid for given number of
+ times. Option is useful for testing failure scenario during corosync
+ synchronization phase.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ votequorum: Block sync until qdevice poll
+ If qdevice is registered a alive, corosync waits in sync phase until
+ timeout expires or qdevice votes with correct nodeid parameter.
+
+ This gives qdevice time to decide to vote or not undisturbed and without
+ time hazard.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ ipc: Process votequorum messages during sync
+ This is needed for qdevice to be able to process messages during
+ synchronization phase.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ votequorum: Add ring id to poll call
+ If votequorum service receives incorrect (not current) ringid, call is
+ ignored and CS_ERR_MESSAGE_ERROR is returned.
+
+ This and previous commits makes incompatible changes in votequorum
+ API/ABI, so library version is increased.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ votequorum: Return current ring id in callback
+ Returning ring id will be used in poll function.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2014-07-25 Christine Caulfield <ccaulfie@redhat.com>
+
+ totemconfig: Make sure join timeout is less than consensus
+ The thesis contains this paragraph:
+
+ " The Join timeout is shorter than the Consensus timeout and is used to
+ increase the probability that Join messages from all currently
+ working processors are received during a single round of consensus."
+
+ Empirically I can confirm that making join less than consensus can cause
+ havoc with a cluster so I think we should enforce this.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2014-07-24 Christine Caulfield <ccaulfie@redhat.com>
+
+ config: Fix typos
+ Fix several places where 'then' is used instead of 'than' in error
+ messages and a comment.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2014-07-24 Jan Friesse <jfriesse@redhat.com>
+
+ corosync-keygen: Replace printf/exit call with err
+ Calling of err makes code shorter, easier to read and eliminates
+ problems with forgotten newline characters.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2014-07-22 Jan Friesse <jfriesse@redhat.com>
+
+ totemconfig: refactor nodelist_to_interface func
+ Move finding of bindaddr in nodelist to generally usable function
+ totem_config_find_local_addr_in_nodelist and refactor
+ config_convert_nodelist_to_interface function to use it.
+
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ totemconfig: totem_config_get_ip_version
+ Add totem_config_get_ip_version to get user configured ip version.
+ Make totem_config_read use this newly introduced function.
+
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ totemconfig: Free ifaddrs list
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+2014-07-21 Vladislav Bogdanov <bubble@hoster-ok.com>
+
+ Slightly rework corosync-keygen.
+ Allow it to create keyfile not in the hardcoded location.
+ Drop root checks.
+ Minor cosmetic fixes to the man-page.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2014-07-21 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ be consistent in using CPPFLAGS vs CFLAGS
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ cleanup after test-driver
+ update .gitignore and make maintainer-clean target
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2014-07-16 Vladislav Bogdanov <bubble@hoster-ok.com>
+
+ Implement config file testing mode
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2014-07-15 Vladislav Bogdanov <bubble@hoster-ok.com>
+
+ corosync-cmapctl: Allow -p option to delete keys
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2014-07-09 Jan Friesse <jfriesse@redhat.com>
+
+ Fix compiler warning introduced by previous patch
+ QB loop signal handler prototype differs from signal(2) prototype.
+ Solution is to create wrapper functions.
+
+2014-07-03 zouyu <hopkings2005@gmail.com>
+
+ Handle SIGSEGV and SIGABRT signals
+ SIGSEGV and SIGABRT signals are now correctly handled (blackbox is
+ dumped and logsys is finalized).
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ fix memory leak produced by 'corosync -v'
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2014-07-01 Kazunori INOUE <kazunori.inoue3@gmail.com>
+
+ systemd: Config example for corosync wd service
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2014-06-27 Jan Friesse <jfriesse@redhat.com>
+
+ votequorum: Do not process events during reload
+ During reload, local_node_pos is deleted and reinstation is handled in
+ totemconfig after reload is finished. votequorum handles this events and
+ tries to reload it's configuration. This led to logging a little scary
+ messages (even nothing bad is happening, because after local_node_pos
+ reinstation everything back to normal).
+
+ Solution is to stop processing events during reload. Sadly, simple
+ tracking of config.reload_in_progress doesn't work because LibQB events
+ triggering order is undefined so votequorum reload handler can be called
+ before totemconfig (and before local_node_pos is reinstatied).
+
+ So new config.totemconfig_reload_in_progress key is defined with very
+ similar semanthic as config.reload_in_progress but set inside
+ totem_reload_notify function. Votequorum then use this new key.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ Make config.reload_in_progress key read only
+ It's not very good idea to allow user apps changing internal key
+ reload_in_progress.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2014-06-12 Jan Friesse <jfriesse@redhat.com>
+
+ Doc: Enhance INSTALL file a bit
+ Some information in INSTALL file were pretty outdated. This patch moves
+ them closer to current release.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ coroparse: More strict numbers parsing
+ Previous safe_atoi didn't check range of input values so if for example
+ user used -1 s token timeout, it was converted to UINT32_MAX without
+ letting user know.
+
+ Another safe_atoi problem was using strtol. This works pretty well on
+ 64-bit systems, where long integer is usually 64-bits long, sadly on
+ 32-bit systems, it is usually 32-bit long. And because strtol returns
+ signed integer, it was not possible to enter 32-bit value with highest
+ bit set.
+
+ Solution is to use strtoll which is guaranteed to be at least 64-bits
+ long and check value range.
+
+ Also error message now contains also information about expected value
+ range.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2014-06-10 Konstantin <konstantin.ponomarenko@gmail.com>
+
+ Install doc: Correct a typo
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2014-06-09 Lidong Zhong <lzhong@suse.com>
+
+ init: change return value when starting corosync
+ When corosync is started by systemd, it would be considered
+ as failed because it returns a non-zero value, even though it
+ starts sucessfully.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2014-06-02 Jan Friesse <jfriesse@redhat.com>
+
+ Move ringid store and load from totem library
+ Functions for storing and loading ring id was in the totem library. This
+ causes problem, what to do when it's impossible to load or store ring
+ id. Easy solution seemed to be assert, but sadly this makes hard for
+ user to find out what happened (because corosync was just aborted and
+ logsys didn't flush)
+
+ Solution is to move these functions to main.c, where is much easier to
+ handle error. This also makes libtotem free of any file system
+ operations.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ Introduce get_run_dir function
+ Run dir (LOCALSTATEDIR/lib/corosync) was hardcoded thru whole codebase.
+ Totemsrp was trying to create and chdir into it, but also
+ takes into account environment variable COROSYNC_RUN_DIR creating
+ inconsistency.
+
+ get_run_dir correctly returns COROSYNC_RUN_DIR (when set) or
+ LOCALSTATEDIR/lib/corosync. This is now used by all functions instead of
+ hardcoded string.
+
+ All occurrences of mkdir/chdir are removed from totemsrp and chdir is
+ now called in main function. Mkdir call is completely removed, because
+ it was not used anyway (check in main.c was called before totemsrp init,
+ so mkdir was never called) and also make install and/or package system
+ should take care of creating this directory with correct
+ permissions/context.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ logsys: Log warning if flightrecorder init fails
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ logsys: Log error if blackbox cannot be created
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2014-05-15 Jan Friesse <jfriesse@redhat.com>
+
+ totemiba: Fix incorrect failed log message
+ rdma_join_multicast failed ... message parameters was swapped.
+
+ Also information about multicast join is now logged as notice.
+
+2014-05-14 Yevheniy Demchenko <zheka@uvt.cz>
+
+ totemiba: Add multicast recovery
+ Totemiba wasn't able to survive SubnetManager handover or
+ restart. If SM was migrated to another node, corosync logged
+ "multicast error" and losses connectivity.
+
+ Commit should solve this situation.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2014-05-09 hfu <askfuhu@gmail.com>
+
+ Indent: Remove newline before else branch start
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ Indent: Remove space in negation of expression
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2014-05-09 Kazunori INOUE <kazunori.inoue3@gmail.com>
+
+ upstart: Make job conf file configurable
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2014-05-07 Jan Friesse <jfriesse@redhat.com>
+
+ config: Allow dynamic change of token_coefficient
+ token_coefficient change in cmap didn't triggered change. So only way
+ how to change token_coefficient was editing config file and reload.
+
+ Patch let's key totem.token_coefficient to be processed so
+ token_coefficient can be dynamically changed.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2014-04-11 Jan Friesse <jfriesse@redhat.com>
+
+ init: Make init script configurable
+ Init script loads /etc/sysconfig/corosync (or /etc/defaults/corosync) by
+ default, but it didn't existed by default and also no options was
+ defined.
+
+ Patch adds COROSYNC_INIT_TIMEOUT (how many seconds to wait for ipc
+ initialization) with default value 1 minute (instead of previous 10
+ seconds, what may be too small value for some productions) and
+ COROSYNC_OPTIONS (by default empty) containing options directly
+ passed to corosync executable.
+
+ Specfile template is also modified to install example of init file
+ configuration.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2014-03-25 Jan Friesse <jfriesse@redhat.com>
+
+ Add token_coefficient option
+ Token coefficient is used only when nodelist is specified and contains
+ at least 3 nodes. If so, real token timeout is then computed as
+ token + (number_of_nodes - 2) * token_coefficient. This allows cluster
+ to scale without manually changing token timeout every time new
+ node is added. This value can be set to 0 resulting in effective
+ removal of this feature.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ totemconfig: Log errors on key change and reload
+ When volatile key was changed (cmap set or reload) and checks fails,
+ nothing was logged.
+
+ Values are now checked and error string is logged on problems.
+
+ Also totem_config is dumped to log (DEBUG level) after every
+ volatile key change and every reload.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ totemconfig: Key change process dependencies
+ When key with dependency was changed, dependant keys were not recomputed.
+ Nice example is consensus timeout. If token timout was changed,
+ consensus timeout was not recomputed correctly (nether via cmap change
+ of key nor via cfg reload).
+
+ Solution is almost complete refactor of handling volatile defaults.
+
+ totem_volatile_config_read now handles not only storing cmap key to
+ totem_config structure, but also checking of existence, comparing with
+ zero value and properly storing defaults.
+
+ totem_set_volatile_defaults is gone. It's function was splitted into
+ totem_volatile_config_read and totem_volatile_config_validate functions.
+
+ Reload callback and change of key callback are now mostly same functions
+ and both calls totem_volatile_config_read.
+
+ Patch also fixes small memory leak. totem.vsftype key is not used for
+ long time and original totem_volatile_config_read wasn't freeing
+ allocated memory returned by icmap_get_string. Whole reading of
+ totem.vsftype is removed.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ Really clear totemconfig nodes on reload
+ When reload was called nodes were constantly added to totemconfig
+ nodelist.
+
+ So simple corosync-cfgtool -R resulted very quickly in filling whole
+ array and segfault.
+
+ Solution is to clear member_count.
+
+ Clearing is also moved directly to put_nodelist_members_to_config to
+ make sure it's always processed.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ Log: Make reload of logging work
+ When reload was called multiple times (~20), logging to file stopped
+ working.
+
+ Main problem was hidden in the fact, that log file was opened multiple
+ times, because even target_id was shared via subsystem loggers, file
+ name was not.
+
+ Solution is to ALWAYS set proper log file name into subsystem logger
+ (copy is stored). This will not only fix problem but also removes small
+ leak.
+
+ Also if filename didn't changed, function can return sooner.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2014-03-17 Jan Friesse <jfriesse@redhat.com>
+
+ config: Handle totem_set_volatile_defaults errors
+ When totem_set_volatile_defaults is called from totem_config_validate
+ return code is unchecked.
+
+ It's then perfectly possible to set (for example) join timeout to very
+ small value (1) and consensus value is then set to 0 making corosync
+ unable to create membership.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2014-02-26 Jan Friesse <jfriesse@redhat.com>
+
+ votequorum: Properly initialize atb and atb_string
+ icmap_get_* behavior is to NOT modify passed variable when it doesn't
+ success. So we must initialize variable before icmap_get_* call.
+
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+2014-02-25 Jan Friesse <jfriesse@redhat.com>
+
+ mon: Make monitoring work
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ mon: Pass correct pointer to inst
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ mon: Fix comparsion typo
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ mon: Make mon compilable with libstatgrab ver 0.9
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2014-02-19 Jan Friesse <jfriesse@redhat.com>
+
+ cpg: Make sure left nodes are really removed
+ When node is paused and other nodes has in meantime exited cpg process,
+ paused node after resume doesn't update it's membership correctly so on
+ previously paused node exited cpg process is still visible.
+
+ Solution is to compare join list with cpd and remove all pids which are
+ not included in join list.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ cpg: Make sure nodid is always logged as hex num
+ Also number is prefixed by 0x so it's easier to spot that number is
+ hexadecimal.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ cpg: Refactor mh_req_exec_cpg_procleave
+ Most of functionality is moved to do_proc_leave function to make it
+ reusable.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2014-02-18 Jan Friesse <jfriesse@redhat.com>
+
+ totemsrp: Fix typo with cont gather
+ Patch f3ffd3da5c71a10e1783a38e50bafc61192854f6 introduced named states
+ of state-machine, but sadly contains logical problem causing
+ stats.continuous_gather increasing even when it shouldn't. Problem is
+ not critical, because continuous_gather is set to 0 on successful
+ membership creation.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2014-02-17 Christine Caulfield <ccaulfie@redhat.com>
+
+ votequorum: Add extended options to auto_tie_breaker
+ This patch adds more flexibility to the auto_tie_breaker feature of
+ votequorum. With this, not only can the lowest nodeid be used as
+ a tie breaker, but also the highest, or a node from a nominated list.
+
+ If there is a list of nodes, the first node in the list that was not
+ part of the previous partition is used. This allows the user to
+ specify a preferred set of nodes but prevents a split-brain if the
+ cluster divides evenly with a node in each half.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2014-01-23 Masatake YAMATO <yamato@redhat.com>
+
+ Free object allocated at quorum_register_callback
+ Memory object allocated with malloc at quorum_register_callback
+ is not freed. The object is linked to internal_trackers_list.
+
+ The object is unlinked at quorum_unregister_callback. However,
+ it is not freed at the function.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2014-01-14 Jan Friesse <jfriesse@redhat.com>
+
+ Properly check result of symlink
+ Error message is displayed when it's impossible to create symlink to
+ fdata file.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ Fix cppchecks warning
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ Close devnull file handler
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2014-01-14 Christine Caulfield <ccaulfie@redhat.com>
+
+ votequorum: Add missing man pages
+ Man pages for votequorum_qdevice_update and votquorum_qdevice_master_wins
+ were missing from the last commit.
+
+2014-01-13 Jason <huzhijiang@gmail.com>
+
+ totem: Drop invalid join msg in operational state
+ According to the totem paper, if a processor
+ receives a join message in the operational state and if the
+ receivers identifier is in the join messages fail list,
+ then join message should be ignored.
+
+ By applying this validation of join messages, we can avoid unnecessary
+ switching from operational state to gather state(or even lead to rings
+ can not be merged) like the following to happen.
+
+ 1. Initially, there is only one ring contains three nodes, say
+ ring(A,B,C).
+ 2. A and B network partition, "in the same time", C is down.
+ 3. Node A sends join message with proclist:A,B,C. faillist:NULL.
+ Node B sends join message with proclist:A,B,C. faillist:NULL.
+ 4. Both A and B consensus timeout due to network partition.
+ 5. A and B network remerged.
+ 6. Node A sends join message with proclist:A,B,C. faillist:B,C. and
+ create ring(A).
+ Node B sends join message with proclist:A,B,C. faillist:A,C. and
+ create ring(B).
+ 7. Say join message with proclist:A,B,C. faillist:A,C which sent
+ by node B is received by node A because network remerged.
+ 8. Node A shifts to gather state and send out a modified join message
+ with proclist:A,B,C. faillist:B. Such join message will prevent
+ both A and B from merging.
+ 9. Node A consensus timeout (caused by waiting node C) and sends join
+ message with proclist:A,B,C. faillist:B,C again.
+
+ Same thing happens on node B, so A and B will dead loop forever
+ in step 7, 8 and 9.
+
+ As the paper also said: "If a processor receives a join message in the
+ operational state and if the sender's identifier is in the receiver's
+ my_proclist and the join message's ring_seq is less than the receiver's
+ ring sequence number, then it ignores the join message too." So these
+ patch applying these validations of join messages altogether.
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2014-01-13 Jan Friesse <jfriesse@redhat.com>
+
+ systemd unit: Make sure network is really up
+ Change network.target to network-online.target to make sure network is
+ really up and running when starting corosync.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2014-01-13 Christine Caulfield <ccaulfie@redhat.com>
+
+ votequorum: Improve/add documentation for quorum device API
+ Improve the man pages for the votequorum qdevice API and include
+ them in the build. Also improve the testvotequorum2 test program.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2014-01-07 Christine Caulfield <ccaulfie@redhat.com>
+
+ votequorum: Add persistent expected_votes tracking.
+ This patch adds the option to store expected_votes to
+ persistent storage. This is needed to allow_downscale
+ to operate properly.
+
+2013-11-26 Jan Friesse <jfriesse@redhat.com>
+
+ cfgtool: return error on reload failure
+ If reload fails, return code is set to value >0 to indicate error.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2013-11-08 Christine Caulfield <ccaulfie@redhat.com>
+
+ man pages: Note that votequorum's allow_downscale is unsupported
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+2013-11-04 Jan Friesse <jfriesse@redhat.com>
+
+ logsys: Make logging of totem work again
+ Because of change in libqb (9abb686) logging of TOTEM subsystem stopped
+ working.
+
+ Instead of rely on previous behavior (implicit substring match), all
+ totem files are now explicitly given.
+
+ Also QB subsystem now uses comma separated filelist instead of previous
+ function calling.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2013-10-24 Masatake YAMATO <yamato@redhat.com>
+
+ totemsrp: Show English message when memb_state_gather_enter is called
+ The reason why memb_state_gather_enter is invoked was printed
+ in integer code. This patch introduces human readable English
+ messages for the code.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2013-09-20 Yevheniy Demchenko <zheka@uvt.cz>
+
+ totemiba: Check if configured MTU is allowed by HW
+ Solution use aproximation of totem structures. This needs to be
+ rewritten in proper way. Also MTU checking should be implemented for IP
+ transports.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ totemiba: Fix parameters position for poll_add
+ Parameters in functions like mcast_cq_send_event_fn, ... were defined in
+ incorrect order. Also their names were weird.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ totemiba: Del channel fd from poll before destroy
+ Corosync freezes after several peer node connects/disconnects. The
+ freeze happens in recv_token_cq_recv_event_fn in ibv_get_cq_event call.
+ The problems is in fact, that after each peer node connect,
+ recv_token_accept_destroy is called, which tries to call
+ poll_dispatch_delete _after_ freeing of completion_channel. As
+ completion_channel contains fd, handlers are not disconnected from
+ poller properly. This leads to complete inconsistency in subsequent
+ calls to handlers.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ totemiba: Properly allocate RDMA buffers
+ 1. In UD mode receivnig side of RDMA application should have enough
+ space in buffer to hold data and GRH. Also, sge.length on the receiving
+ size should be set to max_msg_size + sizeof (struct ibv_grh). Current
+ corosync doesn't take grh in the account and does not work if mtu is set
+ to the real mtu of IB port (it works if netmtu is set to < 2048-40).
+ 2. ibv_wc.byte_len is the actual lentgh of the received packet, i.e.
+ msg_len + GRH. GRH length should be substracted in further proceeding.
+ If not, it might cause problems when messages get retransmitted, as
+ their apparent size will constantly grow.
+ 3. Current corosync will not work with rdma and mtus > 2048. Most modern
+ IB HW supports 4096 mtu.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2013-09-12 Christine Caulfield <ccaulfie@redhat.com>
+
+ Reload: document config.reload_in_progress in man page
+
+ Reload: Add atomic reload to log config
+ When a reload is in progress, wait until it has all finished
+ before re-reading all of the logging parameters
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ Reload: Add atomic reload to totemconfig
+ When a reload is in progress, wait until the whole thing has
+ finished before setting parameters
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ Reload: Add reload code to cfg
+ Add the code to do the actual corosync.conf reload to cfg, along with
+ a corosync-cfgtool -R command to trigger it
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ Reload: Make coroparse use a designated icmap hash table
+ Pass an icmap hashtable into coroparse so we can load it into
+ a temporary one during reload
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2013-09-10 Jan Friesse <jfriesse@redhat.com>
+
+ icmap: Add func to test equality of two key values
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2013-09-10 Christine Caulfield <ccaulfie@redhat.com>
+
+ [PATCH] Replace freopen with open/dup2 when daemonizing
+ This patch replaces the existing freopen method of
+ forcing stdin/out/err to /dev/null with the more
+ usual system of open/dup2.
+
+ While I don't like posting patches I don't fully understand,
+ this patch seems to fix a problem where stdout/err get
+ assigned to a socket causing double logging output
+ on systemd.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2013-09-03 Christine Caulfield <ccaulfie@redhat.com>
+
+ Add log message to exit signal handler
+ I've seen a few instances where corosync has shut down for
+ apparently 'no reason'. In fact most of the time the shutdown
+ has been caused by an external source (often an init script)
+ but it's not been obvious what has happened and people
+ implicate the deamon
+
+ This patch simply adds a log message to the signal handler
+ when it is called so that the cause of the shutdown is obvious.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2013-08-29 Jan Friesse <jfriesse@redhat.com>
+
+ icmap: Add map copy function
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ icmap: Add function to return item data pointer
+ icmap_get_r is now implemented using this function. Function is not very
+ safe tho defined as static.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ icmap: Fix value len checking for strings
+ Implementation should allow pass only parts of string (shorten string)
+ and must prohibit reading of uninitialized memory.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ icmap: Add function to return global icmap
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2013-08-27 Jan Friesse <jfriesse@redhat.com>
+
+ icmap: Allow multiple icmap instances
+ Patch adds reentrant version of most of functions (with exception of RO
+ flags support and tracking) to allow multiple icmap instances existence
+ inside corosync.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2013-08-19 Michael Chapman <mike@very.puzzling.org>
+
+ Fix scheduler pause-detection timeout
+ qb_loop_timer_add expects the timeout to be in nanoseconds, but we were
+ passing the value in milliseconds. Scale the timeout appropriately.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2013-07-10 Jan Friesse <jfriesse@redhat.com>
+
+ Remove dir pragma for xml2conf.xsl in specfile
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+2013-07-09 Jan Friesse <jfriesse@redhat.com>
+
+ cts: Update DC_IDLE pattern
+
+2013-07-08 Kazunori INOUE <inouekazu@intellilink.co.jp>
+
+ Use restart policy in the corosync-notifyd unit
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2013-07-04 David Vossel <dvossel@redhat.com>
+
+ ipc_glue: proper ref counting during service connection iteration
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ ipc_glue: Remove connection unref with no matching reference.
+ We don't reference the connection object on creation, so there
+ is on reason to dereference it on disconnect.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ ipc_glue: Fixes connection ref count leak
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2013-07-01 Kazunori INOUE <inouekazu@intellilink.co.jp>
+
+ systemd: fix typo in unit file
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ notifyd: fix handle dispatch functions results
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2013-06-27 Christine Caulfield <ccaulfie@redhat.com>
+
+ The corosync message "A processor joined or left the membership" is vague and unhelpful. People have to look for the following quorum message and try to deduce which nodes have joined or left from that and past membership messages, even though the routine printing the message already has this information to hand.
+ This patch fixes that message so that it prints the nodeids of the nodes
+ that have joined/left the cluster.
+
+ Signed-Off-By: Christine Caulfield <ccaulfie@redhat.com>
+ Reviewed-By: Jan Friesse <jfriesse@redhat.com>
+
+2013-06-21 Jan Friesse <jfriesse@redhat.com>
+
+ Log: Output parse errors to syslog
+ When corosync was started in daemon mode and there was parse error, no
+ way existed how to find out what happened (this is usual situation with
+ systemd enabled systems). Solution seems to be output to syslog by
+ default.
+
+ Also redundant line with setting logsys is removed because it's no
+ longer needed, because FORK and THREADED mode options has no longer
+ effect. FORK is handled by libqb by default and THREADED mode is forced
+ by calling logsys_thread_start.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ totemconfig: Prevent leak of cluster_name str
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ service: Fix memleak in service_unlink_and_exit
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2013-06-20 Eric Raymond <esr@thyrsus.com>
+
+ Fix patch for corosync.conf.5
+ he markup around an example is impossible to lift to XML or HTML
+ cleanly. Simplifying it fixes the problem.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2013-06-18 Jan Friesse <jfriesse@redhat.com>
+
+ cpg: Set umask in memory_map function
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ ipc_glue: Check service name len
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ ipc_glue: Introduce constant for service name len
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ cfg: Check interface status and name length
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ cfg: Check number of interfaces
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ cfg: Introduce CFG_MAX constants
+ Instead of magic numbers, use constant.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ totemrrp: Make status string shorter
+ Status string should be same lenght as needed for cfg
+ ringstatusget function.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ totem: Don't leak instance variable on crypto fail
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ totemudpu: Handle fd leak in totemudpu
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ totemconfig: Check length of rrp_mode string
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ coroparse: Ensure that config items fits into cmap
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ cpg: Check cpg zc buffer path name length
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+2013-06-17 Jan Friesse <jfriesse@redhat.com>
+
+ votequorum: Prevent leak in qdevice_is_configured
+ Also LEAVE from function is now properly logged.
+
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+2013-06-13 Jan Friesse <jfriesse@redhat.com>
+
+ ipc_cfg: Make coverity happy
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ Initialize error variable in ykd_init
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ Initialize node_found in nodelist_to_interface fun
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ Initialize item in cmap_mcast_send
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ cmapctl: Remove unnecessary access check
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ votequrorum: Assert sender nodeid is known
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ quorumtool: Properly check nodeid cli param
+ Return value of strtol can be negative, but result was assigned to
+ unsigned integer. To make check correct, result is first assigned to
+ signed variable, checked, and then assigned to unsigned variable.
+
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ Handle errors when getting SC_PAGESIZE
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ Check result of logsys_subsys_create
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ Check logsys_format_set result in logsys setup
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ Use proper totem_ip_address size in memset
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ Free icmap strings in logconfig
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ Properly break MAIN_CP_CB_DATA_STATE_QDEVICE state
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ Do not dereference format_buffer when it's NULL
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ Check icmap str get for clustername
+ Even this check is really not needed, it's nice to have it and on fault
+ ensure that cluster_name is really NULL.
+
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ Handle dispatch functions results
+ On error, exit corosync-notifyd properly.
+
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ Properly check result of stat func in coroparse
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ testcpg: Check length of input group name
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ common ta: Close client sockets
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ common ta: Close listener socket
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ test sam: Free temp str allocated by cmap
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ sam test agent: Assert results of send func
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ votequorum test agent: Assert results of send func
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ cpg test agent: Test len of name for cpg_join
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ cpg test agent: Cfg shutdown flag is not bitfield
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ cpg test agent: Assert results of send function
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ cpg test agent: Fix typo in assert
+ Assert should compare rc, instead of setting it.
+
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ Rename make target coverity
+ Makefile target "coverity" is renamed to coverity-aggressive, and target
+ coverity is defined as a little less aggressive.
+
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+2013-05-24 Michael van der Westhuizen <r1mikey@gmail.com>
+
+ Allow corotypes.h to be included from C++ code.
+
+2013-05-21 Jan Friesse <jfriesse@redhat.com>
+
+ Remove unnecessary mmap in cpg
+ Code for zero-copy in cpg does following mmaps:
+ - Mmap anonymous, private memory to some address (-> malloc)
+ - Mmap shared memory of fd to address returned by first mmap
+ (effectively shadows first mapping)
+
+ This is not necessary and only one mapping is needed.
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+2013-04-16 Jan Friesse <jfriesse@redhat.com>
+
+ Install sysconfig/corosync-notifyd in specfile
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ Improve corosync-notifyd example
+ Example now contains default option -d, so corosync-notifyd init script
+ don't fall. Also description is improved a little bit.
+
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+2013-04-12 Masatake YAMATO <yamato@redhat.com>
+
+ Fix a typo in README.recovery
+ Fix a typo.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2013-04-10 Kazunori INOUE <inouekazu@intellilink.co.jp>
+
+ Add Upstart job configuration file
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+2013-04-08 Jan Friesse <jfriesse@redhat.com>
+
+ Detect big scheduling pauses
+ Add poll timer scheduler to be called 3 times per token timeout.
+ If poll timer was not called for more then 0.8 * token timeout, it means
+ corosync process was not scheduled and ether token_timeout should be
+ increased or load should be reduced (useful for VM, where host is
+ overcommitted so VM is not scheduled as expected).
+
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+2013-04-03 Andrei Belov <defanator@gmail.com>
+
+ Added checks for "--as-needed" and "--version-script" linker flags.
+ This makes possible to build Corosync from sources on SunOS 5.11,
+ Mac OS X 10.8.3 and probably other systems with non-GNU linker.
+
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+2013-04-02 Jan Friesse <jfriesse@redhat.com>
+
+ Support for numerical uid/gid
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+2013-04-02 Yuichi SEINO <seino.cluster2@gmail.com>
+
+ build: pass enable options to "make rpm" from configure
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+2013-03-28 Andrei Belov <defanator@gmail.com>
+
+ Improved POSIX-compliant handling of getpwnam_r() and getgrnam_r().
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2013-03-27 Jan Friesse <jfriesse@redhat.com>
+
+ Make cts work with pacemaker 1.1.9
+ This is counterpart of adcc21a30c70a40861736bc9d902c2ef2d4b42c4 in
+ pacemaker.
+
+2013-03-21 Jan Friesse <jfriesse@redhat.com>
+
+ totempg: Make iov_delv local variable
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ cfgtool: Retry shutdown on CS_ERR_TRY_AGAIN
+ It may be nice to deliver macro cs_repeat as default in some include
+ file.
+
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+2013-03-20 Jan Friesse <jfriesse@redhat.com>
+
+ cts: Output nodeid consistently as unsigned int
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+2013-03-19 Xia Li <xli@suse.com>
+
+ Convert the nodeid byte order to be aligned with network order
+ When using corosync with clear_node_high_bit setting to yes,
+ the highest bit is cleared. When all the cluster nodes are in
+ one subnet, we probably configure the IP addresses as follows:
+
+ node1: 147.2.207.64
+ node2: 147.2.207.192
+
+ If the byte order of the nodeid is little endian, wiping off the
+ highest bit will make the two nodes have the same nodeid!
+
+ This patch fixes this by converting the nodeid to network order.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2013-03-08 Jeremy Fitzhardinge <jeremy@goop.org>
+
+ Handle ERANGE from getpwnam_r / getgrnam_r
+ These functions return ERANGE if the supplied buffer is too small to
+ fit a line. Try doubling the buffer a few times until it works.
+
+2013-02-26 Michael Chapman <mike@very.puzzling.org>
+
+ build: make --disable-testagents work
+ The --disable-testagents option sets enable_testagents to "no". This
+ variable should always be explicitly tested against "yes", not just
+ that it is non-empty.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2013-01-31 Jan Friesse <jfriesse@redhat.com>
+
+ Handle unexpected closing brace in config file
+ If configuration file contains closing brace before opening brace
+ at top level, configuration parsing is stopped and file is not
+ completely parsed. Solution is to detect extra closing brace and display
+ error.
+
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ Handle colon in configuration file
+ If colon was entered as part of value on end of value, it is deleted.
+ This makes impossible to enter (legal) IPv6 address ending with :: (like
+ fed0::).
+
+ Also when line contains both brace and colon, it is parsed twice (first
+ as key = value and second as start of section). This is handled by
+ continue in if section.
+
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+2013-01-31 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ votequorum: port to sync API (take 2)
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2013-01-14 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ crypto config: update man pages and examples
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ totemconfig: enforce hmac config when crypto is enabled
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2013-01-14 Kazunori INOUE <inouekazu@intellilink.co.jp>
+
+ log: move Corosync started log messages
+ "Corosync Cluster Engine ... started" message is shown after
+ logsys is full configured.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2013-01-14 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ crypto: drop < 2.3 protocols and onwire compat
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ totemcrypto: fix hmac key initialization
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2012-12-12 Jan Friesse <jfriesse@redhat.com>
+
+ Move qb_loop creation after daemonization
+ Creating qb_loop before daemonization is not problem for poll or epoll
+ type loops, but it's problem for kqueue, because kqueue is not shared
+ in child with parent after fork.
+
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+2012-12-06 Jan Friesse <jfriesse@redhat.com>
+
+ cmap: Handle NULL params in few more functions
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+2012-12-03 Jan Friesse <jfriesse@redhat.com>
+
+ Add option to specify ip version
+ Default is ipv4.
+
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+2012-11-22 Jan Friesse <jfriesse@redhat.com>
+
+ Add waiting_trans_ack also to fragmentation layer
+ Patch for support waiting_trans_ack may fail if there is synchronization
+ happening between delivery of fragmented message. In such situation,
+ fragmentation layer is waiting for message with correct number, but it
+ will never arrive.
+
+ Solution is to handle (callback) change of waiting_trans_ack and use
+ different queue.
+
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ Handle segfault in backlog_get
+ If instance->memb_state is not OPERATION or RECOVERY, we was passing NULL
+ to cs_queue_used call.
+
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+2012-11-22 Steven Dake <sdake@redhat.com>
+
+ Fix problem with sync operations under very rare circumstances
+ This patch creates a special message queue for synchronization messages.
+ This prevents a situation in which messages are queued in the
+ new_message_queue but have not yet been originated from corrupting the
+ synchronization process.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+2012-11-22 Jan Friesse <jfriesse@redhat.com>
+
+ Fix handling of NULL parameters in cmap
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+2012-11-22 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ totemcrypto: implement crypto packet format 2.2 and crypto_compat: config opt
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ Update .gitignore files
+ Untracked files:
+ (use "git add <file>..." to include in what will be committed)
+
+ compile
+ init/corosync
+ init/corosync-notifyd
+ test/ploadstart
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2012-11-21 Evgeny Barskiy <barskiy@rts.ru>
+
+ corosync to start in infiniband + redundant ring active/passive mode
+ Corosync now works with infiniband transport in any redundant ring mode
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2012-11-20 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ votequorum: fix handling of expected_votes/votes changes from cmapctl
+ and allow natural selection to take place....
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ quorum-tool: use option to generate machine parsable output
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2012-11-08 Jan Friesse <jfriesse@redhat.com>
+
+ Add support for selecting IPC type
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ Check successful initialization of IPC
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+2012-11-07 Jan Friesse <jfriesse@redhat.com>
+
+ Enahnce manpages a little bit
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+2012-11-07 Angus Salkeld <asalkeld@redhat.com>
+
+ Try reduce the number of sprintf's
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ Override the link_all_deplibs=no in ubuntu
+ but allow the user to disable this.
+
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+2012-11-06 Jan Friesse <jfriesse@gmail.com>
+
+ Merge pull request #2 from dfcluster/master
+ Update corosync man page
+
+2012-11-05 Jan Friesse <jfriesse@redhat.com>
+
+ If failed_to_recv is set, consensus can be empty
+ If failed_to_recv is set (node detect itself not able to receive
+ message), we can end up with assert, because my_failed_list and
+ my_member_list are same list. This is happening because we are not
+ following specification and we allow to mark node itself as failed.
+ Because if failed_to_recv is set and we reached consensus across nodes,
+ single node membership is created (ignoring both fail list and
+ member_list), we can skip assert.
+
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+2012-11-05 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ quorumtool: add local nodeid to global quorum info section
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ quorumtool: add (local) next to the nodename when displaying node data
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ quorumtool: change default command from -h to -s
+ default run will show status instead of help text
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2012-10-30 dfcluster <df.cluster@gmail.com>
+
+ Update man/corosync.conf.5
+
+2012-10-29 Jacek Konieczny <jajcus@jajcus.net>
+
+ link libtotem_pg to libqb
+ The libtotem_pg library uses symbols from libqb, so it should be
+ explicitely linked with it. This doesn't cause problems for corosync
+ binary itself, as it is linked to both libraries, but can cause
+ problems if anything else links to libtotem_pg.so and automated
+ checkers can show this as a library problem.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ Fix dbus configuration install
+ The corosync-signals.conf DBus configuration file was not
+ installed even if DBus support was enabled because of a configure
+ test error.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2012-10-17 Jan Friesse <jfriesse@redhat.com>
+
+ Correctly check if service was unloaded
+ my_processing_idx is pointer to received service list, instead of global
+ service number. If we check state of service we should use service_id
+ instead of my_processing_idx.
+
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ Define AES_*_KEY_LENGTH if not defined
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+2012-10-16 Andreas Gruninger <Andreas.Grueninger@lgl.bwl.de>
+
+ Missing space in man/Makefile.am
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2012-10-15 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ totemcrypto: add support for different encryption methods
+ (backport from nsscrypto kronosnet code)
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2012-10-11 Jan Friesse <jfriesse@redhat.com>
+
+ Change specfile URL and Source
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ Document config_version option
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+2012-10-10 Jan Friesse <jfriesse@redhat.com>
+
+ Use systemd-rpm macros in specfile
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+2012-10-09 Jan Friesse <jfriesse@redhat.com>
+
+ Enhance spec file
+ Weird construct buildtrunk is gone. Instead of that, we use bcond
+ feature. Also buildtrunk is renamed to runautogen, because SVN era is
+ gone.
+
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+2012-10-08 Jan Friesse <jfriesse@redhat.com>
+
+ Make totemiba compile again
+
+ Return back "Totem is unable to form..." message
+ This patch returns back SUBJ functionality. It rely on fact, that
+ sendmsg will return error, and if such error is returned for long time,
+ it's probably because of firewall.
+
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ Move "Totem is unable to form..." message to main
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ Use unix socket for local multicast loop
+ Instead of rely on multicast loop functionality of kernel, we now use
+ unix socket created by socketpair to deliver multicast messages to
+ local node. This handles problems with improperly configured local
+ firewall. So if output/input to/from ethernet interface is blocked, node
+ is still able to create single node membership.
+
+ Dark side of the patch is fact, that membership is always created, so
+ "Totem is unable to form a cluster..." will never appear (same applies
+ to continuous_gather key).
+
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+2012-10-04 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ man page: fix quorum references
+
+2012-10-03 Jan Friesse <jfriesse@redhat.com>
+
+ Store config_version of other nodes
+ Config version of other nodes is stored in
+ runtime.totem.pg.mrp.srp.members.NODEID.config_version key. Also when
+ local config_version is changed, all nodes are informed.
+
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+2012-10-02 Jan Friesse <jfriesse@redhat.com>
+
+ Support for check of config version on start
+ Config version is requested from other nodes. If our config version is
+ not 0 and differes from highest config version of other nodes, corosync
+ quits.
+
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ Make cmap_mcast_send return correct error code
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ Make service_build contain correct number of msgs
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ Align items in cmap_mcast_send
+ Aligning function (kernel style magic) MAR_ALIGN_UP is used for
+ aligning of items in req_exec_cmap_mcast message.
+
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ Support for flt and dbl in mcast_endian_convert
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ Add support for swab float and double
+ This uses general swabbin function which is able to swab every byte in
+ array.
+
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ Add support for sending cmap values to wire
+ Function is little more complex, but it is designed to be used in future
+ without big changes.
+
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ Parse config_version as 64-bit uint
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+2012-09-27 Jan Friesse <jfriesse@redhat.com>
+
+ Don't access invalid mem in totemconfig interfaces
+ When ringnumber in config file was set to value bigger or equal to
+ INTERFACE_MAX, we are using this big value as index to totemconfig
+ interfaces array, resulting to access to invalid memory and segfault.
+
+ Instead of that, ringnumber is now checked and proper error message is
+ printed if value is too big.
+
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+2012-09-19 Jan Friesse <jfriesse@redhat.com>
+
+ Move some totem and cpg messages to trace level
+ Messages which are flow messages, rather then lifecycle are now logged
+ in trace level.
+
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ Add support for debug level trace in config file
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+2012-09-12 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ icmap: fix mapping return codes
+ Reviewed-by: Angus Salkeld <asalkeld@redhat.com>
+
+2012-09-11 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ build: fix indirect linking vs rpath by linking --as-needed
+ libtotem_pg links against libnss/nspr and correctly sets RPATH
+ corosync links against libtotem_pg, but libtool (via .la) enforces
+ an extra layer of linking against libnss/nspr without setting RPATH.
+
+ corosync final binary can't resolve the second linking and fails
+ to load.
+
+ This issue is visible only on NetBSD that enforces a much stricter
+ use of rpath (vs other OS/distros). Using --as-needed avoids that
+ and it's generally safe to use on other OS'es.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2012-09-10 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ build: make secure build optional
+ apparently some versions of gcc accepts the pie/relro bits
+ but fails to produce a working binary (freebsd9)
+
+ Reviewed-by: Angus Salkeld <asalkeld@redhat.com>
+
+ build: fix regression with handling fPIC and DPIC
+ Reviewed-by: Angus Salkeld <asalkeld@redhat.com>
+
+2012-09-07 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ build: add support for relro and bindnow
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ build: autodetect if compiler support -fPIE and -pie for linking
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ build: clean AM_CFLAGS and AM_CPPFLAGS usage around
+ also set commont include dirs.
+
+ fPIC and DPIC are automatically detected and added
+ as required by libtool. We don't need to carry it around.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ totemconfig: drop unnecessary includes
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2012-09-06 Jan Friesse <jfriesse@redhat.com>
+
+ Remove newline in logsys_config_file_set_unlocked
+ Also remove commented leftover.
+
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ Make threaded log work
+ Previous two log releated patches tried to solve few problems with
+ threaded libqb, but introduced regressions when running in daemon mode.
+
+ This patch takes bigger hammer and hopefully solves all problems.
+
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+2012-09-05 Jan Friesse <jfriesse@redhat.com>
+
+ Ensure qb_log thread is started
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+2012-09-03 Jan Friesse <jfriesse@redhat.com>
+
+ Ensure no garbage left in msghdr for sendmsg call
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ Use uint8_t in setsockopt when needed
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ OpenBSD getifaddrs returns netmask without sa_family
+ So we relax netmask check and set to same family as ipaddr
+ if needed
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ Add header files when needed
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ Make use of EBADMSG conditional
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+2012-08-31 Angus Salkeld <asalkeld@redhat.com>
+
+ Fix cpg_membership_get()
+ The wrong size was getting set in exec/cpg.c
+
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+2012-08-30 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ build: drop OS detection
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ build: bring SOLARIS up to the same standard as other OSes
+ drop all SOLARIS specific ifdefs and replace them with feature checks
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ build: drop TS_CLASS definition, used nowhere
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ build: drop COROSYNC_BSD out of configure
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ totemip: clean up headers a lot more
+ getifaddrs is always available if there is freeifaddr.
+
+ all BSD and openindiana have it defined in ifaddr.h.
+
+ drop a bunch of obsoleted headers.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ build: drop MAP_ANONYMOUS check from configure
+ define it only in case it's not there
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ build: drop COROSYNC_DARWIN definition
+ not referenced anywhere in the code
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ build: drop completely linux detection
+ from now on there are no unsupported OS'es...
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ build: make libstatgrab the facto default for monitoring service
+ drop duplicate code and remove the last COROSYNC_LINUX ifdefs
+ around
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ totemip: add missing include
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ build: use MADV_NOSYNC only when it's defined
+ so far only FreeBSD defines it.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ build: make exec/totemip os detection free
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ build: drop _SEM_SEMUN_UNDEFINED
+ not referenced anywhere in the code
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2012-08-30 Jan Friesse <jfriesse@redhat.com>
+
+ Log: Use threaded mode for syslog and file log
+ Syslog and file log can block, so it's good idea to use libqb threaded
+ mode to prevent it.
+
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ Use native IPC mechanism
+ Instead of hardcoded SHM, we should use NATIVE, so libqb is able to find
+ out what is best/availiable mechanism.
+
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ Add la, lo and .libs files/directory to gitignore
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+2012-08-30 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ build: fix library version export in ELF header
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2012-08-29 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ build: fix spec file creation
+ hopefully once and for all...
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ spec: cleanup spec file to be slightly smarter
+ move all the conditionals in 2 variables to make it easier to read
+ and maintain and fix install of dbus-signal file
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ build: fix do_snmp conditionals
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2012-08-28 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ build: fix make rpm
+ remove .la files from binary rpm
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ build: cleanup configure.ac for non-linux OS'es
+ libstatgrab ships with pkg-config file. Use it.
+
+ watchdog is implemented only on linux. Error out if necessary.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ build: drop PATH_MAX definition from dark ages
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ build: drop redefine of NAME_MAX since nothing references it anylonger
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ build: drop last reference to OS_CPPFLAGS and use AC EXTENSIONS instead
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ build: fix build on openindiana 151a
+ openindiana toolchain is rather messy. This is the first cut only
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ build: remove bashism in cc support check
+ this is required for all systems that don't use bash for /bin/sh
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ build: drop SOLARIS_OPTS and DARWIN_OPTS
+ SOLARIS was unused
+
+ DARWIN needs verification
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ build: minor cleanup and final removal of OS_LDFLAGS
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ build: rework snmp library detection and setting of CFLAGS
+ this allows to drop more OS_* specific bits
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ build: drop more dlopen leftovers from dinosaur era...
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ build: make monitoring optional in corosync exec
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ build: update .gitignore files
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ build: fix make distcheck
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ build: make path to bash configurable at build time
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ build: order library install to make sure libsam can relink against libcmap
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ build: fix usage of sed and drop build-aux/genman
+ "sed -i" is a GNU specific extention.
+
+ Replace with more portable version and drop completely genman
+ in favour of a make rule.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ test: fix testcpg build on FreeBSD9
+ HOST_NAME_MAX is intentionally NOT defined on BSD.
+
+ Users of HOST_NAME_MAX should be using sysconf or use very
+ conservative values.
+
+ limits.h still defines _POSIX_HOST_NAME_MAX. use that instead.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ build: respect watchdog conditional when building corosync exec
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ common_lib: make it build on FreeBSD 9 and Mac OS X
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ build: use libtool for linking
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ build: cleanup configure.ac
+ sort different sections in more logical way and add check for sed
+ plus a few missing headers/functions
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2012-08-21 Tim Beale <tim.beale@alliedtelesis.co.nz>
+
+ Remove redundant default-config code
+ We were checking 'hold_timeout == 0' in 3 different places when setting up
+ the default totem config.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2012-08-21 Tim Beale <tlbeale@gmail.com>
+
+ Remove unused structure
+ Nowhere in the corosync codebase references this structure.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ man: corosync.conf seqno_unchanged_const description incorrect
+ seqno_unchanged_const is used to determine when the rep should hold the
+ token. The merge detection timeout is started after any idle rotation of
+ the token.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2012-08-16 Jan Friesse <jfriesse@redhat.com>
+
+ Make logging of WD and MON service correct
+ MON and WD services are using fsm.h, which calls log function. Such
+ messages were incorrectly logged as SERV (or random service) which made
+ debugging hard.
+
+ Solution is to add callback parameter to fsm functions and do actual
+ logging there.
+
+ Handling of failure states is also done in calback now.
+
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ Fix dbus part of corosync-notifyd
+ Function dbus_connection_read_write which causes block for 0.5 sec is
+ replaced by correct dispatching of input and flushing of output buffer.
+
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+2012-08-14 Jan Friesse <jfriesse@redhat.com>
+
+ example conf: Remove Duplicate "debug" statement
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+2012-08-14 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ build: fix libsam dependencies when using make -j
+ tested on linux (can't verify solaris)
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2012-08-13 Jan Pokorny <jpokorny@redhat.com>
+
+ Example config files: fix a typo
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2012-08-09 Jan Friesse <jfriesse@redhat.com>
+
+ IPC: Call lib function only when it's possible
+ send_ok was incorrectly tested as boolean, even it's errno type
+ variable.
+
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ Close sockets after deleting from poll
+ This will remove (non critical) debug message from QB about polling on
+ closed FD.
+
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ cpg: Check input param name_t length
+ IPC is using buffer of CS_MAX_NAME_LENGTH for name. If user calls
+ function with longer string, such string can be passed to service
+ incomplete.
+
+ Solution is to not allow string larger then CS_MAX_NAME_LENGTH
+ and return error.
+
+ Same applies to cpg service.
+
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ Handle sync and service unload correctly
+ When sync started and service is unloaded in meantime, it can happen that
+ sync will call sync_* functions on unloaded service.
+
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ service: remove leftovers from mt corosync
+ Multithreaded corosync used to use many ugly workarounds. One of them is
+ shutdown process, where we had to solve problem with two locks. This was
+ solved by scheduling jobs between service exit_fn call and actual
+ service unload. Sadly this can cause to receive message from other node
+ in that meantime causing corosync to segfault on exit.
+
+ Because corosync is now single threaded, we don't need such hacks any
+ longer.
+
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ cmap: Check input param name_t length
+ IPC is using buffer of CS_MAX_NAME_LENGTH for name. If user calls
+ function with longer string, such string can be passed to service
+ incomplete.
+
+ Solution is to not allow string larger then CS_MAX_NAME_LENGTH (what is
+ same as ICMAP_KEYNAME_MAXLEN) and return error.
+
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+2012-08-09 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ quorumtool: fix display when nodenames or reverse lookup is missing
+ when requesting nodename in ring0_addr, and reverse dns lookup
+ is not available, quorumtool output becomes inconsistent.
+
+ quorum {
+ provider: corosync_votequorum
+ }
+
+ nodelist {
+ node {
+ ring0_addr: fedora-master-node1
+ nodeid: 1
+ }
+ node {
+ ring0_addr: fedora-master-node2
+ nodeid: 2
+ }
+ }
+
+ [fabbione@daikengo corosync]$ nslookup fedora-master-node1
+ ..
+ Address: 192.168.2.193
+
+ [fabbione@daikengo corosync]$ nslookup 192.168.2.193
+ ..
+ ** server can't find 193.2.168.192.in-addr.arpa.: NXDOMAIN
+
+ [root@fedora-master-node1 tools]# corosync-quorumtool -s
+ ...
+
+ Membership information
+ ----------------------
+ Nodeid Votes Qdevice Name
+ 1 1 NR fedora-master-node1.int.fabbione.net
+ 2 1 NR 192.168.2.194
+
+ (similar on the other node)
+
+ With this patch, when nodelist is available, we simply return ring0_addr
+ name for a node, fixing the output to be:
+
+ Membership information
+ ----------------------
+ Nodeid Votes Qdevice Name
+ 1 1 NR fedora-master-node1
+ 2 1 NR fedora-master-node2
+
+ that also removes possible inconsistencies between nodename, FQDN
+ and so on, by using what user requested in corosync.conf
+
+ In case ring0_addr is not available or numeric output is requested,
+ behavior remains as before.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2012-08-08 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ votequorum: change init/clean up to deal with exit races
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2012-08-07 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ quorumtool: make output more meaningful
+ there is really no point to have a per node view of (vote)quorum
+ since all the info are always there.
+
+ drop the -n option for status/display nodes and improve
+ the output to provide a full cluster view at any given time.
+
+ Old format:
+
+ [root@fedora-master-node2 ~]# corosync-quorumtool -s
+ Quorum information
+ ------------------
+ Date: Mon Aug 6 10:22:27 2012
+ Quorum provider: corosync_votequorum
+ Nodes: 2
+ Ring ID: 8
+ Quorate: Yes
+
+ Votequorum information
+ ----------------------
+ Node ID: 3254954176
+ Node state: Member
+ Node votes: 1
+ Qdevice votes: 1
+ Expected votes: 3
+ Highest expected: 3
+ Total votes: 3
+ Quorum: 2
+ Flags: Quorate Qdevice
+
+ Membership information
+ ----------------------
+ Nodeid Votes Name
+ 3238176960 1 fedora-master-node1.int.fabbione.net
+ 3254954176 1 fedora-master-node2.int.fabbione.net
+ 0 1 QDEVICE (Alive/Voting/NoMasterWins)
+
+ New format:
+
+ [root@fedora-master-node1 tools]# ./corosync-quorumtool -s
+ Quorum information
+ ------------------
+ Date: Mon Aug 6 15:50:03 2012
+ Quorum provider: corosync_votequorum
+ Nodes: 2
+ Ring ID: 48
+ Quorate: Yes
+
+ Votequorum information
+ ----------------------
+ Expected votes: 3
+ Highest expected: 3
+ Total votes: 3
+ Quorum: 2
+ Flags: Quorate Qdevice
+
+ Membership information
+ ----------------------
+ Nodeid Votes Qdevice Name
+ 3238176960 1 A,V,MW fedora-master-node1.int.fabbione.net
+ 3254954176 1 NR fedora-master-node2.int.fabbione.net
+ 0 1 QDEVICE
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ votequorum: make the last QDEVICE define name consistent with everything else
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ votequorum: bump soname
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ votequorum: display qdevice votes
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ votequorum: add missing return call
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ votequorum: make master_wins check stricter
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ votequorum: add ENTER/LEAVE for consistency
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ votequorum: fix library checks on qdevice name and readd qdevice_update
+ for some odd reasons qdevice_update was just gone.. totally...
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ votequorum: delegate qdevice_master_wins setting to qdevice
+ votequorum has no business to device if master_wins setting is correct or not.
+ only the qdevice can decide and should set the value for votequorum.
+
+ Logic is:
+
+ - user requests master_wins from config
+ - corosync starts
+ - qdevice starts
+ - qdevice reads cmap values / register with votequorum
+ - qdevice decides if the node can support master_wins or not and tells votequorum
+ - at this point votequorum can check if an unquorate node is part of the master_wins
+ partition
+
+ it is the qdevice responsibility to keep that value up to date in votequorum and the
+ value can be changed at runtime.
+
+ this commit also exchange per node master_wins information to lay down the infrastructure
+ to verify discrepancies in node config for master_wins (coming next on this channel).
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ votequorum: drop votequorum_qdevice_getinfo and collapse data into getinfo
+ it's really pointless to have basically a duplicated API call
+ to transfer one value and one name.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ votequorum: external defines should all be prefixed with VOTEQUORUM_
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ votequorum: drop _FLAG_ from defines
+ those are all info flags.. it's redudant and inconsistent
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ votequorum: fix define name to match reality
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ qdevice: implement master_wins partition
+ in previous incarnation of qdisk + cman, master_wins was restricted
+ to 2 node only.
+
+ In this new version it is possible to use master_wins for any cluster
+ size.
+
+ Let's assume a 4 node cluster. Each node votes 1, qdevice votes 3.
+
+ node 1 becomes qdevice master
+ node 2/3/4 no
+
+ In case of a split (let's assume 2/2):
+
+ partition 1: {4, 1}
+ partition 2: {1, 1}
+
+ node 2 in partition 1 would normally be unquorate, leaving effectively
+ only node 1 active.
+
+ master_wins allows node 2 to recognize to be part of a quorate partition
+ (since node1 is broadcasting that qdevice is voting) and retain
+ quorum.
+
+ node1 has never lost quorate status since qdevice is voting there.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ votequorum: fix flag check for qdevice votes propagation
+ and cleanup similar code to make it more readable
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ votequorum: remove last instance of state and rename it to cast_vote
+ also align naming of vote to cast_vote for info calls
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ votequorum: several major bug fixes and code cleanup
+ - add a protection check to avoid spurious messages on membership
+ change
+ - greately simplify processing of nodeinfo, since the only
+ data that we send for qdevice over nodeinfo is the number of votes
+ - fix a flag check to trigger quorum calculation that would
+ leave a cluster unquorate under certain conditions
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ votequorum: move to the new flag structure
+ simplify different code path as checks are simpler, separate
+ ALIVE and CAST_VOTE
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ votequorum: simplify getinfo data and protect against call against quorum node
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ votequorum: use REGISTERED flag consistently
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ votequorum: simply internal qdevice_getinfo function
+ as data are moving around we can drop lots of special cases
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ votequorum: add qdevice CAST_VOTE status/flag
+ this is a preparation commit for the next changes. right now it is
+ no more than an alias to ALIVE.
+
+ CAST_VOTE is required to support master/slave feature from qdevice.
+
+ Effectively a quorum device can be:
+
+ Not registered / registered (connected to API but nothing else is happening)
+
+ if registered:
+
+ Not alive / alive (quorum device is petting the API via poll and timer is running)
+
+ if alive:
+
+ Not voting (slave) / voting (master)
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ votequorum: rename NODE_FLAGS_QDEVICE_STATE to NODE_FLAGS_QDEVICE_ALIVE
+ STATE is confusing and overloaded term in votequorum as it's used for nodes
+ and other bits.
+
+ make the name unique and ALIVE means that the qdevice is heartbeating
+ to votequorum.
+
+ improve display of the status in tools and tests.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ votequorum: rename NODE_FLAGS_QDEVICE to NODE_FLAGS_QDEVICE_REGISTERED
+ make the flag name explicit
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ votequorum: re-enable qdevice api
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ quorum devices: add support to build system
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2012-08-04 Steven Dake <sdake@redhat.com>
+
+ Add groff as a BuildRequires to spec file
+ According to Fedora packaging guidelines, groff is not on the list
+ of package exceptions for BuildRequires. A recent change in the Fedora
+ build system has triggered breakage in building rpm packages and it
+ is likely this package won't build for Fedora 18.
+
+ Reference:
+ http://fedoraproject.org/wiki/Packaging:Guidelines#Exceptions_2
+
+ Reviewed-by: Fabio Di Nitto <fdinitto@redhat.com>
+
+2012-08-02 Jan Friesse <jfriesse@redhat.com>
+
+ Don't call sync_* funcs for unloaded services
+ When service is unloaded, sync shouldn't call sync_init|process|activate
+ and abort functions. It happens very rare, but in process of unloading
+ all services, totem can recreate membership and bad things can happen
+ (service is unloaded, so there may be access to already freed memory,
+ ...)
+
+ Solution is to fetch services sync handlers in every time when we are
+ building service list instead of using precreated one.
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ Introduce SERVICES_COUNT_MAX macro
+ Sync/service was using maximal number of services in ehter numberic form
+ (magic constant) or inconsistently, this means using
+ SERVICE_HANDLER_MAXIMUM_COUNT which means maximal number of handlers.
+
+ New macro solves this.
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+2012-07-30 Jan Friesse <jfriesse@redhat.com>
+
+ cmap_keys: Document few more runtime statistics
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ cts: Delete shm blacbox after corosync kill
+ This makes SHM Audit pass in test CpgCfgChgOnExecCrash.
+
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ cpg: Be more verbose for procjoin message
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+2012-07-12 Jan Friesse <jfriesse@redhat.com>
+
+ cts: Change DC_IDLE pattern
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ cts: Make shm_leak_audit run
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ Correctly free state string in wd
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ cts: Change local_start[ing|ed] pattern in CTS
+ Previous pattern is no longer send to syslog. Use first pattern which
+ is.
+
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ Support for crypto_ and nodelist in lenses
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+2012-07-11 Jan Friesse <jfriesse@redhat.com>
+
+ Revert "Free state variable allocated in wd_resource_state_is_ok"
+ This reverts commit 01c63ca17ca5b5a780cff0dd96d7d432b3e980a3.
+
+2012-06-14 Jan Friesse <jfriesse@redhat.com>
+
+ cpg: Enhance downlist selection algorithm
+ Let's say we have 2 nodes:
+ - node 2 is paused
+ - node 1 create membership (one node)
+ - node 2 is unpaused
+
+ Result is that node 1 downlist is selected, so it means that from node 2
+ point of view, node 1 was never down.
+
+ Patch solves situation by adding additional check for largest previous
+ membership.
+
+ So current tests are:
+ 1) largest (previous #nodes - #nodes know to have left)
+ 2) (then) largest previous membership
+ 3) (and last as a tie-breaker) node with smallest nodeid
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ cpg: Print cpg name to debug informations
+ In downlist and joinlist debug output group was printed in nonsense
+ format of integer to pointer to array.
+
+ Now it's printed by full name.
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ cpg: Process join list after downlists
+ let's say following situation will happen:
+ - we have 3 nodes
+ - on wire messages looks like D1,J1,D2,J2,D3,J3 (D is downlist, J is
+ joinlist)
+ - let's say, D1 and D3 contains node 2
+ - it means that J2 is applied, but right after that, D1 (or D3) is
+ applied what means, node 2 is again considered down
+
+ It's solved by collecting joinlists and apply them after downlist, so
+ order is:
+ - apply best matching downlist
+ - apply all joinlists
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ cpg: Never choose downlist with localnode
+ Test scenario is follows:
+ - node 1, node 2
+ - node 1 is paused
+ - node 2 sees node 1 dead
+ - node 1 unpaused
+ - node 1 and 2 both choose same dowlist message which includes node 2 ->
+ node 2 is efectivelly disconnected
+
+ Patch includes additional test if left_node is localnode. If so, such
+ downlist is ignored.
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+2012-06-11 Jerome FLESCH <jerome.flesch@netasq.com>
+
+ When flushing, discard only memb_join messages
+ Patch solves problem when 1 ring out of 2 went up/down quite often.
+
+ The simplest setup to reproduce bug is following:
+ - 2 VMs, connected by 2 network interfaces
+ - OS: Linux
+ - On one of the VMs, a test program sending some CPG messages (see the
+ script "test_corosync.sh" joined to this mail for example)
+
+ Here are the Corosync logs we get when we do this setup:
+
+ Jun 06 16:23:40 corosync [TOTEM ] A processor joined or left the
+ membership and a new membership was formed.
+ Jun 06 16:23:40 corosync [CPG ] chosen downlist: sender r(0)
+ ip(192.168.56.104) r(1) ip(192.168.57.104) ; members(old:1 left:0)
+ Jun 06 16:23:40 corosync [MAIN ] Completed service synchronization,
+ ready to provide service.
+ Jun 06 16:24:37 corosync [TOTEM ] Marking ringid 1 interface
+ 192.168.57.105 FAULTY
+ Jun 06 16:24:38 corosync [TOTEM ] Automatically recovered ring 1
+ Jun 06 16:25:33 corosync [TOTEM ] Marking ringid 1 interface
+ 192.168.57.105 FAULTY
+ Jun 06 16:25:34 corosync [TOTEM ] Automatically recovered ring 1
+ Jun 06 16:26:35 corosync [TOTEM ] Marking ringid 1 interface
+ 192.168.57.105 FAULTY
+ Jun 06 16:26:36 corosync [TOTEM ] Automatically recovered ring 1
+ (...)
+
+ The second ring goes down about every 2 minutes and automatically back
+ up right after.
+
+ We spent some times looking for the commit that introduced this bug, and
+ it appears it's due the following one:
+ Corosync 1.3.3 -> 1.3.4: e27a58d93d0d3795beb550f87b660c9c04f11386
+ Corosync 1.4.1 -> 1.4.2: be608c050247e5f9c8266b8a0f9803cc0a3dc881
+ Commit message: Ignore memb_join messages during flush operations
+
+ I had a look at this commit, and it seems to me it's dropping too many
+ packets:
+ Because of this commit, while totemrrp_recv_flush() is called, Corosync
+ drops memb_join packets, but also ORF tokens. In the end, it seems that
+ sometimes, we drop so many of them that Corosync marks the ring as
+ faulty.
+
+ To fix that, only memb_join messages are dropped now.
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2012-06-05 Jan Friesse <jfriesse@redhat.com>
+
+ Store fdata with timestamp and pid in name
+ This should allow easier handling of various blackbox dumps. Original
+ fdata name is now symlink to latest created dump.
+
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ Remove corosync-fplay
+ Libqb now ships with qb-blackbox command doing same job as
+ corosync-fplay. It doesn't make sense to maintain two versions of same
+ utility so corosync-fplay can go. corosync-blackbox command now calls
+ directly qb-blackbox.
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+2012-06-01 Kazunori INOUE <inouekazu@intellilink.co.jp>
+
+ notifyd: handle addition of a members key to CMAP
+ When new key (totem.pg.mrp.srp.members) was added to CMAP,
+ we would like to receive the trap of this time.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2012-06-01 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ testcpg: fix build warning
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2012-05-31 Jan Friesse <jfriesse@redhat.com>
+
+ totemudpu: Bind sending sockets to bindto address
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+2012-05-29 Jan Friesse <jfriesse@redhat.com>
+
+ snmp MIB: Remove unnecessary comma
+ Thank Hideo Yamauch for pointing this bug.
+
+2012-05-29 Kazunori INOUE <inouekazu@intellilink.co.jp>
+
+ notifyd snmp: fix a function name
+ This fixes the bug to which snmp trap of rrp_faulty_event is not sent.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2012-05-29 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ rename mainconfig to logconfig
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ mainconfig: allow mainconfig logic to be used both internally and externally
+ corosync logging configuration logic is rather complex and in order
+ to make it simpler to reuse (at least within corosync/ tree)
+ we need to be able to use both icmap and cmap.
+
+ the patch might seem controversial, but it reduces heaps of code around
+ from qdevices (coming next).
+
+ It might be useful to consider moving this to a common shared library
+ but there aren't enough users yet and a shared lib would force
+ corosync to link with cmap (that we do not want at all costs)
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+2012-05-29 Angus Salkeld <asalkeld@redhat.com>
+
+ LOG: make sure the log target is enabled.
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ LOG: handle closing unused logfiles better
+ This fixes a bug where having a second log file will close
+ the previous one.
+
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ LOG: be more explict about the qb file names
+ else we can get messages been put in the wrong subsys.
+
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ LOG: drop the number of logging subsystems from 64 to 32
+ Currently 14 are used, 64 seems like a waste of memory.
+
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+2012-05-24 Barney Desmond <barney.desmond@anchor.net.au>
+
+ Correct the description of bindnetaddr config parameter in manpage
+ bindnetaddr has been wrongly described in the past, and did not
+ document that fact that it will also accept exact address matches.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2012-05-24 Jan Friesse <jfriesse@redhat.com>
+
+ totemip: Support bind to exact address
+ Logic for binding now works in following way:
+ - Try to find exact match
+ - If not exact match is found, use first found network address
+
+ This allows set concrete IP even if network settings contains two IPs on
+ same network.
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ totemip: insert items in correct order
+ list_add_tail is used instead of list_add so ip addresses are inserted
+ in same order as returned by getifaddrs.
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+2012-05-21 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ init: major cleanup
+ - rename generic.in and notifyd.in to corosync.in and corosync-notifyd.in
+ (makes build simpler)
+ - fix sysvinit corosync.in sleep time to include a check for when IPC
+ are ready and drop cman bits (there is no cman with corosync 2.0)
+ - corosync-notifyd.service should always start after corosync.service
+ - corosync.service should always start after network
+ - corosync.service uses init script wrapper
+ - install/ship sysvinit as wrappers for systemd in /usr/share/corosync
+ when necessary
+ - change the build system to deal with all of the above
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2012-05-17 Jan Friesse <jfriesse@redhat.com>
+
+ Include ringid in processor joined log message
+ This should help correlate syslog entires with their blackbox
+ counterparts.
+
+ Reviewed-by: Andrew Beekhof <andrew@beekhof.net>
+
+2012-05-15 Jan Friesse <jfriesse@redhat.com>
+
+ Update TODO file
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+2012-04-26 Dan Clark <2clarkd@gmail.com>
+
+ Improve testcpg to handle change of node identity
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2012-04-24 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ icmap: don't leak memory when changing ro/rw status on a key
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ icmap: fix a valgrind errors (pass 1)
+ clean up a lot of allocated blocks at exit.
+ those changes has no runtime effects, but it makes valgrind
+ output a bit more useful by dropping over 700 errors/warnings to skip
+ over every single run.
+
+ there are still a few icmap related valgrind errors but those need
+ some more complex and timeconsuming investigation.
+
+ pre patch:
+
+ ==21844== HEAP SUMMARY:
+ ==21844== in use at exit: 1,229,321 bytes in 1,516 blocks
+ ==21844== total heap usage: 7,191 allocs, 5,675 frees, 3,819,853 bytes allocated
+
+ ==21844== LEAK SUMMARY:
+ ==21844== definitely lost: 3,617 bytes in 11 blocks
+ ==21844== indirectly lost: 21,960 bytes in 11 blocks
+ ==21844== possibly lost: 1,080,101 bytes in 131 blocks
+ ==21844== still reachable: 123,643 bytes in 1,363 blocks
+ ==21844== suppressed: 0 bytes in 0 blocks
+
+ ==21844== ERROR SUMMARY: 136 errors from 136 contexts (suppressed: 0 from 0)
+
+ post patch:
+
+ ==25793== HEAP SUMMARY:
+ ==25793== in use at exit: 1,185,870 bytes in 808 blocks
+ ==25793== total heap usage: 9,427 allocs, 8,619 frees, 4,156,841 bytes allocated
+
+ ==25793== LEAK SUMMARY:
+ ==25793== definitely lost: 3,697 bytes in 12 blocks
+ ==25793== indirectly lost: 22,248 bytes in 13 blocks
+ ==25793== possibly lost: 1,079,655 bytes in 113 blocks
+ ==25793== still reachable: 80,270 bytes in 670 blocks
+ ==25793== suppressed: 0 bytes in 0 blocks
+
+ ==25793== ERROR SUMMARY: 119 errors from 119 contexts (suppressed: 0 from 0)
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2012-04-20 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ crypto init: release *_slot resource after init
+ Those are only used at init phase and we can free some memory for the system.
+
+ Reviewed-by: Angus Salkeld <asalkeld@redhat.com>
+
+2012-04-16 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ ipcs: allow connections only after all services are ready
+ this fixes a rather annoying race condition at startup where a client
+ connects to corosync "too fast" before the service is ready to operate
+ and client gets some random data during initialization phase.
+
+ With this fix, we allow connections to ipc only after the main engine
+ is operational and configured (and after the first totem transition).
+
+ Reviewed-by: Angus Salkeld <asalkeld@redhat.com>
+
+2012-04-10 Jan Friesse <jfriesse@redhat.com>
+
+ Always allocate totemrrp stats array
+ This prevents segfault when rrp mode is set with only one ring.
+
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ Properly parse uidgid files
+ Full path to key is now tested rather then key name only.
+
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+2012-04-10 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ build: improve systemd service file handling
+ this solves the issue of having to special case before and after usrmove
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2012-04-06 Jan Friesse <jfriesse@redhat.com>
+
+ Remove info pages see also from cmapctl man
+ Corosync doesn't have documentation in info format, so information is
+ corosync-cmapctl was not true.
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ Add man page with CMAP keys created by corosync
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+2012-04-05 Angus Salkeld <asalkeld@redhat.com>
+
+ Check before making a reference to __start___verbose
+
+2012-04-03 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ conf: add quorum section to example config
+ document only the provider option since all the others
+ (votes/expected_votes/etc) are provider specific.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2012-04-03 Angus Salkeld <asalkeld@redhat.com>
+
+ Only call qb_ipcc_disconnect when the instance is fully dereferenced.
+ Sometimes calling xyz_finilize() within a dispatch would
+ cause a crash because the qb_ipcc_disconnect actually
+ disconnects immediatly and frees it't memory. whereas
+ the corosync structure is reference counted. So this
+ makes use of the reference counting to only call
+ qb_ipcc_disconnect when it is fully dereferenced.
+
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+2012-03-27 Jan Friesse <jfriesse@redhat.com>
+
+ Convert udpu example to use nodelist
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+2012-03-27 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ totemcrypt: fix build warning (unused variable)
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ totemcrypto: major code cleanup (no functional or onwire changes)
+ - cleanup include list
+ - reorder code and functions (crypto then hash)
+ - split crypt/decrypt/hash functions
+ - some micro optimizations by dropping a few memcpy
+ - make the code more readable (better var names and buffers mapping)
+ - improve exit paths on error (return codes and free)
+ - store crypto header size instead of recalculating it per packet
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2012-03-26 Jan Friesse <jfriesse@redhat.com>
+
+ Make ifaces_get work with dynamic no_rings
+ Commit which added number of addresses to srp_address structure didn't
+ count with totemsrp_ifaces_get where whole structure was copied instead
+ of addresses only. This is now fixed.
+
+ Also to make API totempg forward compatible, size of interfaces array
+ must be passed to ifaces_get like functions to prevent memory overwrite.
+
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+2012-03-22 Jan Friesse <jfriesse@redhat.com>
+
+ Add no_addrs field in srp_addr structure
+ This should allow us future change to dynamic number of rings without
+ breaking wire compatibility.
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+2012-03-16 Jan Friesse <jfriesse@redhat.com>
+
+ Reflect config changes for crypto in examples
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ Mark few more icmap keys as read only
+ Also most of the key settings are now centralized in one function, so
+ it's easier to audit.
+
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+2012-03-15 Jan Friesse <jfriesse@redhat.com>
+
+ Make common_lib version independand on totem_pg
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ crypto: Remove sha224 and add md5 hash
+ SHA224 is not supported on RHEL6 and also it's kind of weird. Instead of
+ that, md5 can now be configured.
+
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ Update crypto_set API
+ Also few leftovers from cfg is removed and version of totempg is
+ increased to 5 to reflect all changes we made
+
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+2012-03-15 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ crypto: allocate padding in crypto_header
+ while it might seem a waste of space by using 2 extra bytes in
+ the crypto_config_header, it actually gives us the option
+ to grow "unknown at this time" features without hopefully
+ breaking onwire compat
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ crypto: add new hashing methods and fix config defaults
+ add support for sha224/256/384/512
+
+ change config defaults to match coroparse and totemconfig
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2012-03-15 Jan Friesse <jfriesse@redhat.com>
+
+ Document crypto_hash and crypto_cipher options
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+2012-03-14 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ crypto: change network packets and add dynamic crypto header/data
+ The new network packet will look:
+
+ struct crypto_config_header * that provides info on crypto/hashing
+ hash_block[size based on hashing function] (if hash is selected)
+ salt[SALT_SIZE] (if crypto is selected)
+ ...data...
+
+ and we kill the concept of crypto_security_header completely since
+ values are now dynamic for hash_block_size.
+
+ the reason why hash_block needs to be there, is because we do
+ hash salt in case both hashing and crypto are selected.
+
+ the crypto_config_header is totally transparent to totem
+ and to any underlaying crypto functions.
+
+ as we go cleaning, also use HASH_BLOCK_SIZE to generate hash_block.
+ the input buffer and output buffer size are dependent on the algo
+ used to hash.
+
+ we can now determine the real header size and adjust net_mtu properly
+ at startup. This will allow in future to use any algorithm since
+ size is dynamic.
+
+ some part of the code still needs some polishing to make it more
+ readable (specially the mapping of pointers into the packet
+ is still a bit obscure).
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ totem: don't send garbage onwire if we fail to crypt
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ crypto: add crypto config to network data
+ this add 2 bytes at the end of the each packet to propagate
+ config info.
+
+ in case there is a config mismatch packet must be rejected.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ crypto: drop secauth and make crypto none work again
+ keep totem.secauth config key for compatibility
+
+ if the key is NOT set, crypto will default to aes256/sha1
+ if the key is set to "off", crypto is disabled.
+ this reflects pretty much old behavior
+
+ keywords totem.crypto_cipher and totem.crypto_hash can
+ override secauth individually.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2012-03-13 Jan Friesse <jfriesse@redhat.com>
+
+ Parse and use hash and crypto from config file
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ Rename totemcrypto
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+2012-03-13 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ crypto: mask the crypto operations from totem packet size management
+ totem doesn't need to understand what crypto does.
+
+ totem needs to be able to tell crypto: "those are data, play with them"
+ and crypto needs to return: "here are your scrambled data and the new size"
+
+ similar to decrypt/verify.
+
+ this way we add enough dynamic within crypto to change header size and all
+ at any given time (for different hash algorithm for example) without
+ affecting on wire compat.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2012-03-13 Jan Friesse <jfriesse@redhat.com>
+
+ onecrypt: move encryption code to crypto.c
+ This will remove duplicity of code.
+
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ cfg: remove crypto_set
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ corosync-cfgtool: Remove set of cryptography
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ Remove libtomcrypt
+ Tomcrypt in corosync is for long time not updated. Because we have
+ support for libnss, libtomcrypt can be removed.
+
+ Also few leftovers (AES is 256 bits, not 128, ...) are removed.
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+2012-03-12 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ drop evs service
+ there are several reasons for this:
+
+ 1) evs is only partially implemented with no plans to complete it
+
+ typedef enum {
+ EVS_TYPE_UNORDERED, /* not implemented */
+ EVS_TYPE_FIFO, /* same as agreed */
+ EVS_TYPE_AGREED,
+ EVS_TYPE_SAFE /* not implemented */
+ } evs_guarantee_t;
+
+ 2) evs has no users in any upstream distribution and no search
+ engine can find any other upstream using it.
+
+ 3) the only reason (I was told) to carry around evs was that evs
+ receives the full ring_id struct from totem. This is only
+ partially correct because while the structures are prepared
+ to carry around those data, they are never transmitted from
+ corosync engine down the IPC line to the user.
+ CPG ring_id contains the exact same information and it's
+ actually less buggy (due to prototying of the info).
+
+ worst case scenario where a user really absolutely need libevs,
+ it can be easily reimplemented as libcpg wrapper and avoid
+ lots of code duplication.
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ build: drop another leftover from the past
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ build: drop obsoleted SOCKETDIR option
+ yet another leftover from the past that can go away
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ build: drop last LCRSO references
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ pload: make it a test service and not a public one
+ pload is a performance benchmark that measures the onwire
+ speed of corosync.
+
+ problem is that once pload has been executed, the cluster
+ is basically dead.
+
+ turn pload into a test tool, by removing corosync-pload tool
+ and user library.
+
+ cleanup pload code to make it more readable and drop lots
+ of unnecessary stuff.
+
+ add test/ploadstart tool that can configure and start pload
+ via cmap calls.
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+2012-03-10 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ totem: drop crypt_accept: concept/option
+ this was another old onwire compat mode that is not useful anylonger.
+
+ we can safely move the new model by default.
+
+ According to Honza (real hardware 1 node testing) there are no
+ performance impact.
+
+ My tests (8 nodes VM cluster), there is up to 10/12% performance
+ improvements up to 1M packet size where old and new models are equal.
+
+ As a side note, nss still shows to be a performance loss on both
+ real and virtual hw (without any kind of nss hw acceleration).
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+2012-03-09 Angus Salkeld <asalkeld@redhat.com>
+
+ Fix typo in stats key name.
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ Remove unused function logsys_priority_name_get()
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ Add pid, hostname and process name to the logfile
+ Note this is only for file targets not stderr or syslog.
+
+ https://bugzilla.redhat.com/show_bug.cgi?id=789925
+
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+2012-03-09 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ drop last references to compatibility: whitetank
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+ Reviewed-by: Angus Salkeld <asalkeld@redhat.com>
+
+ utils: cleanup main daemon exit codes
+ some of them are not in use anymore and can be dropped.
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ sync: kill evil and syncv1 in one shot
+ this change breaks onwire compatibility.
+
+ cpg is the only user of sync_* interface and it's the only
+ service that will require extra testing.
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2012-03-06 Jan Friesse <jfriesse@redhat.com>
+
+ man: Add cmap pages to index.html
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ man: Add description of cpg_iteration_* functions
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ man: Fix cmap_iter_finalize typo
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+2012-03-05 Angus Salkeld <asalkeld@redhat.com>
+
+ Treat ENOMSG as TRY_AGAIN.
+ ENOMSG is returned by the ringbuffer when you attempt to read
+ a message and there is nothing there to read.
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ Add common IPC errors.
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+2012-03-05 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ quorumtool: improve display of status data
+ always display membership data from the local node
+
+ display when a node is unknown to the local node instead of an error
+ from IPC.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ votequorum: move last malloc/alloca buf to static
+ this should guarantee that votequorum won't fail under high memory
+ pressure. Price is 3500 bytes extra preallocated at startup.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ votequorum: fix node allocation memory leak
+ stop using malloc for each new node, because we cannot free the memory
+ easily. Move to a static allocated buffer that can contain
+ PROCESSOR_MAX + qdevice cluster_node instead.
+
+ We can never have more than PROCESSOR_MAX nodes anyway and the memory
+ footprint is small enough compared to memory leaks (those can
+ effectively happen only in very dynamic clusters with tons of different
+ nodes joining/leaveing with different nodeids).
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2012-03-02 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ votequorum: rename leave_remove to allow_downscale
+ pointed out that leave_remove can be easily confused with the old
+ cman leave_remove behavior. The two are substantially different
+ and we need to avoid confusion both for users and our support team.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ votequorum: fix handling of config updates
+ cmap changes are local to the node only and should not be broadcasted
+ as configuration changes.
+
+ if any change has happened to us, we will inform other nodes via
+ send_nodeinfo.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ votequorum: free our data and lists on exit
+ this is mostly to avoid valgrind errors on exit and make the output
+ more readable.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ votequorum: disallow special features vs qdevice
+ simply taking the safest path here since integration of qdevice is not
+ fully complete
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ votequorum: fix node check based on reconfig parameter
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ votequorum: make a common function to calculate votes and cluster members
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ votequorum: incorporate static config into dynamic
+ no functional changes or extra features yet
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ votequorum: move all configuration in votequorum_readconfig
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ votequorum: start moving from static to fully dynamic config
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ votequorum: disallow wait_for_all and qdevice operations
+ The problem here is that user expectations, when using both modes
+ at the same time, have not been set yet. There are 2/3 options
+ that need investigation.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ votequorum: improve debugging output
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2012-03-02 Jan Friesse <jfriesse@redhat.com>
+
+ Always set interface_up in totemip_iface_check
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+2012-02-29 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ votequorum: fix node->flags type when receiving nodeinfo messages
+ old_flags was set to uint16_t but it needs to be uint32_t.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ votequorum: fix segfault in wfa status update
+ this is a regression introduced by cb5fd775
+
+ when reading static config us->flags does not exists yet and therefor
+ setting it will cause a segfault.
+
+ Move the settings after cluster_node *us is created, with the long
+ term plan to simply kill the whole _static readconfig bits
+ in favour of dynamic (runtime changeable) bits.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2012-02-28 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ quorumtool: improve Membership information output
+ align nodeid, votes and name to make it all more readable
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ quorumtool: make output more human friendly and retain machine parsable bits
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ quorumtools: fix typo in man page
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ quorumtools: drop unused option parsing
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ quorumtool: fix version display info
+ we don't need that on every run
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2012-02-27 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ quorumtool: swap node state and node votes output
+ there is no point to show the votes if the node is dead
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ votequorum: fix votequorum_getinfo man page and align struct name
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ quorumtool: update man page and help text
+ improve error output since this is more than a debugging tool now
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ votequorum: major rework to fix qdevice API and integration with core
+ qdevice is a very special node in the cluster and it adds a certain
+ amount of complexity and special cases across the code.
+
+ most of the qdevice data are shared across the cluster (name/votes)
+ but effectively each node has a different view of the qdevice
+ (registered/unregistered/voting/etc.)
+
+ with this change, we align the qdevice view across the node,
+ exchanging more data between nodes and we fix how qdevice behaves
+ and it is configured.
+
+ The only side effect is that the amount of data transmitted on wire
+ is slightly higher.
+
+ The qdevice API is still disabled by default. This means that
+ the amount of real changes in current code are a lot smaller
+ than it appears by this patch.
+
+ TODO: documentation/man pages needs to be updated once
+ this change is in (and behavior finalized).
+
+ User visible changes:
+
+ - configuration (coroparse, exec/votequorum):
+ the quorum device section is now standalone within the quorum.
+
+ quorum {
+ provider: corosync_votequorum
+ device {
+ model: (name)
+ timeout: (millisec)
+ votes:
+ }
+ }
+
+ the keyword "model:" is mandatory to enable qdevice in configuration
+ and should express the name of the script/daemon that will provide
+ the qdevice. Looking into the future, an init script or systemd
+ service will look for that name in /path/to/be/decided/name
+ and start/stop qdevice.
+
+ timeout: defines the maximum interval the qdevice implementation
+ has available between poll (see votequorum_qdevice_poll.3) before
+ the device is considered dead and votes discarded
+
+ votes: is now a configuration parameter and not an API call.
+ quorum devices don't care what they need to vote.
+ votes is autocalculated when a nodelist is available and all
+ nodes in the list vote 1. Otherwise this parameter is mandatory.
+
+ - configuration (exec/votequorum):
+ startup and runtime configuration changes have been improved.
+ errors at startup are considered fatal. errors at runtime
+ have different exit paths.
+
+ startup:
+
+ * quorum.two_node and qdevice are incompatible.
+ * quorum.expected_votes requires quorum.device.votes.
+ * quorum.expected_votes - quorum.device.votes cannot be lower
+ than 2.
+ * qdevice and last_man_standing are mutually exclusive.
+ * qdevice and auto_tie_breaker are mutually exclusive.
+
+ runtime config changes:
+
+ * quorum.two_node and qdevice are incompatible:
+ if quorum device is alive, two_node is disabled.
+ if quorum device is not alive and node count is 2, two_node is
+ enabled, and quorum device cannot be registered
+
+ * if either last_man_standing or auto_tie_breaker were enabled
+ at startup, and at runtime quorum device is configured,
+ quorum device registration will be blocked.
+
+ * if quorum.expected_votes is configured but not quorum.device.votes,
+ quorum device registration will be blocked.
+
+ * if quorum.device.votes is not configured and we cannot
+ automatically calculate it, quorum device registration will be blocked.
+
+ * An error in configuring quorum.expected_votes and quorum.device.votes
+ will block quorum device registration.
+
+ blocking quorum device registation, also means dropping the votes.
+
+ quorum.device.votes (either set or automatically calculated) is now
+ used to determine current expected_votes in the cluster.
+
+ - logging (exec/votequorum):
+
+ all errors from configuration are treated as WARNING/CRITICAL.
+
+ lots of extra DEBUG output is added (see internal changes too).
+
+ - corosync-quorumtool (tools/corosync-quorumtool):
+
+ * added option to forcefully kick out a quorum device from the local
+ node. This is for emergency recovery only and it is only
+ available when qdevice API is built-in.
+
+ * Improved status output, specifically add node state and qdevice
+ information
+
+ [root@fedora-master-node2 coro]# corosync-quorumtool -s
+ Version: 1.99.4.12-9c7d-dirty
+ Quorum type: corosync_votequorum
+ Nodes: 2
+ Ring ID: 132
+ Quorate: Yes
+ Node votes: 1
+ Node state: Member
+ Expected votes: 3
+ Highest expected: 3
+ Total votes: 3
+ Quorum: 2
+ Flags: Quorate Qdevice
+ Nodeid Votes Name
+ 1 1 fedora-master-node1.int.fabbione.net
+ 2 1 fedora-master-node2.int.fabbione.net
+ 0 1 QDEVICE (Voting)
+
+ * allow to print status for any node in the cluster known to
+ local node.
+
+ [root@fedora-master-node1 coro]# corosync-quorumtool -s
+ Version: 1.99.4.12-9c7d-dirty
+ Quorum type: corosync_votequorum
+ Nodes: 2
+ Ring ID: 144
+ Quorate: Yes
+ Node votes: 1
+ Node state: Member
+ Expected votes: 3
+ Highest expected: 3
+ Total votes: 2
+ Quorum: 2
+ Flags: Quorate
+ Nodeid Votes Name
+ 1 1 fedora-master-node1.int.fabbione.net
+ 2 1 fedora-master-node2.int.fabbione.net
+
+ [root@fedora-master-node1 coro]# corosync-quorumtool -s -n 2
+ Version: 1.99.4.12-9c7d-dirty
+ Quorum type: corosync_votequorum
+ Nodes: 2
+ Ring ID: 144
+ Quorate: Yes
+ Node votes: 1
+ Node state: Member
+ Expected votes: 3
+ Highest expected: 3
+ Total votes: 3
+ Quorum: 2
+ Flags: Quorate Qdevice
+ Nodeid Votes Name
+ 1 1 fedora-master-node1.int.fabbione.net
+ 2 1 fedora-master-node2.int.fabbione.net
+ 0 1 QDEVICE (Voting)
+
+ Internal changes:
+
+ - change qdevice timer to not run all time, but only when necessary.
+ - change votequorum_nodeinfo on wire data to use flags instead of uint8_t
+ and add QDEVICE status.
+ - allocate nodeid 0 to qdevice since it's the only real
+ nodeid that be reserved.
+ - change send_nodeinfo to allow to send nodeinfo for any node
+ so that we can share qdevice info across the cluster
+ (and this might be useful in future if we need to sync
+ internal cluster view).
+ - add votequorum api call to update qdevice name
+ - add runtime data if quorum device has been forcefully disabled
+ by config error
+ - add qdevice votes to expected_votes calculation (this
+ is probably the biggest difference vs cman)
+ - change votequorum_read_nodelist_configuration so that
+ we can autocalculate votes for qdevice (we need the nodecount
+ vs votes).
+ - add all checks for startup/runtime config (see above).
+ - do not make qdevice part of the membership_list received from
+ totem. None of our users care about it and it is not a real node.
+ - change onwire message handlers to deal with "data for this node from any node"
+ case and undersand nodeid 0 for qdevice info
+ - always allocate qdevice at startup. this simplifies code a lot.
+ - dispatch qdevice nodeinfo on membership changes.
+ - inform libvotequorum users when a qdevice is registered
+ - improve substantially qdevice api and add a simple
+ barrier based on qdevice name.
+ - add qdevice API barrier at cluster level. This feature allow
+ only one qdevice name to be active in the cluster at any time.
+ - qdevice getinfo can now report status for qdevice on any node.
+ - change slightly the way the qdevice API is built-in/out:
+ only the libvotequorum calls are #ifdef'out now. Doing so in
+ the core is too complex and would make the code unreadable
+ with the risk of missing a bit or two effectively introducing
+ an on-wire incompatibility if we will ever turn the API on.
+ - probably added some bugs on the way...
+
+ TODO: update qdevice_* API once the above is settled and test
+ qdevice integration with other features.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+ Reviewed-by: Steven Dake <sdake@redhat.com> (only second part)
+
+2012-02-22 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ build: fix fallout from swithing to common shared lib
+ when building corosync on a clean system or for the very first
+ time, corosync_common needs to be visible both via -L for link
+ and for the LD_PATH, otherwise the linker cannot resolve
+ normal library dependencies.
+
+ This issue does NOT affect corosync users, but it's confined
+ to internal corosync only.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2012-02-21 Jan Friesse <jfriesse@redhat.com>
+
+ Document SAM_RECOVERY_POLICY_CMAP
+ Also all irelevant references for SAM_RECOVERY_POLICY_CONFDB are
+ corrected.
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ Tweak nodeid warning
+ Nodeid warning now appears only when both totem.nodeid and nodelist
+ nodeid exists. When nodelist nodeid is not defined, totem.nodeid is
+ used.
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ spec: Add optional xmlconf
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ iba: Use configured node id
+ Corosync was ignoring nodeid for iba transport and always used
+ autogenerated one.
+
+ Original patch by: Jason Dillaman <jdillama@redhat.com>
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+2012-02-21 Angus Salkeld <asalkeld@redhat.com>
+
+ Convert the common lib into a shared lib.
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+2012-02-16 Jan Friesse <jfriesse@redhat.com>
+
+ Allow autoconfiguration of interface section
+ Thanks to totemip_getifaddrs infrastructure it's now possible to use
+ nodelist informations to autoconfigure interface bindnetaddr. Together
+ with cluster_name, interface section can be completely omitted.
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ totemconfig: ensure suffix for ringX_addr
+ Patch makes sure, that ringX_addr key has really _addr suffix.
+ Previously, it was possible to enter ringXanything and it was
+ interpreted as ringX_addr.
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ cmap: Handle NULL in [i]cmap_set_string value
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ Create solaris specific getifaddrs
+ This not only makes possible to use generic totemip_iface_check, but
+ also fixes some problems with previous implementation (fixed mask, not
+ very well supported ipv6, ...)
+
+ Tested on OpenIndiana 151a
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ Add totemip_iface_check based on totemip_getifaddrs
+ Also Linux and BSD/Darwin specific bits are no longer needed, so they
+ are gone.
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ Add generic implementation of getifaddrs
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+2012-02-14 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ build: fix make dist to include xml man pages
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2012-02-14 Angus Salkeld <asalkeld@redhat.com>
+
+ Change the IPC TIMEOUT to block.
+ This is to make sure that we properly wait for responses
+ from corosync. I have made a fix to libqb to properly
+ handle the case when corosync exits/crashes between
+ a send and receive.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ CPG: fix membership_get()
+ 1) remove BUSY loop from membership get
+ Note only cpg_join and cpg_leave ever set the
+ BUSY error code.
+ 2) set the size correctly
+ 3) copy the name in correctly
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ TEST: remove unused code.
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ Move hdb_error_to_cs to corotypes.h
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ TEST: add logging to testcpg and testevs
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ TEST: Use pacemaker repeat macro
+ This is to simulate the way pacemaker uses the cpg api.
+ With this you can run testcpg directly after corosync
+ starts and it should initialise ok.
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+2012-02-14 Steven Dake <sdake@redhat.com>
+
+ Remove a reference to openais that is present in corosync.conf.5
+ Reviewed-by: Angus Salkeld <asalkeld@redhat.com>
+
+ Update corosync_overview.8 man page
+ Move forward 5 years on our main man page ;)
+
+ Reviewed-by: Angus Salkeld <asalkeld@redhat.com>
+
+ Remove empty testquorum.c file
+ Reviewed-by: Angus Salkeld <asalkeld@redhat.com>
+
+ Update copyright header dates in exec directory
+ Reviewed-by: Angus Salkeld <asalkeld@redhat.com>
+
+ Update copyright dates on include/totem files
+ Reviewed-by: Fabio Di Nitto <fdinitto@redhat.com>
+
+ Remove jhash.h since it is not used
+ We would use libqb for hashing now if we needed hashing.
+ cpg no longer uses jhash.h.
+
+ Reviewed-by: Fabio Di Nitto <fdinitto@redhat.com>
+
+ Updated copyright dates in include directory
+ Reviewed-by: Fabio Di Nitto <fdinitto@redhat.com>
+
+ Update copyright dates in tools directory
+ Reviewed-by: Fabio Di Nitto <fdinitto@redhat.com>
+
+ Update copyright dates in util directory
+ Reviewed-by: Fabio Di Nitto <fdinitto@redhat.com>
+
+ Remove unused or unimplemented CFG apis
+ Remove:
+ cfg_statetrack
+ cfg_statetrackstop
+ cfg_administrativestateste
+ cfg_administrativestateget
+ cfg_serviceload
+ cfg_serviceunload
+
+ Rev SO to 5.0.0
+
+ Reviewed-by: Angus Salkeld <asalkeld@redhat.com>
+
+2012-02-13 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ votequorum: cleanup all man pages
+ sort and reference man pages in typical usage order
+
+ update some structures/defines
+
+ clean formatting to be consistent
+
+ don't ship qdevice API man pages for now
+
+ Reviewed-by: Angus Salkeld <asalkeld@redhat.com>
+
+2012-02-10 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ quorum: cleanup all man pages
+ sort and reference man pages in typical usage order
+
+ update some structures/defines
+
+ clean formatting to be consistent
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2012-02-09 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ cpg: drop dead code
+ not used/referenced anywhere
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ coverity: increase aggressiveness of the test and fix build
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ votequorum: fix variable init
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ quorumtool: fix some var init and checks
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ votequorum: fix possible memory corruption
+ nodeid = 0 is a valide nodeid and node associated with it should
+ not be freed
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ quorum: don't leak memory on error
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ testvotequorum: fix test loop to break if votequorum goes away
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ quorumtool: fix return code
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ testquorum: check for quorum_dispatch return code
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ quorumtools: check for quorum_dispatch return code
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ specfile: ship new man pages
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ man: add *quorum_track* devel man pages
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ quorum: drop dead code
+ spotted while writing man pages. There are no users for this struct
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ man: add quorum_overview.8 man page
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ man: hook quorum and votequorum devel man pages with genman script
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ man: rename all devel man pages to .3.in
+ tidy up man/Makefile.am a bit in the process
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ man: add build infrastructure to generate devel man pages
+ this is useful to include ipc_common errors into all man pages
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+2012-02-09 Angus Salkeld <asalkeld@redhat.com>
+
+ move cs_strerror() to common_lib
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ Treat ENOBUFS as TRY_AGAIN
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ move hdb_error_to_cs to common_lib
+ Note the previous inconsistent implementation.
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ Add a common library that can be shared between libs and corosync
+ We have always had this problem and worked around it by coping code
+ or using inline functions. Both not good IMO.
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+2012-02-08 Steven Dake <sdake@redhat.com>
+
+ Remove cs_config.h from global header install
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ Remove include/engine/quorum and integrate it into exec/engine.h
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ Remove swab.h from global headers
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ Remove list.h from global header install
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ Remove mar_gen.h from global header install since it is not needed
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2012-02-08 Jan Friesse <jfriesse@redhat.com>
+
+ Add CS_DISPATCH_ONE_NONBLOCKING dispatch type
+ Add missing option for dispatch, which fills gap in combination of
+ block/nonblock and one/all dispatch types. New type doesn't mask
+ CS_ERR_TRY_AGAIN, and it means "no message was processed".
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+2012-02-08 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ corotype: drop deprecated CPG_ defines
+ the only user of those obsoleted defines is dlm master (already ported)
+ to use CS_ and cmirror (that needs full porting to new corosync either way).
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ corotypes: drop deprecated QUORUM_ defines
+ neither corosync or any of the dependencies use it.
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ corotypes: drop deprecated EVS_ defines
+ none of our current dependencies use it.
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+2012-02-07 Steven Dake <sdake@redhat.com>
+
+ Free state variable allocated in wd_resource_state_is_ok
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ Remove leaked resource error from wd_resource_state_is_ok
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ Remove use after free and free of uninit value in mainconfig error path
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ Remove use after free in corosync_main_config_set in error path
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ Remove dead code in sam test agent
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2012-02-07 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ votequorum: fix quorum_ringid setting before any delivery occours
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2012-02-07 Angus Salkeld <asalkeld@redhat.com>
+
+ Make sure ipc functions return CS_ERR_TRY_AGAIN and not CS_ERR_TIMEOUT
+ This is because most applications that use corosync do not test
+ for TIMEOUT but only for TRY_AGAIN.
+
+ Reviewed-and-Tested-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ Remove deprecated function qb_util_set_log_function()
+ Use the standard qb_log api.
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ LOG: add libqb as a "subsys"
+ So we can see libqb internal logs
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+2012-02-06 Jan Friesse <jfriesse@redhat.com>
+
+ cmap: Check RO flag in adjust int function
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ CMAP man pages
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+2012-02-06 Jiaju Zhang <jjzhang@suse.de>
+
+ CPG: Send CPG_REASON_PROCDOWN when really needed
+ This patch fixes the issue that in some cases where cpg_finalize()
+ was called just after cpg_leave() was called, CPG_REASON_PROCDOWN
+ might also be sent while CPG_REASON_LEAVE had already been sent.
+ This behavior is not aligned with what the man page has described:
+ "CPG_REASON_PROCDOWN - the process left a group without calling
+ cpg_leave()."
+ And it will confuse CPG's clients in that one process left results
+ in two different reasons being sent.
+
+ The root cause of this issue is cpg_leave() will return after
+ adding the LEAVE message to the sending queue, but the cpg's group
+ name has not been cleared yet. Just at that time, cpg_finalize()
+ is being called, then it determines if there is the calling of
+ cpg_leave() happened only by the checking of cpg's group name, so
+ this method is not sufficient.
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+2012-02-03 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ quorumtool: fix return codes for show_status and monitor
+ correct return codes should be:
+ 1 if node is quorate
+ 0 if node is not quorate
+ -1 if there is any error gather info on the node
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ quorumtools: fix nodes display on status
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ votequorum: fix expected votes manual override from quorumtools
+ votequorum internal quorum/expected_vote check was slightly too
+ conservative and was not done correctly when leave_remove feature
+ is enabled.
+
+ this fix allows admins to effectively override expected_votes
+ and drive ev_barrier as expected.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2012-02-03 Jan Friesse <jfriesse@redhat.com>
+
+ Better checks of integer values in coroparse
+ Instead of atoi, strtol is used. This allows detection of typical
+ problems like empty value of key and incorrectly entered numbers.
+
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+2012-02-02 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ votequorum: add runtime internal data to icmap runtime.votequorum.*
+ specifically ev_barrier, two_node, lowest_node_id and wait_for_all_status
+ are values that change internally at runtime and keeping track
+ of those can make debugging rather easy, specially when LOG_DEBUG is not
+ set.
+
+ Also track our node id.
+
+ Reviewed-By: Christine Caulfield <ccaulfie@redhat.com>
+
+2012-02-02 Jan Friesse <jfriesse@redhat.com>
+
+ Wait for corosync-notifyd exit in init script
+ Without wait for real exit of corosync-notifyd it can happen, that new
+ corosync-notifyd is killed. To prevent such condition, stop now wait for
+ process to die, before exit of stop function.
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ Show correct error when open of logfile failed
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ Store error str if can't open logfile
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+2012-02-02 Angus Salkeld <asalkeld@redhat.com>
+
+ IPC: reference count the connection whilst flushing the outq
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+2012-02-01 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ build: fix make dist and make rpm
+ do some cleanup around to include all files that need to be shipped
+ and honor conditional builds properly
+
+ Reviewed-by: Angus Salkeld <asalkeld@redhat.com>
+
+2012-01-31 Angus Salkeld <asalkeld@redhat.com>
+
+ IPC: allow for failures in the connection_created callback
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+2012-01-31 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ votequorum: add leave_remove option
+ this also cleanup NODESTATE for good. JOINING was never used
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ votequorum: honor onwire node flags change
+ internal flags were not propagated correctly in the node status
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ quorum: fix load/unload priority for quorum services
+ all main services are loaded at priority 1.
+ vfs_quorum and votequorum did not specify a priority and
+ automatically defaulting to 0, that has a special meaning
+ of being loaded last and unloaded last.
+
+ this is not correct behavior and limits what votequorum
+ can do at shutdown, for example notify other nodes that
+ it is leaving (something that cannot be gathered by
+ totem membership change callback).
+
+ fix vsf_quorum to load at priority 1 as the other
+ default services and bump votequorum to 2 (needs to
+ unload before everything else currently known).
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ service: fix service unload regression introduced by lcrso dropping
+ service exec_exit_fn was not honored because the loop was looking
+ into the wrong icmap key
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ votequorum: fix possible string overflow (-1) in qdevice_register
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ votequorum: drop unnecessary flags
+ code inspection shows that those internal flags are never used
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2012-01-31 Angus Salkeld <asalkeld@redhat.com>
+
+ CTS: cleanup the cpg test agent
+ improve the diagnostic log messages
+
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ CTS: make the systemd logic more reliable
+ rely on positive logic as there can be multiple
+ failure reasons.
+
+2012-01-30 Steven Dake <sdake@redhat.com>
+
+ Honor exec_init_fn call
+ exec_init_fn now either returns NULL (success) or a string which indicates
+ the error that occured during service engine initialization. If an error
+ occurs, corosync will exit. This patch adds ykd and makes other suggestions
+ from Fabio Di Nitto.
+
+ Reviewed-by: Fabio Di Nitto <fdinitto@redhat.com>
+
+ Return an exit code of 1 if an interface is faulty in corosync-cfgtool
+ Reviewed-by: Fabio Di Nitto <fdinitto@redhat.com>
+
+2012-01-30 Angus Salkeld <asalkeld@redhat.com>
+
+ cmap: add iterator finalize
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ cmap: add -D option to getopt
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+2012-01-27 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ votequorum: rename qdisk to qdevice
+ a quorum device is not necessarely a disk and this also aligns
+ various names to be generic
+
+ Reviewed-By: Christine Caulfield <ccaulfie@redhat.com>
+
+ quorum: drop quorum.quorate config option
+ it's unused / unnecessary
+
+ Reviewed-By: Christine Caulfield <ccaulfie@redhat.com>
+
+2012-01-27 Angus Salkeld <asalkeld@redhat.com>
+
+ CTS: add test VoteQuorumWaitForAll
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ CTS: remove test service config
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ augeas: update the lense (rm amf & add update quorum options)
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ CTS: be consistent with the cpg group name
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ CTS: make the status command more accurate
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ CTS: remove SamTestQuorum as there is not test_quorum anymore
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ CTS: ignore blackbox shm
+ (only whilst running as it is still visable)
+
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ CTS: delete resourses recursively
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ CTS: init votequorum by default
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ CTS: account for change in sam resource path.
+ This was:
+ process_name:pid
+ now:
+ pid
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ CTS: handle socket exceptions better
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ CTS: fix shell script variable name
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+2012-01-26 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ update TODO list
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ votequorum: fix expected_votes propagation
+ it is not correct to randomly accept expected_votes from any node in
+ the cluster. We can only allow expected_votes from quorate nodes.
+
+ A quorate cluster is "always" right and have the correct expected_votes.
+
+ One of the different bug triggers:
+
+ quorum {
+ expected_votes: 8
+ auto_tie_breaker: 1
+ last_man_standing: 1
+ }
+
+ start all 8 nodes.
+ clean shut down 2 nodes.
+ wait for lms to kick in.
+ kill 3 nodes with highest nodeid
+ (we want to retain a quorate partition of 3 nodes)
+ start one node again -> cluster will be unquorate
+
+ This happens because the node rebooting/rejoining with
+ non current cluster status will propagate an expected_votes of 8,
+ while in reality the cluster is down to expected_votes: 3.
+
+ 4 nodes are still < 5 (quorum for 8 nodes/votes).
+
+ In order to avoid this condition, we need to exchange expected_votes
+ information among nodes but we cannot randomly trust everybody.
+
+ 1) Allow expected_votes to be changed cluster-wide only if the
+ information is coming from a quorate node.
+ 2) Fix node->expected_votes based on quorate status
+ 3) allow a joining node to decrease quorum and expected_votes
+ if the node is not yet quorate, but it's joining a quorate
+ cluster
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ votequorum: fix auto_tie_breaker design and simplify code a lot
+ auto_tie_breaker requires to know the lowest node id in the currently
+ quorate partition and not of the whole cluster.
+
+ this allow us to determine the lowest node id as soon as we are quorate
+ and remove the complexity to read it from WFA or nodelist. Add
+ the same time it adds the flexibility for dynamic nodeids in a cluster.
+
+ drop requirement on WFA if nodelist is not specified
+
+ update man page
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ votequorum: drop NODESTATE_LEAVING
+ this is another leftover from cman compatibility layer
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2012-01-25 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ update TODO list
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ votequorum: add documentation and man pages
+ fix a few typos on the way and separate config / library bits
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ votequorum: change quorum.expected_votes override behavior
+ as agreed on the mailing list, quorum.expected_votes should override
+ automatically calculated expected_votes from nodelist.
+
+ Also simplify the code to handle expected_votes. "silly defaults" is now
+ unnecessary because votequorum does config sanity checks upfront.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ votequorum: two_node should enable wait_for_all by default
+ This avoids fencing races at startup of a cluster.
+
+ It is still possible to override WFA by explicitly setting
+ wait_for_all: 0
+
+ Reviewed-by: Angus Salkeld <asalkeld@redhat.com>
+
+2012-01-25 Angus Salkeld <asalkeld@redhat.com>
+
+ CTS: make basic tests config-generic
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ CTS: fix starting/stopping of test_agents
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ CTS: tidy up the shutdown of cpg_test_agent
+ it is not neccessary to close the fd and remove it
+ from the mainloop
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ CTS: temp comment out quorum tests
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ CTS: fix quourm command
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ CTS: fix up the formt strings
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ Add debug log messages to corosync for join/leave
+ This is needed by cts.
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ LOG: make sure that debug works to syslog
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+2012-01-24 Jan Friesse <jfriesse@redhat.com>
+
+ totemiba: Remove unused wthread.h include
+ Reviewed-by: Angus Salkeld <asalkeld@redhat.com>
+
+ Make xmlconf in SPEC conditional
+ Reviewed-by: Angus Salkeld <asalkeld@redhat.com>
+
+2012-01-23 Angus Salkeld <asalkeld@redhat.com>
+
+ Change the last references from objctl to cmapctl
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+2012-01-23 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ Update TODO list
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ votequorum: add support for nodelist config bits
+ expected votes is now calculated automatically and quorum.expected_votes
+ can be used to override nodelist calculation. The highest of the two
+ value is used for runtime.
+
+ quorum_votes can be specified either in the node list or in quorum.votes.
+ The node list has priority over global.
+
+ propagate votequorum initalization errors (due to config inconsistencies)
+ back to vsf_quorum.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2012-01-23 Angus Salkeld <asalkeld@redhat.com>
+
+ Remove all unneccessary "\n" from log messages
+ These look ugly, are inconsistently done and just have
+ to be removed later in libqb before calling syslog.
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ Shorten some really long lines in main.c
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ cmap: add a delete with prefix (needed by cts)
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ cmap: change -t and -T around (capital == with prefix)
+ I want to add a prefic delete option and then these will
+ not be consistent.
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ cmap: tweek the usage text
+ 1) It wasn't obvious to me what -b did
+ 2) -a has been removed
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ cmap: add a load option for cts "-p"
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ CTS: convert the test agents to use qb logging
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ CTS: fix the corosync start/stop settings
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ CTS: set the syslog restart commands up correctly
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+2012-01-20 Jan Friesse <jfriesse@redhat.com>
+
+ Add nodelist informations to manual page
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ Make local_node ring0 address read-only
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ Support for dynamic nodelist udpu member change
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ Use nodeid provided in nodelist
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ Support udpu members in nodelist
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ Add local_node_pos icmap key
+ Key contains local node position in nodelist
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ Parse nodelist in coroparse
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+2012-01-19 Jan Friesse <jfriesse@redhat.com>
+
+ mon: Remove leftover print of debug output to err
+ Reviewed-by: Angus Salkeld <asalkeld@redhat.com>
+
+ Set default multicast port if not specified
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+2012-01-19 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ votequorum: drop protocol versioning in favour of extra space on the wire
+ protocol needs to stay compatible across a corosync MAJOR release.
+ Implementing internal protocol version compat is at best suicidal.
+
+ Add extra space to the net struct and we can use flags to determine
+ feature sets.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2012-01-19 Angus Salkeld <asalkeld@redhat.com>
+
+ autobuild: make sure systemd is enabled on f15+
+ Reriewed-by: Steven Dake <sdake@redhat.com>
+
+ autobuild: ssh into node as root
+ Reviewed-by: Steven Dake <sdake@redhat.com
+
+ Fix spec file when passed "--with-testagents"
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ CTS: remove the test service agent
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+2012-01-18 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ votequorum: ifdef qdiskd API out
+ as agreed, the API has not been tested yet. Adding later is better than
+ removing it.
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ votequorum: be slightly more efficent and consistent
+ reduce req_exec_quorum_nodeinfo from 40 to 16 bytes (onwire)
+
+ add 4 bytes to req_exec_quorum_reconfigure to be consisent
+ with feature/version checking (onwire data)
+
+ make all nodeid definition "unsigned int" instead of some random mix.
+
+ reduce size of different vars
+
+ remove lots of unnecessary swab due to reducing size of data
+
+ drop join_time from cluster_node, it's never used
+
+ fix printing of nodeids from random mix to uint for consistency
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2012-01-18 Jan Friesse <jfriesse@redhat.com>
+
+ Update TODO with recent mcast addr changes
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ Store auto generated mcast addr and port to icmap
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ Add cluster_name option
+ Option is used for automatic generating of multicast address. If both
+ cluster_name and mcastaddr options are specified, mcastaddr takes
+ precedence.
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+2012-01-17 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ quorum: fix votequorum service initialization
+ the problem is that votequorum was listed as part of default
+ services.
+
+ At service_link_and_init, votequorum library and exec were being
+ made available, even when votequorum was not in used at all, creating
+ all kind of problems.
+
+ By changing the service_link_and_init to be clever, we restore the
+ original and wanted behavior to link the service only when required.
+
+ This also fixed N*votequorum API calls segfaults, init segfaults
+ and a few dozen other small issues...
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ quorumtool: fix node display regression in monitoring option
+ make display_nodes code common with show_nodes
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ votequorum: fix include to match definition name (cosmetic)
+ Reviewed-by: Angus Salkeld <asalked@redhat.com>
+
+ quorum: integrate votequorum and ykd correctly
+ the problem is mostly in votequorum here, where votequorum_exec is
+ initialized with or without votequorum being configured as quorum
+ provider.
+
+ re-establish init order (regression from dropping lcrso) and make
+ sure we init correctly only the module configured.
+
+ ykd changes are for consistency only at this point in time.
+
+ Reviewed-by: Angus Salkeld <asalked@redhat.com>
+
+ build: fix distcheck regression introduced from ykd binding
+ Reviewed-by: Angus Salkeld <asalked@redhat.com>
+
+ votequorum: fix standalone build
+ Reviewed-by: Angus Salkeld <asalked@redhat.com>
+
+ main: drop unrequired vars
+ Reviewed-by: Angus Salkeld <asalked@redhat.com>
+
+ quorum: link ykd back into quorum and fix build warning
+ Reviewed-by: Angus Salkeld <asalked@redhat.com>
+
+ votequorum: check for parameters and return proper error
+ Reviewed-by: Angus Salkeld <asalked@redhat.com>
+
+ vsf_quorum: fix potential memory leak
+ Reviewed-by: Angus Salkeld <asalked@redhat.com>
+
+ coroparse: fix include path after drop lcrso merge
+ Reviewed-by: Angus Salkeld <asalked@redhat.com>
+
+ update .gitignore
+ Reviewed-by: Angus Salkeld <asalked@redhat.com>
+
+2012-01-17 Steven Dake <sdake@redhat.com>
+
+ Silent a warning from coverity about handle being used without assign
+ Reviewed-by: Angus Salkeld <asalked@redhat.com>
+
+ Silent a warning from coverity about icmap_track being used without assign
+ Reviewed-by: Angus Salkeld <asalked@redhat.com>
+
+ Silent a warning from coverity about icmap_track being used without assign
+ Reviewed-by: Angus Salkeld <asalked@redhat.com>
+
+ Silent a warning from coverity about icmap_track being used without assign
+ Reviewed-by: Angus Salkeld <asalked@redhat.com>
+
+ Silent a coverity warning about a variable being uninit when it actually is
+ Reviewed-by: Angus Salkeld <asalked@redhat.com>
+
+ Silent a coverity warning about handle being unset (when it really is)
+ Reviewed-by: Angus Salkeld <asalked@redhat.com>
+
+ Silent a warning from coverity about icmap_track being used without assign
+ Reviewed-by: Angus Salkeld <asalked@redhat.com>
+
+ Silent a warning from coverity about icmap_track being used without assign
+ Reviewed-by: Angus Salkeld <asalked@redhat.com>
+
+ Silent a warning from coverity about icmap_track being used without assign
+ Reviewed-by: Angus Salkeld <asalked@redhat.com>
+
+ Silent a warning from coverity about icmap_track being used without assign
+ Reviewed-by: Angus Salkeld <asalked@redhat.com>
+
+ Silent a warning from coverity about icmap_track being used without assign
+ Reviewed-by: Angus Salkeld <asalked@redhat.com>
+
+ Silent a warning from coverity about icmap_track being used without assign
+ Reviewed-by: Angus Salkeld <asalked@redhat.com>
+
+ Add break where one was missing
+ Reviewed-by: Angus Salkeld <asalked@redhat.com>
+
+ Remove unchecked coverity error
+ Reviewed-by: Angus Salkeld <asalked@redhat.com>
+
+2012-01-16 Steven Dake <sdake@redhat.com>
+
+ Fix missing rebase problem that causes make rpm to fail
+ Reviewed-by: Fabio Di Nitto <fdinitto@redhat.com>
+
+ Add missing votequorum.h file from previous commit
+ Reviewed-by: Fabio Di Nitto <fdinitto@redhat.com>
+
+ Remove main_get_config_modules since it is no longer needed
+ Reviewed-by: Fabio Di Nitto <fdinitto@redhat.com>
+
+ Finish up quorum integration
+ Reviewed-by: Fabio Di Nitto <fdinitto@redhat.com>
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ Remove some lcr ifdef'ed code in service.c
+ Reviewed-by: Fabio Di Nitto <fdinitto@redhat.com>
+
+ Remove services directory from loc command
+ Reviewed-by: Fabio Di Nitto <fdinitto@redhat.com>
+
+ Get rid of external config loader in include/engine/config.h
+ Reviewed-by: Fabio Di Nitto <fdinitto@redhat.com>
+
+ Remove service.d directory since plugins are gone
+ Reviewed-by: Fabio Di Nitto <fdinitto@redhat.com>
+
+ Remove lcr directory, files, and references since it is no longer needed
+ Reviewed-by: Fabio Di Nitto <fdinitto@redhat.com>
+
+ Initial removal of plugins
+ Quorum is broken in this patch.
+ service.h needs to be cleaned up significantly
+
+ Reviewed-by: Fabio Di Nitto <fdinitto@redhat.com>
+
+ Move cs_error into global header so that third party applications can use it
+ Reviewed-by: Andrew Beekhof <abeekhof@redhat.com>
+
+2012-01-16 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ votequorum: fix name and version
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ votequorum: drop unused define
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ votequorum: rearrange code
+ this commit has no functional changes or bugfixes.
+
+ Simply reorganize the code in more logical way and change function
+ names to be more consistent.
+
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ votequorum/quorum-tools: drop unnecessary includes
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+ votequorum: network data should be packed
+ Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
+
+2012-01-13 Jan Friesse <jfriesse@redhat.com>
+
+ Use fast inc for service statistics
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ icmap: Add fast version of inc and dec operation
+ Biggest difference between fast and standard inc/dec operation is in
+ fast that fast doesn't do malloc/memcpy, but also it means that tracking
+ events doesn't have old value set.
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+2012-01-13 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ Fix spec file to reflect documentation changes
+ Reviewed-by: Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ man: improve index.html a bit
+ add tools/daemon section and developers section
+
+ also add links to other API docs
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ man: sort interfaces alphabetically
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ man: cosmetic index.html changes
+ makes it slightly more consistent and readable
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ man: drop confdb from man pages
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ update TODO list
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ quorum: extend initialize man page
+ add QUORUM_FREE/QUORUM_SET and fix a typo
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ quorum: libquorum API documentation (quorum_getquorate)
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ quorum: libquorum API documentation (quorum_context_set)
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ quorum: libquorum API documentation (quorum_context_get)
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ quorum: libquorum API documentation (quorum_dispatch)
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ quorum: libquorum API documentation (quorum_fd_get)
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ quorum: libquorum API documentation (quorum_finalize)
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ quorum: libquorum API documentation (quorum_initialize)
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ votequorum: update man pages
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ votequorum: lower quorum change logging
+ vfs_quorum already does logging at INFO level
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ update TODO list
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ votequorum: drop votequorum_leave
+ this was a compatibility function for cman_tool only.
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ votequorum: add missing new line
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ votequorum: display flags for all features
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ quorumtool: improve monitoring output some more
+ this avoid printing some static data more than once
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ votequorum: drop HASSTATE/SETSTATE
+ this is a leftover from killing DISALLOWED
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ quorumtool: make data display more generic
+ this improves the monitoring option a ton
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ quorumtool: drop redundant init calls to votequorum
+ this is taken care of in initall
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ quorumtools: update copyright header
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ cmapctl: initialize more variables
+ and kill the last gcc warnings
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ cmapctl: initialize bit_value and check if it's set
+ more gcc warnings...
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ mainconfig: check error return codes from logsys_format_set
+ and avoid yet another gcc warning
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ main: drop unrequired call to totem_get_stats
+ and shut up another gcc warning
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ icmap: make sure variable is initialized
+ shut up gcc warning
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+2012-01-12 Steven Dake <sdake@redhat.com>
+
+ unshare exec/icmap.so
+ Reviewed-by: Fabio Di Nitto <fdinitto@redhat.com>
+
+ Change all ais references to corosync
+ Reviewed-by: Fabio Di Nitto <fdinitto@redhat.com>
+
+2012-01-11 Jan Friesse <jfriesse@redhat.com>
+
+ cmapctl: Print all keys by default
+ Also remove option -a, because there is no need to hide
+ internal_configuration.
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ Update TODO with notifid changes
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ Store rrp faulty status of ring in cmap
+ New key with faulty status of ring is created in cmap as name
+ runtime.totem.pg.mrp.rrp.$ring_number.faulty
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+2012-01-10 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ quorum: more TODO items
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ quorum: update TODO
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ votequorum: fix votes/quorum recalculation in auto_tie_breaker
+ this is necessary when switching from 2 nodes to 1 one in auto_tie_breaker
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ votequorum: improve wait_for_all reset handling when merging parititions
+ this change allow a node to rejoin a cluster that has already seen
+ wait_for_all and reset the flag if the partition that the node is joining
+ is quorate.
+
+ Also propagate current wait_for_all_status and quorate info via nodeinfo.
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ votequorum: fix another regressions introduced by 05b4e99a6e (dispatch notifications only once)
+ left_member_entries is never set when totem config change is regular.
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ votequorum: fix regression introduced by 05b4e99a6e (dispatch notifications only once)
+ Effectively there are 2 kind of quorum notifications that cannot be merged into 1.
+
+ config_change: when the quorum membership changes, triggered by totem/membership changes
+ (node join/leave)
+
+ quorum_status_changes: same membership node becomes quorate or not.
+
+ A quorum status change does not necessarely match a membership change, hence it needs
+ to be dispatched separately.
+
+ An example is a cluster that is not quorate, user changes the amount of votes in a node to
+ regain quorum. No membership changes happen at this point, but votequorum will
+ effectively broadcast the votes: XX change and recalculate quorum.
+ In turn we need to notify quorum users.
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ votequorum: switch two_node from flag to int
+ TWO_NODE was the last flag using quorum_flags.
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ votequorum: drop kill_reason leftovers (part of disallowed)
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ votequorum: missed one comment to cleanup ;)
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ votequorum: clean up coding style
+ first pass to bring votequorum at corosync codying style.
+
+ fix whitespaces, add missing {}, fix comments, be consistent with
+ ENTER/LEAVE usage, be consistent with some functions variable names
+ and some more cosmetic changes
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ votequorum: update copyright/authors
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ votequorum: dispatch notifications only once
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ votequorum: add last_man_standing support (default: off)
+ this flag (0|1) can be configured via quorum.last_man_standing and when
+ enabled, it allows expected_votes to be dynamically recalculated.
+
+ Assuming an 8 nodes cluster, every node votes 1 (mandatory requirement for
+ this feature).
+
+ In the first event, 3 nodes are lost.
+
+ The remaining partition of 5 is barely quorate.
+
+ After a configurable timeout (quorum.last_man_standing_window, default 10sec)
+ the quorate partition is allow to recalculate expected_votes based on
+ the remaining nodes.
+
+ This operation will bring expected_votes to 5 and quorum to 3.
+
+ Repeating the above loop, in the next event, 2 more nodes are allowed to
+ die. etc. etc.
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ votequorum: drop concept of DISALLOWED
+ this is a very old leftover from the RHEL5 timeframe, not used in RHEL6.
+
+ Also change votequorum soname since this change implies an ABI change.
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ quorum: bump soname for libquorum to reflect API change
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ votequorum: fix quorum_flags values
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ votequorum: transmit wait_for_all info in node info message
+ this is necessary to reset the wait_for_all data when a node is joining a cluster
+ that has already seen all nodes once.
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ votequorum: add auto_tie_breaker support (default: off)
+ this flag (0|1) can be configured via quorum.auto_tie_breaker and when
+ enabled, support for perfect even split is on.
+
+ In case of a 50% of votes loss in one single transition, the partition
+ with the node that has the lowest node id will remain quorate.
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ votequorum: add wait_for_all support (default: off)
+ this flag (0|1) can be configured via quorum.wait_for_all and changes
+ behavior when granting quorum for the first time.
+
+ Normal behavior (default / 0) grants quorum as soon as enough nodes
+ are available in a cluster.
+
+ Setting this value to 1 will grant quorum only after all cluster
+ memembers are part of the cluster at the same time.
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ votequorum: always dispatch quorum notifications
+ Resolves: rhbz#768144
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ quorum: change API to return quorum type at initialization time
+ corosync internal theory of operation is that without a quorum provider
+ the cluster is always quorate. This is fine for membership free clusters
+ but it does pose a problem for applications that need membership and
+ "real" quorum.
+
+ this change add quorum_type to quorum_initialize call to return QUORUM_FREE
+ or QUORUM_SET. Applications can then make their own decisions to error out
+ or continue operating.
+
+ The only other way to know if a quorum provider is enabled/configured is
+ to poke at confdb/objdb, but adds an unnecessary burden to applications
+ that really don't need to use an entire library for a boolean value.
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+2012-01-09 Angus Salkeld <asalkeld@redhat.com>
+
+ IPC: don't block forever on a recv msg as corosync might be gone.
+ This at least will not make the client hang forever.
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+2012-01-09 Jan Friesse <jfriesse@redhat.com>
+
+ Add rrp faulty event to notifyd
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ Add usage text to cmapctl
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ Ability to display binary data type in cmapctl
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ Ability to store binary key
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+2012-01-09 Angus Salkeld <asalkeld@redhat.com>
+
+ Fix last corosync/engine/coroapi.h
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+2012-01-08 Steven Dake <sdake@redhat.com>
+
+ Add Requires: libxslt if BUILD_XMLCONF is defined
+ Reviewed-by: Angus Salkled <asalkeld@redhat.com>
+
+ Improve make rpm to work properly
+ Reviewed-by: Fabio Di Nitto <fdinitto@redhat.com>
+
+ Move coroapi out of external headers
+ Reviewed-by: Angus Salkled <asalkeld@redhat.com>
+
+2012-01-07 Steven Dake <sdake@redhat.com>
+
+ Move logsys.c into corosync binary instead of a shared object
+ Our preferred shared logging system is exported via the libqb library. As
+ a result, the corosync project no longer needs to export logsys.so and the
+ code can be directly included in the binary. The header file can also be
+ removed.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ Allow make rpm to complete with recent changes in cmap and xmlproc
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ Fix make dist relating to xmlconf conditional
+ Reviewed-by: Fabio Di Nitto <fdinitto@redhat.com>
+
+2012-01-06 Angus Salkeld <asalkeld@redhat.com>
+
+ Fix some iterator based mem leaks
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+2012-01-06 Steven Dake <sdake@redhat.com>
+
+ Remove libqb issues reference 1 since that isn't really a problem
+
+2012-01-03 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ ipc: make less noise
+ switch from LOG_INFO to LOG_DEBUG for some basic operations
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+2011-12-20 Jan Friesse <jfriesse@redhat.com>
+
+ Add topic-xmlschema to TODO
+ Also topic-xmlconfig is removed.
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ Man pages for corosync-xml
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ Convert xml config file
+ Included are following parts:
+ - XSLT template with actual conversion
+ - simple wrapper on top of xsltproc called corosync-xmlproc
+ - example XML file
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ Remove deprecated options from corosync.conf page
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ Remove deprecated options from conf examples
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ Align --with-snmp in help output
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+2011-12-15 Jan Friesse <jfriesse@redhat.com>
+
+ Updated TODO to reflect cmap inclusion
+
+ Remove objdb and confdb
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ Move wd service to use icmap
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ Move mon service to use icmap
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ Move SAM to use CMAP service
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ Move quorumtool to use cmap service
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ Move notifyd to use cmap service
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ Add cmapctl tool
+ corosync-cmapctl is direct replacement for corosync-objctl
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ Move cfg service to use icmap
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ Move votequorum to use icmap
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ Move testquorum to icmap
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ Move corosync core to use icmap
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ Add user library to use cmap service
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ Add cmap service
+ Cmap service is application developer interface to icmap and it is
+ direct replacement for confdb.
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ Add icmap
+ Icmap is replacement for objdb, based on libqb map (trie).
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+2011-12-15 Angus Salkeld <asalkeld@redhat.com>
+
+ TODO: remove "message/queue size" todo's
+
+ Check for the correct message size in totempg_groups_joined_reserve()
+ Currently:
+ - send_reserve() adds to the reserve
+ - msg_count_send_ok() tests ((avail - totempg_reserved) > msg_count)
+
+ So essentially we are checking to see if 2 * msg_count can fit in
+ the q.
+
+ So instead I am using byte_count_send_ok (size) to see if the
+ message will fit then calling send_reserve()
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ Fix cpgbench (large message sizes)
+ To allow async cpg messages of 1M we need to:
+ 1) increase the totem queue size 4 times
+ 2) align the critical level to one large message free
+
+ There are a number of reasons for doing this:
+
+ We can't let cpg_mcast_joined() fail because the user will not see it
+ and will assume is has succeded.
+
+ The reason we are getting good performance is by providing a negative
+ feedback loop from the totem q to the IPC/poll system. This relies
+ on 4 q states low/med/high/crit. With messages of size 1M you
+ now have a q of size one and now go from level low to crit instantly
+ then back to low as messages are put on and taken off. I don't think
+ this is the best behaviour. By having a q size of 4 allows the system
+ to utilize the q better and give us time to respond to changes in
+ the q level.
+
+ To effectively achieve flow control with a q of size 1 would require
+ all the clients to request the space on the q like is done in
+ totempg_groups_joined_reserve() but probably in shared memory
+ This would take quite a bit of re-work.
+
+ LOG: get the logging to work from loaded quorum modules
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ Tweek the increment in cpgbench so the message size gets to 1M
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+2011-12-14 Angus Salkeld <asalkeld@redhat.com>
+
+ Be more flexible (correct) with flowcontrol.
+ Many functions do not require flowcontrol and are two-way
+ so they can get failures from corosync.
+ Only cpg_mcast_joined() _really_ needs the current level
+ of flowcontrol.
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+2011-12-13 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ quorum-tools: add quorum monitoring option
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ quorum-tool: reduce amount of init/finalize
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ quorum-tools: change internal get_quorum_type
+ don't leak memory, better error reporting and improve
+ status output when there is no quorum configured
+
+ also fix some coding style based on review input
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ quorum-tool: add return codes to show status
+ -1 indicates an error communicating with corosync/quorum/votequorum service
+ 0 node is not quorate
+ 1 node is quorate
+
+ also add more error reporting and a couple of missing calls to finalize
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ quorum-tool: update copyright date
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ quorum-tools: fix options/help text
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+2011-12-13 Angus Salkeld <asalkeld@redhat.com>
+
+ LOG: Fix a crash in the shutdown.
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+2011-12-06 Steven Dake <sdake@redhat.com>
+
+ Change mailing list in configure.ac to discuss@lists.corosync.org
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ Add silent rules to corosync make to more easily find warnings
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2011-12-01 Jan Friesse <jfriesse@redhat.com>
+
+ hdb* functions already returns -error value
+ So it's wrong to define hdb_error_to_cs and pass -error value, because
+ this creates --error = error = CS_OK.
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+2011-11-30 Yunkai Zhang <qiushu.zyk@taobao.com>
+
+ Correct nodeid in memb_state_commit_token_send function
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+2011-11-29 Steven Dake <sdake@redhat.com>
+
+ From: Yunkai Zhang: Today, I have observed one of the reason that corosync running into FAILED TO RECEIVE state.
+ There was five nodes(A,B,C,D,E) in my testing, and I limited the UDP
+ transmission rate of C nodes by iptables command:
+ iptables -A INPUT -i eth0 -p udp -m limit --limit 10000/s
+ --limit-burst 1 -j ACCEPT
+ iptables -A INPUT -i eth0 -p udp -j DROP
+
+ After one hour later, C node had been missing some MCAST messages,
+ it's state described as following:
+ ==state of C node==
+ my_aru:0x805
+ my_high_seq_received:0xC2C
+ my_aru_count:7
+
+ =>receved MCAST message with seq:806 from B nodes
+ =>enter *message_handler_mcast*
+ =>add this message to regular_sort_queue
+ ...
+ =>enter *update_aru* function
+ => range = (my_high_seq_received - my_aru)
+ = (0xC2C - 0x805)
+ = 1063
+ => if range>1024, do nothing and and return directly.
+ ==END==
+
+ According this logic, after (my_high_req_received-my_aru)>1024, my_aru
+ will not be updated though corosync can receive MCAST messages
+ retransmitted by other nodes.
+
+ But at that timte, my_aru_count was only 7. So the corosync at C node
+ would keep in this status until my_aru_count increased to
+ fail_to_recv_const(the default value is 2500). This was a long time
+ for corosync, but we wasted it.
+
+ To solve this issue, maybe we can enlarge the range condition in
+ update_aru function? Or we just ingnore the checking of range value,
+ it seems no harmfull, because we have been using fail_to_recv_const to
+ control the things.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2011-11-28 Yunkai Zhang <qiushu.zyk@taobao.com>
+
+ Correct nodeid of token when we retransmit it
+ Although incorrect nodeid will not affect program's logic, but it will
+ make us confused when we add some logs to record the transmission path of
+ token in debug mode.
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+2011-11-26 Yunkai Zhang <qiushu.zyk@taobao.com>
+
+ Fixed bug when corosync receive JoinMSG in OPERATIONAL state
+ Accordig the totem protocal, nodes should enter GATHER state when it
+ receive JoinMSG in OPERATIONAL state. If we discard it in OPERATIONAL
+ state, the nodes sending this JoinMSG could not receive the response
+ untill other nodes reach token lost timeout.
+
+ This bug will cause nodes having entered GATHER state spend more time to
+ rejoin the ring, and then it will make nodes reach token expired timeout
+ more easily.
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+2011-11-26 Steven Dake <sdake@redhat.com>
+
+ Remove unchecked return error in test code
+
+ Remove unused variable from latest cpg work that merged all config changes Signed-off-by: Steven Dake <sdake@redhat.com>
+
+ Remove unchecked return problem in test code
+
+ Remove unchecked return warning
+
+ Remove use of NULL in test agent
+
+ Remove unchecked return error
+
+ Correct typing in memory_map function in lib/cpg.c
+
+2011-11-14 Angus Salkeld <asalkeld@redhat.com>
+
+ Fix last warnings so we can build with --enable-fatal-warnings
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+2011-11-10 Angus Salkeld <asalkeld@redhat.com>
+
+ TOTEM: better clean up on exit
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ OBJDB: free up resources on exit
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ LOG: cleanup logging resources at exit
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ Clean up the poll loop resourses on exit
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ Add calls to missing object_find_destroy() to fix mem leaks
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ Free mem allocated by getaddrinfo
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+2011-10-31 Yunkai Zhang <qiushu.zyk@taobao.com>
+
+ Send one confchg event per CPG group to CPG client
+ We found that sheepdog will receive more than one confchg msg when
+ network partition occur. For example, suppose the cluster has 4
+ nodes: N1, N2, N3, N4, and they form a single-ring initially. After a
+ while, network partition occur, the single-ring divide into two
+ sub-ring: ring(N1, N2, N3) and ring(N4). The sheepdog in the ring(N4)
+ will receive the following confchg messages in turn:
+ Memb: N2,N3,N4 Left:N1 Joined:null
+ memb: N3,N4 Left:N2 Joined:null
+ memb: N4 Left:N3 Joined:null
+
+ This patch will fixed this bug, and the client will only receive one
+ confchg event in this case:
+ memb: N4 Left:N1,N2,N3 Joined:null
+
+ Reviewed-by: Angus Salkeld <asalkeld@redhat.com>
+
+2011-10-28 Anton Jouline <anton.jouline@cbsinteractive.com>
+
+ Adding support for dynamic membership with UDPU transport
+ Add a new object called totem.interface.dynamic to allow creation/deletion
+ of new child objects using the corosync-objctl utility:
+
+ to add new member:
+ linux# corosync-objctl -c totem.interface.dynamic.10-211-55-12
+
+ to delete an existing member:
+ linux# corosync-objctl -d totem.interface.dynamic.10-211-55-12
+
+ Corosync will dynamically add these members to the configuration and start
+ communicating with those nodes.
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+2011-10-25 Jan Friesse <jfriesse@redhat.com>
+
+ Remove unused buf and len variables in log_printf
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+2011-10-24 Jan Friesse <jfriesse@redhat.com>
+
+ api: Change some of totempg definitons
+ Recent changes in patch "Get rid of hdb usage in totempg.h interface"
+ caused incompatibility between corosync API and totempg.
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ totemmrp: Allow compilation without warnings
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ Allow compilation of totempg without warnings
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ logsys.h: Properly define LEAVE macro
+ Reviewed-by: Angus Salkeld <asalkeld@redhat.com>
+
+2011-10-22 Angus Salkeld <asalkeld@redhat.com>
+
+ Set the size of the blackbox to the size on flatiron
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ CTS: remove dead code in sam_test_agent
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ don't log an error if exiting with 0
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ LOG: update the log defines
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+2011-10-21 Steven Dake <sdake@redhat.com>
+
+ add wait-for-license to cov-analyze
+ Reviewed-by: Angus Salkeld <asalkeld@redhat.com>
+
+ res could return an undefined value if there was no error in totempg_groups_initialize
+ Reviewed-by: Angus Salkeld <asalkeld@redhat.com>
+
+ Remove default from cpg_model_initialize - atm there is only one model
+ Reviewed-by: Angus Salkeld <asalkeld@redhat.com>
+
+ Remove dead code in evs service
+ Reviewed-by: Angus Salkeld <asalkeld@redhat.com>
+
+ Remove dead code in votequorum
+ Reviewed-by: Angus Salkeld <asalkeld@redhat.com>
+
+2011-10-21 Angus Salkeld <asalkeld@redhat.com>
+
+ TEST: make cpgbench go to 1M
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ Remove references to README.devmap
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+2011-10-21 Steven Dake <sdake@redhat.com>
+
+ Remove dead code in cfg.c
+
+2011-10-21 Angus Salkeld <asalkeld@redhat.com>
+
+ Remove old README.devmap
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ MAN: remove unused man pages
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ LOG: use libqb facility conversion functions
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ LOG: get logging to file working correctly
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ LOG: Fix debugging
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+2011-10-20 Steven Dake <sdake@redhat.com>
+
+ Updated TODO with feedback from community defining our Needle 2.0/2.1 goals
+ Revieweed-by: Jan Friesse <jfriesse@redhat.com>
+
+ Add --concurrency to coverity make target
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2011-10-10 Masatake YAMATO <yamato@redhat.com>
+
+ Remove cloned lines in main of main.c
+
+2011-09-22 Steven Dake <sdake@redhat.com>
+
+ Deliver all messages from my_high_seq_recieved to the last gap
+ This patch passes two test cases:
+
+ -------
+ Test #1
+ -------
+ Two node cluster - run cpgbench on each node
+
+ modify totemsrp with following defines:
+ Two test cases:
+
+ -------
+ Test #2
+ -------
+ 5 node cluster
+
+ start 5 nodes randomly at about same time, start 5 nodes randomly at about
+ same time, wait 10 seconds and attempt to send a message. If message blocks
+ on "TRY_AGAIN" likely a message loss has occured. Wait a few minutes without
+ cyclng the nodes and see if the TRY_AGAIN state becomes unblocked.
+
+ If it doesn't the test case has failed
+
+ Reviewed-by: Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2011-09-08 Jan Friesse <jfriesse@redhat.com>
+
+ totemconfig: change minimum RRP threshold
+ RRP threshold can be lower value then 5.
+
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+2011-09-05 Steven Dake <sdake@redhat.com>
+
+ Allow conditional rpmbuilds of NSS feature
+ NSS is currently non-conditional. Allow nss to be build conditonally.
+
+ Reviewed-by: Angus Salkeld <asalked@redhat.com>
+
+2011-09-02 Steven Dake <sdake@redhat.com>
+
+ Ignore memb_join messages during flush operations
+ a memb_join operation that occurs during flushing can result in an
+ entry into the GATHER state from the RECOVERY state. This results in the
+ regular sort queue being used instead of the recovery sort queue, resulting
+ in segfault.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2011-09-01 Jan Friesse <jfriesse@redhat.com>
+
+ rrp: Higher threshold in passive mode for mcast
+ There were too much false positives with passive mode rrp when high
+ number of messages were received.
+
+ Patch adds new configurable variable rrp_problem_count_mcast_threshold
+ which is by default 10 times rrp_problem_count_threshold and this is
+ used as threshold for multicast packets in passive mode. Variable is
+ unused in active mode.
+
+ Reviewed by: Steven Dake <sdake@redhat.com>
+
+ rrp: Handle endless loop if all ifaces are faulty
+ If all interfaces were faulty, passive_mcast_flush_send and related
+ functions ended in endless loop. This is now handled and if there is no
+ live interface, message is dropped.
+
+ Reviewed by: Steven Dake <sdake@redhat.com>
+
+2011-08-24 Steven Dake <sdake@redhat.com>
+
+ Get rid of hdb usage in totempg.h interface
+ hdb has some expense and is not necessary in the totempg.so runtime. This
+ patch removes the dependence on hdb and instead uses a direct pointer.
+
+ Reviewed-by: Angus Salkeld <asalkeld@redhat.com>
+
+ Remove hdb.h header includes from unnecessary files
+ The files in this patch do not use the hdb.h header.
+
+ Reviewed-by: Angus Salkeld <asalkeld@redhat.com>
+
+2011-08-23 Steven Dake <sdake@redhat.com>
+
+ Use qb_hdb instead of mutex based hdb code
+ Rid ourselves of the mutex usage still in the code base
+
+ Reviewed-by: Angus Salkeld <asalkeld@redhat.com>
+
+ Add totempg_threaded_mode_enable() api
+ This API allows totem to operate as a multithreaded library. Performance is
+ better without threads but some library users may only have multithreaded
+ systems. In the corosync case where we have removed threads, this reduces
+ cpu utilization by ~10% by removing about 50% of the mutex lock and unlock calls
+ that occur during typical operation. Since the latest corosync is nearly
+ thread free, there is no need for mutex operations.
+
+ Reviewed-by: Angus Salkeld <asalkeld@redhat.com>
+
+ Move cs_queue.h from include directory to exec directory
+ This file is only used by totemsrp.c. Move out of general include
+ directory.
+
+ Reviewed-by: Angus Salkeld <asalkeld@redhat.com>
+
+ use va version of external log function
+ This removes a sprintf operation in the totem and ipc logging operations
+
+ Reviewed-by: Angus Salkeld <asalkeld@redhat.com>
+
+2011-08-18 Tim Beale <tim.beale@alliedtelesis.co.nz>
+
+ A CPG client can sometimes lockup if the local node is in the downlist
+ In a 10-node cluster where all nodes are booting up and starting corosync
+ at the same time, sometimes during this process corosync detects a node as
+ leaving and rejoining the cluster.
+
+ Occasionally the downlist that gets picked contains the local node. When the
+ local node sends leave events for the downlist (including itself), it sets
+ its cpd state to CPD_STATE_UNJOINED and clears the cpd->group_name. This
+ means it no longer sends CPG events to the CPG client.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2011-08-17 Tim Beale <tim.beale@alliedtelesis.co.nz>
+
+ Display ring-ID consistently in debug
+ Ring ID was being displayed both as hex and decimal in places. Update so
+ it's displayed consistently (I chose hex) to make debugging easier.
+
+ Reviewed-by: Angus Salkeld <asalkeld@redhat.com>
+
+ Add code comment mapping for message handler defines
+ As a corosync-newbie it can be hard to bridge the gap between where a
+ particular message is sent and where the receive handler processes it,
+ and vice versa.
+
+ Reviewed-by: Angus Salkeld <asalkeld@redhat.com>
+
+2011-08-15 Steven Dake <sdake@redhat.com>
+
+ Remove -lcoroipcc from tools/Makefile.am notifyd
+ Reviewed-by: Angus Salkeld <asalkeld@redhat.com>
+
+ properly define rec_token_cq_send_event_fn
+ Reviewed-by: Angus Salkeld <asalkeld@redhat.com>
+
+ Define totemiba_log_printf properly
+ Reviewed-by: Angus Salkeld <asalkeld@redhat.com>
+
+ Fix problem in totemiba where incorrect define is used (and also not defined)
+ Reviewed-by: Angus Salkeld <asalkeld@redhat.com>
+
+2011-08-09 Jan Friesse <jfriesse@redhat.com>
+
+ Allow compile master on RHEL 6
+ corosync_timer_handle_t is know conditionally defined to prevent double
+ definition causing compile fault on RHEL 6 systems.
+
+ Reviewed-by: Angus Salkeld <asalkeld@redhat.com>
+
+2011-08-09 Angus Salkeld <asalkeld@redhat.com>
+
+ Make realtime scheduling optional not the default.
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ Update TODOs
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ libqb: logging & trace
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ libqb: Add libqb dependency in the rpm & pc file
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ Fix some compiler warnings
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ Use PATH_MAX for file path size
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ libqb: Improve IPC dispatch and async handling
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ CPG: downgrade some log messages
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ CTS: make test agent shutdown more gracefully
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ CTS: add an audit to check for leaking shared memory
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ CTS: get GenStopAllBeekhof working a bit better
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ CTS: log bind() errors better
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ CTS: log cfg results
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ CTS: rename flatiron to needle
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ CTS: add exit handler to test_agents
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ CTS: add "Too many open files" to the BadNews pattern
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ CTS: impove debug during msgSend test
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ CTS: add logging to test agent
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ CTS: increse wait for node to reboot
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ CTS: support new pacemaker-cts
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ AUGEAS: fix "tags" log field
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ TEST: fix the print out when cpg_finalize() fails
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ libqb: use the new cs_strerror() to print out the error message.
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ libqb: fix iov_len in pcmk_test
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ libqb: fix valgring warnings in mon/wd
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ libqb: change pause_timestamp to uint64_t
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ libqb: rip out objdb & serialize locks
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ libqb: only init IPC on service engines that need it.
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ libqb: remove the lib init/exit from the test service agent
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ libqb: use the main loop to shutdown
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ libqb: remove tsafe.c
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ libqb: remove worker thread - keep to one thread.
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ libqb: make timer api a wrapper around qb_loop timers.
+ - change timeout value to nano seconds
+ - fix timer handles (don't alloc on stack)
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ libqb: change ipc -> qb_ipc
+ IPC: return 0/-ENOBUFS from message handler
+ IPC: use the new rate_limit API to improve perf.
+ CPG: add send_async API & hook up flow control
+ IPC: Fix flow control getting stuck.
+ IPC: Port the remaining libs to use libqb IPC
+ IPC: remove libqb flowcontrol API
+ TEST: put cpg_dispatch() in it's own thread
+ IPC: cleanup ipc_glue.c name everything cs_ipcs_*()
+ IPC: add back statistics
+ IPC: remove coroipcc_ symbols from lib*.versions
+ IPC: init each se's IPC as it is loaded.
+ IPC: use the new connection_closed() event to free the context.
+ IPC: re-add zero copy functionality back
+ IPC: remove cpg_mcast_joined_async() and make it the default
+ -> now cpg_mcast_joined() == cpg_mcast_joined_async()
+ libqb: expose a libqb error converter
+ libqb: add missing error conversions
+ libqb: remove repeat try loop in lib/cpg.c
+ CPG: fix zero copy mcast
+ CPG: use newer return codes
+ Add ENOTCONN to qb_to_cs_error()
+ libqb: fix error conversion from errno to cs_error_t in confdb
+ libqb: change errno_to_cs to qb_to_cs_error
+ libqb: add a cs_strerror() to get a more meaningful message
+ libqb: fix some confusing error conversions.
+ libqb: set the timeout on recv's to -1 (wait forever)
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ libqb: convert coropoll calls to qb_loop calls.
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ Add systemd unit files for corosync and corosync-notifyd
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+2011-08-07 Florian Haas <florian.haas@linbit.com>
+
+ corosync.conf.example: add note about host addresses in bindnetaddr
+ https://lists.linux-foundation.org/pipermail/openais/2011-July/016563.html
+
+ Jan Friesse pointed out that bindnetaddr should be set to a host
+ address (as opposed to a network address) on hosts where multiple
+ NICs live on the same subnet. Add a comment to that effect to
+ the example configuration file.
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ corosync.conf.example: include comments
+ It's nice to say people should read the man page. It's also naive to
+ assume that they always do. Include comments in the example config
+ file itself.
+
+ Reviewed-by: Dan Frincu <dan.frincu@1and1.ro>
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ corosync.conf.example: change mcastaddr
+ Change suggested mcastaddr to one in the 239.255.0.0/16
+ pseudo-subnet. Multicast addresses outside 239.x.x.x may be IANA
+ registered and can clash with other services present on the
+ network. Suggest an address defined as part of the multicast IPv4
+ Local Scope in RFC 2365.
+
+ Reviewed-by: Dan Frincu <dan.frincu@1and1.ro>
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ corosync.conf.example: change bindnetaddr
+ Change the example configuration file so "bindnetaddr" has a value
+ that more obviously looks like a network address. So as not to have
+ people think they need to set an existing IP address here (and hence,
+ have non-identical corosync.conf files between nodes).
+
+ Reviewed-by: Dan Frincu <dan.frincu@1and1.ro>
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+2011-07-26 Jan Friesse <jfriesse@redhat.com>
+
+ main: let poll really stop before totempg_finalize
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ Revert "totemsrp: Remove recv_flush code"
+ This reverts commit 1a7b7a39f445be63c697170c1680eeca9834de39.
+
+ Reversion is needed to remove overflow of receive buffers and dropping
+ messages.
+
+2011-07-24 MORITA Kazutaka <morita.kazutaka@lab.ntt.co.jp>
+
+ totemsrp: fix buffer overflows for large clusters (> 100 nodes)
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+2011-07-21 Jan Friesse <jfriesse@redhat.com>
+
+ specfile: Install corosync-signals.conf for dbus
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ specfile: use _datadir as var expansion not exec
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ specfile: Correct URL and source0
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+2011-07-19 Tim Beale <tim.beale@alliedtelesis.co.nz>
+
+ Add some more stats for debugging
+ + overload - number of times client is told to try again
+ + invalid_request - message contained invalid paramter, e.g. invalid size
+ + msg_queue_avail - messages currently available at the Totem layer
+ + msg-queue_reserved - messages currently reserved at the Totem layer
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+2011-07-18 Jan Friesse <jfriesse@redhat.com>
+
+ rrp: Handle rollower in passive rrp properly
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ rrp: handle rollover in active rrp properly
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ totemconfig: Change default FAIL_TO_RECV_CONST
+ Previous default (50) was too low for most modern switch hardware. This
+ may trigger abort because the aru doesn't increase for 50 token
+ rotations combined with a defect in how failed to recv conditions are
+ handled. By increasing this tunable, the condition should no longer
+ trigger the errant code.
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+2011-07-15 Steven Dake <sdake@redhat.com>
+
+ Correct missing poll funtions from service handler struct needed for confdb APIs
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ Fix problem where corosync will segfault if there are gaps in recovery queue
+ Fixes a problem where there are gaps in the recovery queue. Example my_aru = 5,
+ but there are messages at 7,8. 8 = my_high_seq_received which results
+ in data slots taken up in new message queue. What should really happen
+ is these last messages should be delivered after a transitional
+ configuration to maintain SAFE agreement. We don't have support for
+ SAFE atm, so it is probably safe just to throw these messages away. Without
+ this change, the new message queue on a new configuraton change is out of sync.
+
+ Tested-by: Tim Beale <tlbeale@gmail.com>
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2011-07-08 Jan Friesse <jfriesse@redhat.com>
+
+ totemiba: free send_buf on ibv_reg_mr failure
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+2011-07-06 Florian Haas <florian.haas@linbit.com>
+
+ build: disable RDMA support in RPMs by default
+ Rather than curiously disable RDMA support by default in configure and
+ enable it by default in RPM builds, streamline the default
+ configuration to always turn RDMA support off. It can be enabled in
+ RPM builds with "--with rdma".
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ build: set RDMA related _LIBS and _CFLAGS only if building with RDMA support
+ Having to force {ibverbs,rdmacm}_{LIBS,CFLAGS} looks positively odd;
+ so this may warrant further review. However, they are definitely not
+ needed if building without RDMA support.
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ build: make RDMA support an RPM build conditional
+ Enable RDMA in RPM builds by default to maintain the previous behavior
+ (which always included --enable-rdma in the %configure invocation).
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ build: force LC_ALL=C correctly for dates
+ Failure to force "C" dates will have RPM et al. complain about invalid
+ dates and timestamps.
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+2011-07-06 Tim Beale <tim.beale@alliedtelesis.co.nz>
+
+ Fix compile/runtime issues for _POSIX_THREAD_PROCESS_SHARED < 1
+ For the case where _POSIX_THREAD_PROCESS_SHARED < 1, the code doesn't compile
+ for corosync v1.3.1. And when it does compile, it crashes on our system - our
+ version of uClibc seems to always expect a 4th arg. The man pages suggests
+ the 4th arg is optional, but does say: 'For greater portability it is best to
+ always call semctl() with four arguments', which is what this patch does.
+ Also removed semop as it's an unused variable.
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ getpwnam_r()/getgrnam_r() returns ERANGE for some systems
+ On our system the expected buffer length is 256. This means calls to
+ getpwnam_r()/getgrnam_r() return ERANGE error and corosync fails to startup.
+ These 2 functions return ERANGE when insufficient buffer space is supplied.
+ Judging by the man page for getpwnam_r, the correct way to determine the
+ buffersize on any given system is to use sysconf().
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+2011-07-05 Jiaju Zhang <jjzhang.linux@gmail.com>
+
+ RRP: redundant ring automatic recovery
+ This patch automatically recovers redundant ring failures.
+
+ Please note that this patch introduced rrp_autorecovery_check_timeout
+ in totem config hence breaks internal ABI. The internal ABI users
+ of totem.h need to rebuild their binaries.
+
+ Tested-by: Jan Friesse <jfriesse@redhat.com>
+ Tested-by: Florian Haas <florian.haas@linbit.com>
+ Tested-by: Jiaju Zhang <jjzhang@suse.de>
+
+2011-07-04 Tim Serong <tserong@novell.com>
+
+ Correct mailing list address in corosync_overview manpage
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+2011-06-29 Masatake YAMATO <yamato@redhat.com>
+
+ fix typos in cpg_mcast_joined.3 and cpg_zcb_mcast_joined.3
+
+2011-06-29 Steven Dake <sdake@redhat.com>
+
+ Add coverity target to corosync makefile.am
+ Allow a make coverity target for those developers with coverity tools
+ available to them.
+
+ Reviewed-by: Angus Salkeld <asalkeld@redhat.com>
+
+2011-06-29 Jan Friesse <jfriesse@redhat.com>
+
+ coroipcc: Test _SC_PAGESIZE result
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ Remove spinlocks
+ Spinlocks are now removed, because even spinlock can improve
+ speed is some special cases, in most cases it makes corosync CPU usage
+ much more intensive and less responsive then if only mutexes are used.
+
+ What we were doing is:
+ pthread_mutex_lock
+ pthread_spin_lock
+ pthread_spin_unlock
+ pthread_mutex_unlock
+
+ what is not safe.
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ votequorum: free newly allocated node if nodeid==0
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+2011-06-28 Jerome Flesch <jerome.flesch@netasq.com>
+
+ Fix usage of strerror_r()/perror()
+ Reviewed-by: Angus Salkeld <asalkeld@redhat.com>
+
+2011-06-23 Steven Dake <sdake@redhat.com>
+
+ sched_params log message incorrect
+ The sched_params parameter was set before being printed.
+
+ Reviewed-by: <sdake@redhat.com>
+
+2011-06-22 Jan Friesse <jfriesse@redhat.com>
+
+ configure.ac: Align --enable-* options description
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ configure.ac: change edefault to default
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ CTS: Test for confdb dispatch deadlock
+ Test is disabled by default because it depends on SMP and about 2GB RAM.
+ It's also testing race, so test is unreliable.
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ confdb: Resolve dispatch deadlock
+ Following situation could happen:
+ - one thread is waiting for finish write operation (line 853), objdb is
+ locked
+ - flush (done in objdb_notify_dispatch) is called in main thread, but
+ this call will never appear because main thread is waiting for objdb
+ lock.
+
+ In this situation deadlock appears.
+
+ Commit solves this by:
+ - setting pipe to non-blocking mode
+ - pipe is used only as trigger for coropoll
+ - dispatch messages are stored in list
+ - main thread is processing messages from list
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ objdb: save copy of handles in object_find_create
+ Following situation could happen:
+ - process 1 thru confdb creates find handle
+ - calls find iteration once
+ - different process 2 deletes object pointed by process 1 iterator
+ - process 1 calls iteration again ->
+ object_find_instance->find_child_list is invalid pointer
+
+ -> segfault
+
+ Now object_find_create creates array of matching object handlers and
+ object_find_next uses that array together with check for name. This
+ prevents situation where between steps 2 and 3 new object is created
+ with different name but sadly with same handle.
+
+ Also good to note that this patch is more or less quick hack rather
+ then proper solution. Real proper solution is to not use pointers
+ and rather use handles everywhere. This is big TODO.
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+2011-06-17 Jiaju Zhang <jjzhang.linux@gmail.com>
+
+ RRP: Fix ring initialization issue for UDPU mode
+ Redundant ring has some problem in the UDP unicast mode. The problem
+ is the second ring has not been successfully initialized, that is, the
+ second time iface_changes happens, the member list for that interface
+ has not been added, which results in that ring cannot transmit normal
+ message. So the second ring cannot take over the work if the first
+ ring is down. This patch fixes this issue.
+
+ comments from review:
+ More work is needed probably in totemnet where totemnet maintains the
+ the of node list and an iterator for them, and totemudpu_member_add adds
+ state information to a context for the iteration.
+
+ In any regard, that is somewhat difficult to test, so I'll merge this
+ patch for now - keep in mind interface changes on the bindnetaddr will
+ cause problems with udpu after this patch has been commmitted.
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+2011-06-10 Jan Friesse <jfriesse@redhat.com>
+
+ coroipcc: check recvmsg result in socket_recv
+ According specification recvmsg can return 0, which means that
+ connection is closed. We had this check, but limited only for systems
+ other then Linux. recvmsg can return 0 even on Linux, so check is now
+ applied on all systems.
+
+ Reviewed-by: Angus Salkeld <asalkeld@redhat.com>
+
+ confdb: Properly check result of object_find_create
+ in confdb_object_iter result of object_find_create is now properly
+ checked. object_find_create can return -1 if object doesn't exists.
+ Without this check, incorrect handle (memory garbage) was directly
+ passed to object_find_next.
+
+ Reviewed-by: Angus Salkeld <asalkeld@redhat.com>
+
+ crypto: rng_make_prng prevent buf overflow
+ with bits set to 1023, buf of 256 bytes was filled by rng_get_bytes
+ up to 257 bytes. Buf is now 258 bytes so it's no longer problem.
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+2011-06-06 Jan Friesse <jfriesse@redhat.com>
+
+ mainconfig: Check retval of logsys_format_set
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+2011-06-03 Jan Friesse <jfriesse@redhat.com>
+
+ testcpgzc: fgets buffer to really allocated size
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ cpg: do_proc_join change list_slice to list_add
+ In this concrete case result is equivalent but makes coverity happy.
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ totemudp: memset of proper size
+ In totemudp_mcast_thread_state_constructor memset to
+ sizeof(struct totemudp_mcast_thread_state) instead of size of
+ pointer.
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ coroipcs: init buf in coroipcs_handler_dispatch
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ coroparse: don't leak dirent
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ logsys: _logsys_wthread_create never returns != 0
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ notifyd: Check retval of corosync_cfg_initialize
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ totemconfig: discard check of objdb_get_string ret
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ coroipcc: proper path size in coroipcc_zcb_alloc
+ memory_map function internally limits maximum path size to
+ PATH_MAX but coroipcc_zcb_alloc passed smaller buffer.
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ libquorum: memset/memcpy proper size of callbacks
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+2011-05-30 Jan Friesse <jfriesse@redhat.com>
+
+ iazc: Reduce number of mem alloc and memcpy
+ X86 processors are able to handle unaligned memory access. Improve
+ performance by using that feature on i386 and x86_64 compatible
+ processors, and use old aligning code on different processors.
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+2011-05-27 Jerome Flesch <jerome.flesch@netasq.com>
+
+ logsys: When corosync is compiled with --enable-small-memory-footprint, also reduce the size of the logsys SHM
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ coroipcc_dispatch_get(): Fix --enable-small-memory-footprint support
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ coroipcs_handler_dispatch(): Fix conn_info->service security value: -1 is not a good security value since it's equal to SOCKET_SERVICE_INIT
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ coroipcc: Fix unhandled BSD EOF in coroipcc_dispatch_get()
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ Corosync: Fix build when done with --enable-fatal-warnings
+ Reviewed-by: Jan Friesse<jfriesse@redhat.com>
+
+2011-05-08 Russell Bryant <russell@russellbryant.net>
+
+ logsys.c: Use snprintf() instead of sprintf().
+ Change a couple of string functions to use the the output length
+ limiting counterpart.
+
+2011-05-13 Jan Friesse <jfriesse@redhat.com>
+
+ corosync-objctl: Option to display binary data
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+2011-05-05 Angus Salkeld <asalkeld@redhat.com>
+
+ cpg: fix sync master selection when one node paused.
+ If one node is paused it can miss a config change and
+ thus report a larger old_members than expected.
+
+ The solution is to use the left_nodes field.
+
+ Master selection used to be "choose node with":
+ 1) largest previous membership
+ 2) (then as a tie-breaker) node with smallest nodeid
+
+ New selection:
+ 1) largest (previous #nodes - #nodes know to have left)
+ 2) (then as a tie-breaker) node with smallest nodeid
+
+ CTS: fix some tests that didn't handle been called more than one
+
+ CTS: sort the configuration - prevent duplicates in the config file
+
+ CTS: fix syntax error in log message
+
+ CTS: bump up log messages of failed RPC
+
+ CTS: don't force all-once (breaks random tests)
+
+ autobuild: improve messages
+
+ CTS: add -l to keygen (normal keygen struggles to run on VMs)
+
+ CTS: send with correct number of iovecs
+ Else payload won't be sent
+
+ CTS: timer should not be on the stack
+
+2011-05-05 Jan Friesse <jfriesse@redhat.com>
+
+ totemsrp: Enhance mcast failure detection
+ memb_state_gather_enter increase stats.continuous_gather only if
+ previous state was gather also. This should happen only if multicast is
+ not working properly (local firewall in most cases) and not if many
+ nodes joins at one time.
+
+ Reviewed-by: Angus Salkeld <asalkeld@redhat.com>
+
+2011-04-15 Jan Friesse <jfriesse@redhat.com>
+
+ coroipcs: Deny connect to service without initfn
+ If library connect to service with no init function, coroipcs will try
+ to dereference NULL pointer. Now we correctly return error code
+ CS_ERR_NOT_EXIST.
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+2011-04-15 Tim Serong <tserong@novell.com>
+
+ Add ipc_refcnt to message_handler_req_{exec, lib}_cfg_ringreenable()
+ Without refcounting the conn pointer here, corosync will segfault
+ if one kills a running instance of "corosync-cfgtool -r" (rhbz#695191)
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+2011-04-15 Steven Dake <sdake@redhat.com>
+
+ Align ipc on 8 byte boundaries
+ Align all ipc messages on 8 byte boundaries. This alignment will remove bus
+ errors on systems that can't access non-byte aligned data and should improve
+ performance.
+
+ Reviewed-by: Angus Salkeld <asalkeld@redhat.com>
+
+ Fix problem where unaligned totemip address access would result in bus error on non-unaligned-safe architectures.
+ Reviewed-by: Angus Salkeld <asalkeld@redhat.com>
+
+2011-04-15 Greg Walton <corosync@gwalton.net>
+
+ Clean up ENDIAN ifdef tests
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+2011-04-11 Tim Serong <tserong@novell.com>
+
+ Fix tyop in RRP faulty error messages
+ Reviewed-by: Russell Bryant <russell@russellbryant.net>
+
+2011-04-13 Angus Salkeld <asalkeld@redhat.com>
+
+ IPC: place calls to stats functions outside of mutexes
+ This is to prevent nasty deadlocks between IPC and objdb.
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+2011-04-12 Zane Bitter <zane.bitter@gmail.com>
+
+ Provide better checking of the message type
+ A negative value for the message type (on systems where char is signed)
+ would cause a crash. This is highly probable if the cluster is, for example,
+ misconfigured to have encryption enabled on some nodes but not others.
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+2011-04-08 Zane Bitter <zane.bitter@gmail.com>
+
+ Fix uninitialised memory errors found by valgrind
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+2011-03-29 Angus Salkeld <asalkeld@redhat.com>
+
+ Fix shutdown when a confdb client is still connected
+ If you are connected to corosync and registered for
+ object notifications then corosync is asked to shutdown
+ the IPC server will get stuck. This is because the pipe
+ is closed and the refcount is increased. This leaves ipcs
+ with a connection that it can't destroy.
+
+ Solution:
+ 1) if a write to the pipe fails (pipe closed) decrement the refcounter.
+ 2) fix the object_track_stop() - it was not working as the functions
+ did not match up. (this caused the late callbacks).
+ 3) in ipcs call exit_fn() then stats_destroy_connection() so that
+ the service engine can have time to call object_track_stop()
+ before the object gets destroyed.
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ STATS: add the service name to the connection name.
+ This helps to quickly identify what service the application
+ is connected to.
+
+ The object will now look like:
+ runtime.connections.corosync-objctl:CONFDB:19654:13.service_id=11
+ runtime.connections.corosync-objctl:CONFDB:19654:13.client_pid=19654
+ etc...
+
+ This also makes it clearer to receivers of the dbus/snmp events
+ what is going on.
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ NOTIFYD: prevent duplicate quorate events.
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ NOTIFYD: fix retrieving the application's parent name.
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+2011-03-24 Jan Friesse <jfriesse@redhat.com>
+
+ cfgtool: print list of IP with space between items
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ cpgtool: print list of IP with space between items
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ cfg_get_node_addrs: Return correct addresses
+ Zero element array behavior is very different from normal array or
+ pointer. This behavior is root of problem in not returning correctly
+ filled array of addresses. This appeared only in rrp mode, where more
+ then one address is returned.
+
+ All memcpy's are now correctly converted to copy pointer to char.
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+2011-03-24 Steven Dake <sdake@redhat.com>
+
+ totemsrp: free messages originated in recovery rather then rely on messages_free
+ Relying on messages_free may seem like it should work, but it leads to a
+ situation where every node has released the messages, yet some nodes think
+ messages are missing. The output then looks like "Retransmit: #" in
+ repitition. This patch frees those messages immediately during the transition
+ to the OPERATIONAL state and sets the internal variables totemsrp depends
+ upon to the proper values.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ totemsrp: Only restore old ring id information one time
+ The current code stores the current ring information every time a commit
+ token is generated. This causes the old ring id used for comparison purposes
+ to increase if a token is lost in commit or recovery, resulting in failure of
+ totem. This patch changes the behavior to only store the old ring id one
+ time when the commit token is received, and then further commit token ring
+ id saves are not done until OPERATIONAL is reached.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+ totemsrp: Remove recv_flush code
+ The recv_flush code is no longer necessary because of the miss_count_count
+ addition. It can in some cases lead to register corruption because of
+ interactions with -fstack-protector, the recursive nature of how this code
+ works, and interactions with the optimizer in some versions of gcc.
+
+ Reviewed-by: Jan Friesse <jfriesse@redhat.com>
+
+2011-03-23 Angus Salkeld <asalkeld@redhat.com>
+
+ confdb: send notifications from the main thread not IPC thread
+ corosync-notifyd has exposed an issue with confdb notifications.
+
+ The normal state of affairs is:
+ IPC thread > lock > objdb > lock
+
+ objdb notification whilst really useful turn things around:
+ <middle of big call chain>
+ objdb > lock > confdb > ipc > lock
+
+ This reverse ordering of locks causes a horrible dead lock.
+
+ I see this patch as a work around until corosync-2.0
+ when most of the threads and locking disappear.
+
+ This patch adds a pipe to confdb service. When we get a
+ objdb notification a struct gets written to the pipe.
+ The poll loop then runs the dispatch in the main thread.
+ In the dispatch we call the real ipc_dispatch_send().
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+2011-03-21 Steven Dake <sdake@redhat.com>
+
+ Resolve abort during simulatenous stopping of atleast 4 nodes
+ consider 5 nodes.
+
+ node 3,4 stopped (by random stopping) node 1,2,5 form new configuration
+ and during recovery node 1 and node 2 are stopped (via service service
+ corosync stop). This causes 5 never to finish recovery within the timeout
+ period, triggering a token loss in recovery. Bug #623176 resolved an assert
+ which happens because the full ring id was being restored. The resolution
+ to Bug #623176 was to not restore the full ring id, and instead operate
+ (according to specifications) the new ring id. Unfortunately this exposes
+ a problem whereby the restarting of nodes 1-4 generate the same ring id.
+ This ring id gets to the recovery failed node 5 which is now in gather,
+ and triggers a condition not accounted for in the original totem specification.
+
+ It appears later work from Dr. Agarwal's PHD dissertation considers this
+ scenario. That solution entails rejecting the regular token in the above
+ condition. Since the ring id is also used to make decisions for commit token
+ acceptance, we must also take care to reject the regular token in all cases
+ after transitioning from OPERATIONAL.
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+2011-03-21 Angus Salkeld <asalkeld@redhat.com>
+
+ notifyd: dispatch only one message at a time.
+ This is avoid getting stuck in the dispatch processing
+ messages when the user is trying to shutdown the service.
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+2011-03-15 Angus Salkeld <asalkeld@redhat.com>
+
+ Fix some "set but not used" warnings [-Wunused-but-set-variable]
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ Remove the ttl option from udpu and rely on the kernel ttl setting.
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ Fix the ttl defaults and range
+ 1) both IPv4 and IPv6 mcast should default to ttl=1
+ 2) the range should be 0..255
+ 0 is valid meaning localhost only (cluster of one)
+
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+2011-03-15 Russell Bryant <russell@russellbryant.net>
+
+ Add Doxyfile to .gitignore
+ Reviewed-by: Angus Salkeld <asalkeld@redhat.com>
+
+2011-03-12 Angus Salkeld <asalkeld@redhat.com>
+
+ docs: auto-generate the version
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+2011-03-12 Russell Bryant <russell@russellbryant.net>
+
+ Convert existing documentation to doxygen format.
+ This patch modifies most of the existing comments in header files to be
+ in a format that doxygen can interpret. This provides another
+ significant improvement to the web/pdf/etc generated documentation
+ without having to add new content.
+
+ Reviewed-by: Angus Salkeld <asalkeld@redhat.com>
+
+2011-03-12 Zane Bitter <zane.bitter@gmail.com>
+
+ Allocate packet buffers in the transport drivers
+ This change paves the way for eliminating a copy within the Infiniband
+ driver in the future by transferring responsibility for allocating and
+ freeing message buffers to the transport driver layer.
+
+ Tested under valgrind on a single-node cluster.
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+2011-03-10 Zane Bitter <zane.bitter@gmail.com>
+
+ Fix minor errors in man page documentation for corosync.conf
+ * Correct 'See Also' reference to corosync.conf(5) in corosync(8) man page
+ * Update path to default config (now /etc/corosync/corosync.conf)
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+2011-03-08 Steven Dake <sdake@redhat.com>
+
+ Fix abort when token is lost in RECOVERY state
+ A commit token should be rejected when a token is lost in the recovery
+ state. This occurs naturally because the ring id increases by 4 for
+ every new ring. Prior to this patch, if the token was lost, the old
+ ring id information was restored, causing a commit token to be accepted
+ when it should be rejected. This erronously accepted commit token would
+ lead to an assertion which is fixed by this patch.
+
+ Reviewed-by: Angus Salkeld <asalkeld@redhat.com>
+
+2011-03-07 Russell Bryant <russell@russellbryant.net>
+
+ Add content for the doxygen main page.
+ This creates some content on the main page of the documentation
+ generated by doxygen. The main page includes the license and a link
+ to the project web site.
+
+ eviewed-by: Steven Dake <sdake@redhat.com>
+
+ Resolve a couple of doxygen warnings.
+ This resolves a couple of doxygen warnings. First, the group needed a
+ name. Second, all of the functions in the file were added to the group
+ but doxygen complained about the lack of an end to the grouping.
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ Update doxygen configuration file.
+ The included doxygen configuration file was a bit stale. It included
+ some options that were obsolete and caused doxygen to generate some
+ warnings when running it. Most of the changes here were simply done by
+ running "doxygen -u" to automatically update the file. It added its
+ documentation for the options and removed the obsolete options.
+
+ This also includes one configuration change, which is to set EXTRACT_ALL
+ to yes. This instructs doxygen to generate documentation pages for all
+ files, public functions, and public data structures even if they are not
+ currently documented using doxygen syntax. Doxygen is capable of
+ generating some useful documentation on its own, such as dependency
+ graphs.
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ Minor build system updates for doxygen.
+ The configure script has been updated to check for the doxygen and dot
+ applications (from doxygen and graphviz). The results from these checks
+ are now used in the Makefile to ensure that the tools are installed when
+ you run "make doxygen". If they are not, it will generate a helpful
+ error message.
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ Ensure that strings are null terminated after strncpy().
+ From the strcpy(3) man page, the following warning is given:
+ The strncpy() function is similar, except that at most n bytes of src
+ are copied. Warning: If there is no null byte among the first n bytes
+ of src, the string placed in dest will not be null-terminated.
+
+ The current corosync code base does not take this warning into account
+ when using strncpy, potentially resulting in non-null terminated strings.
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+2011-03-05 Russell Bryant <russell@russellbryant.net>
+
+ Add -l option to corosync-keygen.
+ This option (-l or --less-secure) causes corosync-keygen to read from
+ /dev/urandom instead of /dev/random to ensure that no input is required
+ from the user. It may be useful when this command is used from a
+ script.
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+2011-02-24 Steven Dake <sdake@redhat.com>
+
+ Don't assert when ring id file is less then 8 bytes
+ If the ring id file for the processor is less then 8 bytes, totemsrp would
+ assert. Our speculation is that this condition happens during a fencing
+ operation or local filesystem corruption.
+
+ With this patch, Corosync will create fresh ring id file data when the
+ incorrect number of bytes are read from the ring id.
+
+ Amend to use sizeof the strerror string length and PATH_MAX for the path length.
+
+ Reviewed-by: Angus Salkeld <asalkeld@redhat.com>
+
+ snmp: Allow buildling of corosync on already existing older install of corosync
+ When building corosync against older libraries already installed on the system,
+ the corosync-notifyd application uses the wrong Makefile.am commands. This
+ results in the SNMPLIBS (which includes -L/usr/lib64) coming before the proper
+ LDADD flags. The result is an inability to compile on an already existing
+ installation.
+
+ Reviewed-by: Angus Salkeld <asalkeld@redhat.com>
+
+2011-02-24 Jan Friesse <jfriesse@redhat.com>
+
+ objdb: destroy all handles in _clear_object
+ Patch replaces free for object_instance with handle_destroy to remove
+ leaks in handles (and also memory leak).
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+2011-02-23 Jan Friesse <jfriesse@redhat.com>
+
+ Iterate all items in object_reload_notification
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ corosync-fplay: use uint32_t and remove bit-shift
+ The flight recorder records all data in 32 bit words. Use uint32_t type
+ rather then unsigned int. Also remove bit-shift with multiply by sizeof
+ uint32_t.
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ corosync-fplay: Use size_t length mod in printf
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+2011-02-22 Jan Friesse <jfriesse@redhat.com>
+
+ corosync-fplay: handle too large rec_size
+ Corrupted files may contain items with rec_size larger then g_record
+ buffer and/or flt_data_size.
+
+ Also g_record array size is now defined as constant.
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ logsys: Properly lock flt data before dump
+ Data needs to be locked, otherwise resulting fdata file may be
+ incorrect.
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ logsys: Don't leak fd on successful fdata dump
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+2011-02-21 Russell Bryant <russell@russellbryant.net>
+
+ Add calls to pthread_attr_destroy().
+ This patch adds a couple of missing calls to pthread_attr_destroy().
+
+ There were a couple of instances where pthread_attr_init() was being
+ used without a cooresponding call to pthread_attr_destroy(). This also
+ localizes the pthread_attr_t to the function where it is needed instead
+ of having it persist (the man page specifically states that destroying
+ the attributes structure has no effect on threads created using the
+ attributes).
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+2011-02-14 Angus Salkeld <asalkeld@redhat.com>
+
+ CTS: wait (consistently) for 15 minutes for events
+
+2011-02-13 Angus Salkeld <asalkeld@redhat.com>
+
+ autobuild: clean the build dir first.
+ This deletes files like .version that cause problems.
+
+2011-02-11 Angus Salkeld <asalkeld@redhat.com>
+
+ CTS: temp remove troublesome tests.
+ Right I know - not so good to comment out tests.
+ BUT they are passing but there is some weirdness
+ in ssh reconnecting to these nodes that causes CTS false
+ negatives.
+ So the nodes are watchdogged (as expected) but when they come
+ back up cts gets stuck in a loop re-trying to ssh into
+ them. It odd as a manual ssh works fine.
+
+ Basically I think it's more important the we get reliable
+ testing than have these test in there.
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+2011-02-07 Angus Salkeld <asalkeld@redhat.com>
+
+ Make node state a string (not an integer)
+ Ryan noticed this inconsistency, all other status's
+ are string so this should be too.
+
+ Reviewed-by: Seven Dake <sdake@redhat.com>
+ Reviewed-by: Ryan O'Hara <rohara@redhat.com>
+
+ CONFDB: fix parent_get response id
+ Reviewed-by: Seven Dake <sdake@redhat.com>
+
+2011-02-04 Angus Salkeld <asalkeld@redhat.com>
+
+ MIB: expand the descriptions of the notifications
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+2011-02-04 Lon Hohberger <lhh@redhat.com>
+
+ Match up MIB to notifyd & add SNMP quorum events
+ Reviewed-by: Angus Salkeld <asalkeld@redhat.com>
+
+ Make SNMP MIB match what is being sent over DBUS
+ Reviewed-by: Angus Salkeld <asalkeld@redhat.com>
+
+2011-02-04 Angus Salkeld <asalkeld@redhat.com>
+
+ Add dbus and snmp notifier
+ This is to send dbus events on major cluster events:
+ - membership changes
+ - application connect/dissconnet from corosync
+ - quorum changes
+
+ dbus events can then be converted into snmp traps by foghorn or
+ corosync-notifyd can be run to directly send snmp traps.
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+ Reviewed-by: Russell Bryant <russell@russellbryant.net>
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ CONFDB: add confdb_object_name_get()
+ This is useful when tracking object changes.
+
+ Reviewed-by: Seven Dake <sdake@redhat.com>
+
+ STATS: fix key name length on "join_count"
+ Reviewed-by: Seven Dake <sdake@redhat.com>
+
+ STATS: increase the space for application names
+ Reviewed-by: Seven Dake <sdake@redhat.com>
+
+2011-01-31 Jan Friesse <jfriesse@redhat.com>
+
+ Handle "nocluster" kernel parameter in init script
+ Init script checks kernel parameters and refuses to start corosync if
+ nocluster parameter exist on boot time. The init script will
+ continue to work as expected from console/tty after boot.
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+2011-01-12 Jan Friesse <jfriesse@redhat.com>
+
+ Add objdb firewall_enabled_or_nic_failure
+ New objdb var runtime.totem.pg.mrp.srp.firewall_enabled_or_nic_failure
+ is set to 1 if continuous_gather is larger then MAX_NO_CONT_GATHER.
+ Under normal conditions, value of variable is 0.
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+2011-01-11 Angus Salkeld <asalkeld@redhat.com>
+
+ Add missing entries into .gitignore
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ remove unused function declaration
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ fix timersub warning on freebsd
+ Make them all protected by #ifndef timersub
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+2011-01-11 Steven Dake <sdake@redhat.com>
+
+ Handle delayed multicast packets that occur with switches
+ Some switches delay multicast packets vs the unicast token. This patch works
+ around that problem by providing a new tuneable called miss_count_const. This
+ tuneable works by counting the number of times a message is found missing
+ and once reaching the const value, marks it as missing in the retransmit list.
+
+ This improves performance and doesn't display warning messages about missed
+ multicast messages when operating in these switching environments.
+
+ Reviewed-by: Angus Salkeld <asalkeld@redhat.com>
+
+2011-01-03 Angus Salkeld <asalkeld@redhat.com>
+
+ CPG: make sure coroipcc_service_disconnect() is always called.
+ This prevents a shared mem leak if corosync dies while clients
+ are connected.
+
+ Calling cpg_finalize() did not release the shared mem as
+ coroipcc_msg_send_reply_receive() returned an error and
+ thus coroipcc_service_disconnect() did not get called.
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ IPC: send failure message to client if memory maps fail
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+2010-12-03 Jan Friesse <jfriesse@redhat.com>
+
+ Display warning when not possible to form cluster
+ This may typically happen if local firewall is enabled. Patch adds new
+ item to statistics called continuous_gather where is number of
+ continuous entered gather state. If this number is bigger then
+ MAX_NO_CONT_GATHER, warning message is displayed. This is also used on
+ exiting, so stop of corosync is now possible even with enabled firewall.
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+2010-12-01 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ build: fix make srpm from release tarball
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ build: fix rpm build to include corosync-blackbox
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+2010-12-01 Steven Dake <sdake@redhat.com>
+
+ Revert "Always autogen the tree when building an RPM"
+ This reverts commit d145838a21fb636461a2bceeada34db439f4a9ec.
+
+ Always autogen the tree when building an RPM
+ Since the source tarball never includes the autogen'ed tree in the new source
+ repo methodology, always autogen the tree.
+
+ Set the max buffer size for sockets
+ Set the recv buffer to a large size and the send buffer to a large size to
+ allow the kernel to store more messages before dropping messages.
+
+ Amended to change optlen type to socklen_t
+
+ Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+
+2010-11-28 Steven Dake <sdake@redhat.com>
+
+ The flushing code was introducing data corruption because of recursion errors that occur as a result of the design of udpu. Totem no longer requires the flushing technique because we don't mark a packet as missing until it has not been seen by a certain number of token rotations per a previous patch. This mechanism was introduced to work around a problem in switches where multicast messages may be delayed by long periods compared to the unicast token.
+ This patch removes the flushing logic from udpu since it is no longer necessary.
+
+ Reviewed-by: Angus Salkeld <asalkeld@redhat.com>
+
+2010-11-24 Angus Salkeld <asalkeld@redhat.com>
+
+ Add totem/interface/ttl config option.
+ This adds a per-interface config option to
+ adjust the TTL.
+
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+2010-11-19 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ build: fix makefile to ship corosync.conf.example.udpu
+ Reviewed-by Angus Salkeld <asalkeld@redhat.com>
+
+2010-11-18 Steven Dake <sdake@redhat.com>
+
+ Merge branch 'topic-udpu'
+ Conflicts:
+ Makefile.am
+
+ Remove dead soresueaddr code
+ Reviewed-by: Angus Salkeld <asalkeld@redhat.com>
+
+ Add the UDPU transport
+ The UDPU transport is useful for those deployments which can't use multicast.
+ UDPU works by using UDP unicast, which is fully supported by every switch
+ manufacturer by default and doesn't rely on a functional IGMP implementation.
+
+ An example of the UDPU transport is contained in the corosync.conf.example.udpu
+ file which shows a 16 node cluster. This file should be copied to each node
+ in the cluster and IP addresses changed as appropriate.
+
+ Amended to remove dead udpu REUSEADDR socket option.
+
+2010-11-10 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ build: fix spec file and srpm/rpm generation
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+ add release script and git based versioning
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+2010-11-10 Steven Dake <sdake@redhat.com>
+
+ Merge branch 'master', remote branch 'origin/master'
+
+ Add license information to LICENSE file about build process files
+ A few files licensed under GPLv3+ produce text output but are not used as
+ part of the runtime or libraries provided by Corosync. Make that notification
+ in the LICENSE file.
+
+ Reviewed-by: Fabio Di Nitto <fdinitto@redhat.com>
+
+2010-10-22 Angus Salkeld <asalkeld@redhat.com>
+
+ Add -i <num-iterations> to cpgverify
+ Reviewed-by: Steven Dake <sdake@redhat.com>
+
+2010-10-22 Steven Dake <sdake@redhat.com>
+
+ New topic descriptions based upon work community wants to do
+ This file describes the topics of interest for development, their start and
+ finish date, their main developer, and a description of the topic.
+
+ Reviewed-by: Angus Salkeld <asalkeld@redhat.com>
+
+2010-10-21 Angus Salkeld <asalkeld@redhat.com>
+
+ Add .gitignore files.
+ Otherwise "git status" is a pain.
+
+ Reviewed-by: Steven Dake <sdake@edhat.com>
+
+2010-10-21 Steven Dake <sdake@redhat.com>
+
+ Add -n option to corosync-objctl to create a new object/key combo
+ Find an existing parent object and add the last object/key name of the command
+ to the object database. This allows the runtime addition of ip addresses to
+ the list of IPs corosync knows about for the purpose of the UDPU transport mode.
+
+ Reviewed-by: Angus Salkeld <asalkeld@redhat.com>
+
+2010-10-12 Jan Friesse <jfriesse@redhat.com>
+
+ Remove delay in library on corosync shutdown
+ Patch removes 2 seconds delay in library on normal corosync shutdown.
+ Delay is still present on abnormal shutdown.
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@3059 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-09-29 Angus Salkeld <asalkeld@redhat.com>
+
+ autobuild: fix the continous build
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@3058 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-09-28 Angus Salkeld <asalkeld@redhat.com>
+
+ Check for a properly configured multicast address.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@3057 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-09-27 Angus Salkeld <asalkeld@redhat.com>
+
+ CTS: add sam/wd integration tests.
+ - fix send_dynamic() exception
+ - fix basic sam integration test
+ - fixup calls to sam tests
+ - fix startup when using testquorum (currently only handles votequorum)
+ - improve SAM test case with better checking.
+
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@3056 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ AUG: add support for resources section & quorum/quorate
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@3055 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ WD/SAM integration.
+ - timestamps -> uint64_t and in nanosecs
+ - use clock_gettime
+ - common object naming
+ - common state names
+ - timeouts in milliseconds
+
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@3054 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add monitoring and watchdog services.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@3053 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add a Finite State Machine.(fsm.h)
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@3052 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add a Finite State Machine.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@3051 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-09-27 Jan Friesse <jfriesse@redhat.com>
+
+ SAM Confdb integration
+ Patch add support for Confdb integration with SAM. It's now possible to
+ use SAM_RECOVERY_POLICY_CONFDB as flag to previous policies.
+
+ Also new function sam_mark_failed is added for ability to use RECOVERY
+ policy together with confdb and get expected results (specially with
+ integration with corosync watchdog)
+
+ Patch also makes SAM thread safe.
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@3050 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-09-25 Angus Salkeld <asalkeld@redhat.com>
+
+ configure: cleanup formatting.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@3049 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ objdb: fix some ugly indentation.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@3048 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ objdb: delete trackers when an object is deleted
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@3047 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ objdb: object_created_notification() fix the order of the parent and object handles.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@3046 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ objdb: fix some strange types (uint8_t* -> void*).
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@3045 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ add float and double support to corosync-objctl
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@3044 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ CPG: remove irratating log "downlist received left_list:"
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@3043 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-09-14 Steven Dake <sdake@redhat.com>
+
+ Patch from Kacper Kowalik to support honoring user defined LDFLAGS.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@3042 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Patch from Kacper Kowalik to add support for --enable-user-flags configure option.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@3041 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-09-03 Steven Dake <sdake@redhat.com>
+
+ change shutdown priority to 80 in generic.in.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@3039 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Patch from Keisuke Mori to add proper dependeny on syslog to corosync init script.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@3038 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-08-31 Steven Dake <sdake@redhat.com>
+
+ Fix few xopen tsafe issues.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@3037 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Bump version to 1.2.8.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@3034 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Build properly with different versions of libc by including all posix APIs in header definitions.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@3030 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-08-25 Angus Salkeld <asalkeld@redhat.com>
+
+ IPC: return CS_ERR_NO_RESOURCES to library when low on fds.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@3029 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ POLL: gracefully handle running out of file descriptors.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@3028 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-08-24 Steven Dake <sdake@redhat.com>
+
+ Remove checking of sub parameters in service.d files.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@3024 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-08-17 Steven Dake <sdake@redhat.com>
+
+ Properly detect shutdown of corosync process
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@3022 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-08-03 Steven Dake <sdake@redhat.com>
+
+ Remove cancel token retransmit timeout.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@3012 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-08-02 Jan Friesse <jfriesse@redhat.com>
+
+ Check that Corosync was not runned by cman
+ Patch fixes init script so it's tested, if corosync was runned
+ by cman or not. If so, it refuses to stop Corosync.
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@3011 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Allow running only one instance of Corosync
+ Patch makes Corosync more compliant with common practices
+ for writing daemon. It creates pid file (usually
+ /var/run/corosync.pid) and flocks it. So only one instance
+ of Corosync can be executed now.
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@3010 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-07-27 Steven Dake <sdake@redhat.com>
+
+ Change trunk version to 1.2.7.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@3007 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Remove consensus check for two node cluster cases which can have smaller consensus values. Document in man page the behavior of consensus.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@3005 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-07-21 Steven Dake <sdake@redhat.com>
+
+ Fix merge error with revision 3001.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@3002 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix problem where flow control could lock up ipc under very heavy load in very rare circumstances.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@3001 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-07-19 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ Fix logging_daemon config parser code.
+ Resolves: rhbz#615203
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2997 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-07-17 Angus Salkeld <asalkeld@redhat.com>
+
+ SYNC: always call sync_aborted() in sync_confchg_fn().
+ 1) sync_callbacks.sync_abort can be null.
+ 2) sync_processing is set to 0 after syncv1 is done.
+ Then syncv2 processing is down. If we get a config change
+ after syncv1 is down, but before syncv2 is done then it won't
+ get aborted.
+
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2995 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-07-16 Angus Salkeld <asalkeld@redhat.com>
+
+ CTS: add a test case for Andrew's bug
+ Bug:
+ sometimes shutdown can take a long time if all nodes
+ are shutdown together.
+
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2994 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ SYNCV2: add debug when messages are discarded
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2993 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ SYNC: add some ENTER() trace points.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2992 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ SYNCV2: reset the my_memb_determine_ring_id in sync_v2_memb_list_abort()
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2991 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ SYNC: remove unused primary_designated from sync_primary_callback_fn()
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2990 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-07-14 Steven Dake <sdake@redhat.com>
+
+ Remove reset of token timeout on retransmitted token reception. The timer should only be reset when a real token is received or membership protocol could run into problems with certain timing parameters.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2988 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-07-07 Steven Dake <sdake@redhat.com>
+
+ Speed up IPC connection process.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2986 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-07-03 Steven Dake <sdake@redhat.com>
+
+ Fix fail list fault that occurs in very rare circumstances.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2984 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-06-30 Steven Dake <sdake@redhat.com>
+
+ Bump trunk revision to 1.2.6.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2980 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Have makefile create /var/log/cluster rather then corosync.spec file.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2979 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-06-30 Andrew Beekhof <abeekhof@redhat.com>
+
+ Safely redirect stderr/in/out to /dev/null to prevent fork() from crashing
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2976 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-06-29 Steven Dake <sdake@redhat.com>
+
+ Patch to fix stack protector sig abort that occurs when ipc buffer is too short.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2974 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-06-29 Angus Salkeld <asalkeld@redhat.com>
+
+ ipc: Fix error handling of mmap util functions.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2972 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-06-29 Steven Dake <sdake@redhat.com>
+
+ Have corosync spec file own /var/log/cluster/corosync.log have example use /var/log/cluster/cluster.log as default log file
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2970 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix problem where flight data leaks files in /dev/shm when corosync is restarted continuously via init scripts.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2964 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-06-28 Jan Friesse <jfriesse@redhat.com>
+
+ Fix OBJDB locking
+ Patch fixes following situation:
+
+ 1. objdb receives reload notification and ends in function
+ object_reload_config. This will call objdb_wrlock. I will call this
+ thread #1
+
+ 2. Another thread will decide to update corosync statistics and calls
+ object_key_increment. This calls objdb_rdlock. This thread is #2. But
+ because condition (lock_thread != pthread_self()) is satisfied, it will
+ also calls pthread_rwlock_rdlock. This will blocks, because thread #1
+ holds the lock.
+
+ 3. object_reload_config will call reload functions (as real example
+ xml2objdb). xml2objdb needs to calls object_create. This calls
+ objdb_rdlock, but will hang on pthread_mutex_lock(&meta_lock), because
+ this lock is held by thread #2.
+
+ -> deadlock
+
+ It is handled by using recursive mutex.
+
+ Also every function is now really locked.
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2963 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-06-23 Jan Friesse <jfriesse@redhat.com>
+
+ Remove pathconf which may fall
+ Corosync has problem with readdir_r if pathconf function fails.
+
+ Main problem is hidden in calling pathconf (internally calls statfs)
+ which may fail. After this fail, newly allocated memory for readdir_r
+ was smaller than expected and memory was overwritten by readdir_r.
+
+ Patch removes calling of pathconf and rather use NAME_MAX constant which
+ is always large enough for all file systems.
+
+ Also return value of malloc SHOULD be checked.
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2962 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-06-21 Angus Salkeld <asalkeld@redhat.com>
+
+ Add make/spec file changes for corosync & blackbox man pages.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2961 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add a simple man page for corosync
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2960 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add a man page for corosync-blackbox
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2959 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-06-21 Steven Dake <sdake@redhat.com>
+
+ Change version to 1.2.5 in trunk.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2956 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-06-19 Steven Dake <sdake@redhat.com>
+
+ Stop the totem stats updater timer during shutdown to prevent references to invalid memory.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2953 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Unlock global serializer lock during shutdown.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2949 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-06-18 Andrew Beekhof <abeekhof@redhat.com>
+
+ Prevent segfault in fork()
+ Not closing stdin/stderr/stdout leads to a segfault in fresetlockfiles()
+ See https://lists.linux-foundation.org/pipermail/openais/2010-June/014854.html for further info.
+
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2948 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-06-15 Steven Dake <sdake@redhat.com>
+
+ Patch from Honza: Send CPG_REASON_PROCDOWN on process left
+ Our manual pages are clear:
+
+ CPG_REASON_PROCDOWN - the process left a group without calling
+ cpg_leave().
+
+ Currently, we are sending CPG_REASON_LEAVE in such situation.
+
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2946 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-06-15 Christine Caulfield <ccaulfie@redhat.com>
+
+ object_key_iter() calls object_key_iter_typed() and then always tries to dereference the string it returns, even if the call fails. The attached patch fixes this.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2944 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-06-10 Steven Dake <sdake@redhat.com>
+
+ changes to corosync.spec.in template:
+ Move configure to %build section
+ don't set corosync's init levels during an upgrade of the corosync package
+
+ Patch from Vadym Chepkov
+
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2943 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-06-09 Steven Dake <sdake@redhat.com>
+
+ update version to 1.2.4.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2939 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Update logsys to use proper ring buffer on file backed map
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2922 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-06-07 Angus Salkeld <asalkeld@redhat.com>
+
+ Disable test while I fix it.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2921 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-06-04 Steven Dake <sdake@redhat.com>
+
+ sem_wait can be interrupted by signal. Handle interruption properly.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2920 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-06-03 Steven Dake <sdake@redhat.com>
+
+ Fix fail to receive logic which occurs very rarely on high loss networks with software based multicast.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2919 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-06-02 Angus Salkeld <asalkeld@redhat.com>
+
+ temporarily remove a cts test case.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2918 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-06-01 Steven Dake <sdake@redhat.com>
+
+ Totem spec is clear:
+ reject retransmitted tokens
+ if token.aru = aru in token on last rotation ... do some logic
+
+ Here is how the current code works:
+
+ last_aru = instance->my_last_aru;
+ instance->my_last_aru = token->aru;
+ reject retransmitted tokens
+ if token.aru = aru in token on last rotation ... do some logic
+
+ The issue is last_aru will be set to token->aru when a token retransmission
+ occurs before a new token arrives.
+
+ This results in the "do some logic" part happening more often then it should.
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2917 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix problem where callbacks are not delivered to evs service.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2916 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-05-28 Steven Dake <sdake@redhat.com>
+
+ The static function 'decode_mode()' is used by the static function 'dump_subsys_config()' which is is turn used by the static function 'dump_full_config()' which is never used.
+ Are these functions used by someone using some magic? I did not find
+ any reference and even the flag LOGSYS_DEBUG, which prevents them from
+ compiling, does not exist at some other point.
+
+ If these functions are really not used, please remove them (because at
+ least one of them has a buffer overflow). Patch against 1.2.3
+ is attached.
+
+ If there is a need for these functions, I'll send a patch to fix
+ the 'decode_mode()' function.
+
+ Kind regards
+
+ Andreas Florath
+
+
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2915 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-05-28 Angus Salkeld <asalkeld@redhat.com>
+
+ Add a man page for corosync-quorumtool
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2914 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add a man page for corosync-pload
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2913 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add man page for corosync-fplay.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2912 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add man page for corosync-cpgtool
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2911 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add man page for corosync-cfgtool
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2910 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Really corosync-keygen.8
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2909 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add a man page for corosync-keygen and update corosync_overview
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2908 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-05-27 Jan Friesse <jfriesse@redhat.com>
+
+ coroipcc - don't loop forever on EINTR
+ This patch unify behaviour of SYS V semaphores and POSIX semaphores.
+ POSIX semaphores never return CS_ERR_TRY_AGAIN on EINTR and keeps
+ waiting. This was fixed for SYS V semaphores in rev. 2303.
+
+ Another change is to remove very small probability of hung forever in
+ coroipcc_dispatch_put.
+
+ Last change is removal of duplicate code by adding ipc_sem_wait function.
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2907 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-05-26 Steven Dake <sdake@redhat.com>
+
+ Fix problem where memcpy operation occurs incorrectly to copy schedule parameter data resulting in priority inversion deadlocks on single cpu systems.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2906 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-05-21 Angus Salkeld <asalkeld@redhat.com>
+
+ makefile: add -lquorum -lcoroipcc to sam test programs
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2905 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Autobuild: add -v option to mock
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2904 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-05-19 Steven Dake <sdake@redhat.com>
+
+ Bump revision to 1.2.3.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2901 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix leak in error path in nss encryption.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2857 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ This patch updates the wording for the bindnetaddr option in corosync.conf to explicitly state that you need to use the network address, as opposed to "should always end in zero", which is only correct for class C networks.
+ Regards,
+
+ Tim
+
+
+ --
+ Tim Serong <tserong@novell.com>
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2856 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Make cpg_membership_get() functional.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2855 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-05-19 Angus Salkeld <asalkeld@redhat.com>
+
+ cov 10412: fix mem leak in encrypt_and_sign_nss()
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2854 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ add __attribute__((noreturn)) to functions that always exit.
+ we had some __attribute__((__noreturn__))
+ and some __attribute__((noreturn))
+
+ I made them all: __attribute__((noreturn))
+
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2853 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-05-18 Steven Dake <sdake@redhat.com>
+
+ Fix free of ring status information when memory allocation fails during allocation of the ring status information.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2852 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix signed comparison with unsigned value in mainconfig.c
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2851 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-05-18 Angus Salkeld <asalkeld@redhat.com>
+
+ cov 10388: fix check for no mcast address
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2850 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ cov (many): make sure all _set() functions return a signed int
+ in the body it can return -1, and callers check for -1.
+ but the return type is unsigned int?
+
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2849 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ cov 10391: allow assert to check for a negative number
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2848 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ cov 10404: don't assign loc pointer when not used.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2847 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-05-18 Steven Dake <sdake@redhat.com>
+
+ Fix problem where logsys messages are not flushed at exit before worker thread is created.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2846 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-05-18 Angus Salkeld <asalkeld@redhat.com>
+
+ cov 10405: remove unused pointer from totemsrp.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2845 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-05-17 Angus Salkeld <asalkeld@redhat.com>
+
+ cov 10373: check poll return value
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2844 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix compile error in services/cfg.c
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2843 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-05-16 Angus Salkeld <asalkeld@redhat.com>
+
+ cov 10392: remove pointless assert
+ backlog is unsigned
+
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2842 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ cov 10413: crypto init a variable.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2841 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ cov (10387, 10397): cleanup memory mapping functions
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2840 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ cov 10374: check sam_hc_send() before counter++
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2839 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ cov 10399: set the msg_flags to 0 in coroipcs.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2838 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ cov 10390: remove pointless assert.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2837 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ cov 10389: remove unneccessary check.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2836 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ cov 10371: check return of lcr_ifact_reference
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2835 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ cov 10401: error_string never set
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2834 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ cov 10411: fix leak in totemudp.c
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2833 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ cov 10400: unit'ed variable.
+ not important, easy to fix.
+
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2832 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-05-14 Steven Dake <sdake@redhat.com>
+
+ Merge patch from Sato Yuki which fixes corosync-cfgtool -r
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2831 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-05-14 Angus Salkeld <asalkeld@redhat.com>
+
+ cov 10396: prevent a leak under error conditions (lib/sam.c)
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2830 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ cov 10378: fix syntax error.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2829 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ cov 10385: assigning signed int to unsigned variable
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2828 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ cov 10384: better error handling from accept()
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2827 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ cov 10383: impove the error handling after socket()
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2826 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ cov 10382: improve error handling around open()
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2825 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ cov 10381: check result of open()
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2824 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ cov 10379 &10380: check result of open before calling ftruncate.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2823 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-05-13 Jan Friesse <jfriesse@redhat.com>
+
+ SAM integration of quorum
+ Patch adds integration of SAM and quorum, so it's now possible to use
+ SAM_RECOVERY_POLICY_QUORUM_QUIT or SAM_RECOVERY_POLICY_QUORUM_RESTART
+ recovery policy. With these policies, sam_start will block until
+ corosync is quorate. If quorum is lost during health checking, recovery
+ action is taken.
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2822 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Allow call sam_warn_signal_set after sam_register
+ Patch fixes situation, when user want to change warn signal after
+ call of sam_register function. This was not possible, because parent
+ process never got new value from child.
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2821 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-05-13 Steven Dake <sdake@redhat.com>
+
+ Bump version to 1.2.2.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2818 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ logsys rework to deal with memory corruption around debug:on configurations.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2816 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-05-13 Angus Salkeld <asalkeld@redhat.com>
+
+ autobuild: clean up the example config before installing
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2815 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-05-12 Angus Salkeld <asalkeld@redhat.com>
+
+ cpg: fix unitialized variable
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2814 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ CTS: fix test_agent start/stop errors
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2813 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ CTS: fix test service configuration
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2812 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ configure: minor change to get tab completion to work
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2811 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-05-05 Angus Salkeld <asalkeld@redhat.com>
+
+ autobuild: hard code mock path to /usr/bin/mock
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2808 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ set execute bit on autobuild.sh
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2807 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ spec: fix some errors from rpmbuild & rpmlint
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2806 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ testcpg: fix a format string compile warning.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2805 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ log: remove "Member left/join" log messages
+ No longer needed by CTS and likely to be very noisy
+ with large node numbers.
+
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2804 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-05-04 Angus Salkeld <asalkeld@redhat.com>
+
+ cpg: fix sync'ing the downlist.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2801 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ check and discard unknown messages
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2800 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ diags: add a mechanism to trigger the writing the flight data
+ trigger the dumping of flight data using:
+ corosync-objctl -w runtime.blackbox.dump_flight_data=anything
+ trigger the dumping of state using:
+ corosync-objctl -w runtime.blackbox.dump_state=anything
+
+ then read the flight data as usual:
+ corosync-fplay
+
+ This patch includes a wrapper script called:
+ corosync-blackbox
+
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2799 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix "mock --with testagents"
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2798 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-05-03 Angus Salkeld <asalkeld@redhat.com>
+
+ CTS: reproduce David's bug
+ This patch creates a test case the runs the following steps:
+ 1: start all nodes
+ 2: isolate node n1
+ 3: Kill corosync on n1
+ 4: unisolate node n1
+ 5: start corosync on n1
+ 6: start cpg on all nodes
+ 7: isolate node n1
+ 8: Kill corosync on n1
+ 9: unisolate node n1
+ 10: start corosync on n1
+ 11: Waiting for config change on n2
+
+
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2797 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-05-02 Angus Salkeld <asalkeld@redhat.com>
+
+ Add autobuild.sh : for buildbot to run CTS
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2796 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-04-30 Steven Dake <sdake@redhat.com>
+
+ The retransmit token storage area is an improper type of an array of pointers rather then a pointer to a buffer.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2795 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ When a message is retransmitted, a memmove operation is done to remove the newly retransmitted entry from the list. It is possible this memmove operation can buffer overflow because it has an invalid length calculation fixed by this revision.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2794 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Allow maximum entries in the retransmit queue when recovery takes place.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2793 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Save the ring id and restore it properly when the recovery operation fails as a result of a new gather or token loss.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2792 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-04-29 Christine Caulfield <ccaulfie@redhat.com>
+
+ Fix name of fail_recv_const in corosync.conf man page
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2791 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-04-28 Jan Friesse <jfriesse@redhat.com>
+
+ Fix parallel build of libs in lib directory
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2790 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-04-26 Jan Friesse <jfriesse@redhat.com>
+
+ Handle POLLNVAL in coroipcc
+ Old code in coroipcc doesn't handle POLLNVAL. It can happen, that some
+ applications (for example fenced) will stuck forever.
+
+ Also poll result is now handled more correctly.
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2789 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-04-23 Jan Friesse <jfriesse@redhat.com>
+
+ Handle some valgrind errors
+ - Memset for res_setup variable in coroipcs:req_setup_send
+ - Two memset in logsys for buffers
+ - Problem in corosync_totem_stats_updater where avg_token_holdtime has
+ size of avg_backlog_calc
+ - corosync_totem_stats_init where avg_backlog_calc is 32 bits (not 64)
+ - objdb problem if new_valie_len != object->value_len. In such case
+ newly allocated memory is not initialized and in some situations,
+ value_len is not updated.
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2787 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-04-23 Angus Salkeld <asalkeld@redhat.com>
+
+ select a new sync member if the node with the lowest nodeid has left.
+ Problem:
+
+ Under certain circumstances cpg does not send group leave messages.
+
+ With a big token timeout (tested with token == 5min).
+ 1 start all nodes
+ 2 start ./test/testcpg on all nodes
+ 2 go to the node with the lowest nodeid
+ 3 ifconfig <int> down && killall -9 corosync && /etc/init.d/corosync restart && ./testcpg
+ 4 the other nodes will not get the cpg leave event
+ 5 testcpg reports an extra cpg group (basically one was not removed)
+
+ Solution:
+ If a member gets removed using the new trans_list and
+ that member is the node used for syncing (lowest nodeid)
+ then the next lowest node needs to be chosen for syncing.
+
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2785 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ CTS: increase the token timeout on some tests
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2784 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ CTS: add CpgCfgChgOnNodeRestart
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2783 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-04-20 Jan Friesse <jfriesse@redhat.com>
+
+ CPG model_initialize and ringid + members callback
+ Patch adds new function to initialize cpg, cpg_model_initialize. Model
+ is set of callbacks. With this function, future addions of models
+ should be possible without changing the ABI.
+
+ Patch also contains callback in CPG_MODEL_V1 for notification about
+ Totem membership changes.
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2770 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Support for store user data in SAM
+ Ability to in-memory storing of user data which survives between
+ instances of process.
+
+ Also ability needed ability for bi-directional communication between
+ child and parent is added.
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2769 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix confdb linking (add -ldl)
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2768 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-04-20 Christine Caulfield <ccaulfie@redhat.com>
+
+ Fix a crash in YKD
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2767 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-04-16 Angus Salkeld <asalkeld@redhat.com>
+
+ CTS: update the CTS README
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2766 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ CTS: make record events blocking
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2765 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ CTS: add context get/set tests.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2764 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ CTS: fix the test_agent start/stop/status mechanism.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2763 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-04-15 Angus Salkeld <asalkeld@redhat.com>
+
+ test for augtool before using it in "make check"
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2762 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-04-14 Angus Salkeld <asalkeld@redhat.com>
+
+ CTS: add quorum notifications to test agents.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2761 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ CTS: add simul start/stop to GenTestClasses
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2760 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ CTS: make the extra config tests named
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2759 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ CTS: add --rrp-bindaddr to enable rrp tests.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2758 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-04-12 Angus Salkeld <asalkeld@redhat.com>
+
+ When sync is aborted clear the "my_ring_id" variable.
+ This patch fixes crashes found by repeated pacemaker CTS SimluStart
+ tests. When you bring up the nodes together it can cause a lot of
+ configuration changes and sync gets started and aborted
+ lots of times.
+
+ When abort is called the ring_id is not changed which means that any
+ sync packet that arrive from that point on will be accepted as valid.
+ I have seen old barrier messages causing the processing index to increment
+ later causing an array out of bounds.
+
+ This patch memsets the ring_id to 0, thus causing the ring_id in the packet and
+ my_ring_id not to match.
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2757 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-04-07 Angus Salkeld <asalkeld@redhat.com>
+
+ add comment to the man page explaining the use of port and port -1.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2756 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-04-02 Steven Dake <sdake@redhat.com>
+
+ Allow modifying POLLIN/POLLOUT state in another thread while the main thread is blocked in poll system call.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2755 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Remove problem where NULL dispatch handler functions would result in lockup of the dispatch if they were sent by a service engine.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2754 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-04-01 Jan Friesse <jfriesse@redhat.com>
+
+ Support for user configurable warning signal
+ Allow developer configure a signal to be send as a warning signal
+ before real SIGKILL.
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2753 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Support for specific libraries version
+ Patch adds support for changing version number of library simply by edit
+ lib$(LIB).verso file.
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2752 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-03-30 Angus Salkeld <asalkeld@redhat.com>
+
+ Add missing cts files.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2751 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-03-30 Steven Dake <sdake@redhat.com>
+
+ Fix barrier operation with syncv2 and compat:none or openais service engines.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2750 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-03-30 Angus Salkeld <asalkeld@redhat.com>
+
+ augeas: add uidgid and quorum options to lense
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2749 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-03-30 Jérôme Flesch <jerome.flesch@netasq.com>
+
+ Coroipcc: Make sure that coroipcc_service_connect() always return a valid cs_error_t
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2748 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-03-30 Angus Salkeld <asalkeld@redhat.com>
+
+ CTS: add votequorum test agent
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2747 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ objdb: fix key change notifications
+ 1) don't send notifications if the key is the same.
+ 2) Add key value change notifications to key_inc & key_dec
+
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2746 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ CTS: add some more confdb tests
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2745 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ CTS: add sam tests
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2744 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ CTS: add cpg_zcb tests
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2743 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ CTS: add a test for sync events
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2742 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ fix make distcheck (add corosync.aug to EXTRA_DIST
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2741 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-03-26 Jérôme Flesch <jerome.flesch@netasq.com>
+
+ Totemudp: Add debug logs when a call to sendmsg() fails
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2740 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-03-25 Angus Salkeld <asalkeld@redhat.com>
+
+ Make corosync exit with 0 normally and +1.. on error.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2739 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-03-24 Angus Salkeld <asalkeld@redhat.com>
+
+ fix 'make distcheck'
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2738 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ CTS: get some more code to execute.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2737 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ CTS: Add a condb test agent and python tests.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2736 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ CTS: Add a confdb test agent and python tests.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2735 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ CTS: fix issues with new pacemaker cts
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2734 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ CTS: restruct tests so we can run them with multiple configs
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2733 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add quorum option to augeas lense
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2732 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix unloading of evs (service id == 0)
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2731 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ CTS: add service load/unload test
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2730 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix code coverage with lcrso's
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2729 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ CTS: Add tests with more totem options.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2728 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add crypto options to augeas lense & add make check
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2727 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ CTS: Add msg sha1 checking of the message body (like cpgverify)
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2726 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-03-23 Steven Dake <sdake@redhat.com>
+
+ Bump version to 1.2.1.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2723 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Tone down noisy logging from ipcs system.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2721 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-03-22 Steven Dake <sdake@redhat.com>
+
+ Fix lockup that occurs rarely with pthread_join() is called in atexit() handler.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2719 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-03-20 Steven Dake <sdake@redhat.com>
+
+ Fix problem where retransmissions don't occur resulting in failure to receive condition.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2685 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-03-16 Christine Caulfield <ccaulfie@redhat.com>
+
+ Fix a couple of small bugs that happen when the configuration is reloaded.
+ 1. the reload callback was not sent to the library,
+ 2. totem exponentially added new callbacks because the old ones were not
+ removed properly.
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2684 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add a reload callback to libconfdb.
+ This also increments the libconfdb version to 4.1.0
+
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2683 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-03-11 Angus Salkeld <asalkeld@redhat.com>
+
+ Remove warnings.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2682 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ add optional --with testagents to the spec file
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2681 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ CTS: fix buffer overrun in test agent.
+ Also to make debugging easier:
+ 1) don't stop abrt
+ 2) fix debug message
+ 3) catch a failed mesage to the TA and fail the test.
+
+
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2680 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ CTS: fix deletion of the tmp root for augeas
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2679 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-03-09 Angus Salkeld <asalkeld@redhat.com>
+
+ add a list of member nodes into the objdb runtime tree.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2678 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ tsafe: change fork() override to pthread_atfork() callbacks.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2677 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-03-04 Jan Friesse <jfriesse@redhat.com>
+
+ Support for lib_cpg_finalize
+ Add support for MESSAGE_REQ_CPG_FINALIZE message. This will allow us
+ remove cpg_pd from list of active connections, and remove problem, when
+ cpg_finalize + cpg_initialize + cpg_join can result in CPG_ERR_EXIST
+ error.
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2676 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Cpg join with undelivered leave message
+ Patch handles situation, when on one node, one process:
+ - join cpg
+ - do same actions
+ - leave cpg
+ - join cpg again
+
+ Following sequence can (racy) end with broken process_info list.
+
+ To solve this problem, one more check is done in
+ message_handler_req_lib_cpg_join so if process_info with same pid and
+ group as new join request exists, CPG_ERR_TRY_AGAIN is returned.
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2675 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-03-03 Angus Salkeld <asalkeld@redhat.com>
+
+ Fix some "make lint" problems
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2674 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-03-03 Steven Dake <sdake@redhat.com>
+
+ Specify the ringnumber parameter must start at 0 in the corosync.conf man page.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2673 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix error handling to avoid segfaults/leaks on error in coroipcc_service_connect.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2672 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Turn executable bit on for py/sh scripts in cts.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2671 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-03-03 Angus Salkeld <asalkeld@redhat.com>
+
+ Add tsafe.h to noinst_HEADERS to fix "make distcheck"
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2670 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add tsafe (thread safe) file to catch unsafe function calls.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2669 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add a test harness to corosync that uses CTS from pacemaker.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2668 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-02-26 Christine Caulfield <ccaulfie@redhat.com>
+
+ Reduce the number of times the quorum message is displayed.
+ Patch from David Teigland
+
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2667 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-02-25 Angus Salkeld <asalkeld@redhat.com>
+
+ convert giduid calls to reentrant versions.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2666 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ convert strerror() into strerror_r()
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2665 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ convert readdir into readdir_r
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2664 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ convert strtok to strtok_r
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2663 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-02-18 Angus Salkeld <asalkeld@redhat.com>
+
+ Add a debug message on node join/leave.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2662 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Correct testcpg's groupname.length
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2661 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-02-18 Steven Dake <sdake@redhat.com>
+
+ Patch to set unset value in token hold cancel structure as to not crash wireshark.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2660 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-02-17 Angus Salkeld <asalkeld@redhat.com>
+
+ add a note about rotating logfile created with to_logfile
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2659 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add augeas lense for corosync.conf
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2658 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-02-16 Jan Friesse <jfriesse@redhat.com>
+
+ Fix corosync shutdown process
+ This patch change corosync shutdown process, so now:
+ - exit function of service engine is called
+ - all IPC connections are closed and removed from poll
+ - service engine is unlocked
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2657 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-02-15 Steven Dake <sdake@redhat.com>
+
+ Use nodeid instead of localhost ip for the case when binding to a loalhost interface.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2656 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-02-12 Christine Caulfield <ccaulfie@redhat.com>
+
+ Remove a double list_del() when a tracking CFG client shuts down without calling cfg_track_stop. This caused corosync to crash.
+ The extra list_empty() check is redundant too because it also happens in remove_ci_from_shutdown()
+
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2655 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-02-04 Steven Dake <sdake@redhat.com>
+
+ Merge of Dejan's on=yes patch for the config parser options to ease migration.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2654 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-02-04 Angus Salkeld <asalkeld@redhat.com>
+
+ pass transitional members into the sync_init() callbacks.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2653 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ move sync_v2_init() into main_service_ready
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2652 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-02-02 Angus Salkeld <asalkeld@redhat.com>
+
+ totemsrp: fix transitional configuration changes with long token timeouts
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2651 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-01-31 Steven Dake <sdake@redhat.com>
+
+ Fix coroipcs message corruption that occurs when a message fills the remainder of the dispatch buffer with a full message.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2650 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-01-22 Jan Friesse <jfriesse@redhat.com>
+
+ Add schedwrk_create_nolock function
+ This patch adds schedwrk_create_nolock, which will not call
+ serialize_lock before execution of callback.
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2649 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-01-21 Jan Friesse <jfriesse@redhat.com>
+
+ Pass correct poll handle to poll_stop on exit
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2648 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ poll_dispatch_delete - ability to return 0
+ Patch fixes poll_dispatch_delete, so it is able to return 0
+ (success), when requested FD was found.
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2647 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-01-20 Jan Friesse <jfriesse@redhat.com>
+
+ Fix setting invalid mode in log destination
+ This fixes problem in revision 2642, when only last
+ line of log destination setting is really applied.
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2646 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-01-14 Jan Friesse <jfriesse@redhat.com>
+
+ Fix malloc deadlock in signal handler
+ This patch solves situations, where malloc is called
+ inside signal handler. It creates thread, which waits
+ for semaphore unlock and then starts shutdown sequence.
+
+ RHBZ#547511
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2644 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix freeze of IPC library connection on sem_wait
+ This patch solves library waiting on sem_wait. It doesn't
+ solve all other problems, which can make corosync not
+ to exit (malloc race, global lock deadlock, ...)
+
+ RHBZ#547511
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2643 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-01-13 Jan Friesse <jfriesse@redhat.com>
+
+ Fix coroparse to allow white chars before comment
+ - allows white characters before #
+ - new function to parse log destinations (remove code duplicity)
+ - clarify man page
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2642 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2010-01-11 Jan Friesse <jfriesse@redhat.com>
+
+ Generate nodeid value when unset on BSD
+ Generated nodeid is generated in same way as
+ on Linux is.
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2641 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-12-15 Steven Dake <sdake@redhat.com>
+
+ Remove invalid assertion in totemsrp.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2640 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-12-15 Andrew Beekhof <abeekhof@redhat.com>
+
+ Correctly determine current state in init script
+ If two stop actions are ever performed simultaneously, then neither will terminate.
+ With the default implementaiton of __pids_pidof, the status() function from
+ /etc/init.d/functions incorrectly thinks the other stop action is a real
+ corosync process.
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2639 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-12-08 Angus Salkeld <asalkeld@redhat.com>
+
+ Allow empty (default) consensus timeout.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2638 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-12-08 Steven Dake <sdake@redhat.com>
+
+ Bump verion to 1.2.0.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2581 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Remove string overwrite if many recovery messages are originated.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2580 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Remove compiler warning in vsf_quorum.c.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2579 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Remove compiler warning in totemsrp.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2578 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Update to AUTHORS file.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2577 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-12-08 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ Update spec file to deal with new libsam
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2576 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Generate .pc file for new libsam
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2575 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-12-07 Steven Dake <sdake@redhat.com>
+
+ SAM man pages.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2574 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Set boolean indicating the retrans flag was set to 1 to 0 when setting retrans flag in token to zero.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2573 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Make assertions for range checking of message delivery check with the define instead of magic numbers that are not valid if the define changes.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2572 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-12-07 Jan Friesse <jfriesse@redhat.com>
+
+ Remove potentially thread unsafe call of strftime
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2571 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ SAM implementation merge
+ The SAM library provide a tool to check the health
+ of an application. The main purpose of SAM is to restart
+ a local process when it fails to respond to a healthcheck
+ request in a configured time interval.
+
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2570 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-12-07 Steven Dake <sdake@redhat.com>
+
+ Prevent lockup in recovery state in totem after 206 messages are originated.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2569 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix recovery messages to be proper length to remove segfault that occurs during recovery.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2568 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-12-06 Steven Dake <sdake@redhat.com>
+
+ Force consensus timer to be at minimum 1.2 * token to prevent one group of nodes from executing a token timeout in the COMMIT state while another node executes a consensus timeout, showing to applications as a temporary network partition.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2567 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-12-04 Christine Caulfield <ccaulfie@redhat.com>
+
+ Make man page match reality of totem configuration values.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2566 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ This puts multiple nodeids on each [QUORUM] Members line instead of putting each nodeid on a separate line. With more than a few nodes the excessive lines become a real nuisance, and anyone up around 32 nodes may literally be scrolling through hundreds of those lines.
+ from David teigland
+
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2565 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-12-03 Angus Salkeld <asalkeld@redhat.com>
+
+ stats: don't calloc the totemsrp stats struct.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2564 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Correct some ugly indentation.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2563 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ objdb: fix memory leaks when objects are destroyed.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2562 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-12-02 Angus Salkeld <asalkeld@redhat.com>
+
+ make sure key_names past from confdb are null terminated.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2561 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-12-02 Jan Friesse <jfriesse@redhat.com>
+
+ bsd: Fix mlockall on FreeBSD version >= 8.0
+ FreeBSD version 8.0 and greater supports mlockall
+ syscall correctly. So configure.ac is changed to detect
+ FreeBSD version and main.c is changed to support it.
+
+ Resolves: rhbz#513687
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2560 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-12-02 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ spec file cleanup
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2559 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-12-01 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ Fix threads vs fork init order
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2558 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-11-30 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ Fix stop regression
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2557 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Expose service.d config directory
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2556 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-11-30 Steven Dake <sdake@redhat.com>
+
+ Start pause timer at initialization so first gather doesn't result in pause timeout operations.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2555 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-11-30 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ Clean up init scripts and make a single generic one
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2554 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-11-29 Angus Salkeld <asalkeld@redhat.com>
+
+ Rename totem_new_msg_signal() to something more generic.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2553 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ coroipcs: Add a queue_size stats counter to each ipc connection.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2552 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ coroipcs: add logging for flow control state changes.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2551 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-11-27 Steven Dake <sdake@redhat.com>
+
+ Patch to use proper IFA on Linux platforms to match interface addresses when netmask is not 255.255.255.0.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2550 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-11-23 Angus Salkeld <asalkeld@redhat.com>
+
+ COVERITY 4: remove dead code in XYZ_dispatch().
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2549 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ COVERITY 17: fix exit handling in show_votes().
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2548 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ COVERITY 12: prevent overrun of logsys output buffers.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2547 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-11-22 Angus Salkeld <asalkeld@redhat.com>
+
+ COVERITY 13: prevent buffer overrun in quorum-tool.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2546 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ COVERITY 11: remove dead code from cpg_iteration_next().
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2545 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ COVERITY 14: free zcb_mapped if memory_map() fails.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2544 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ COVERITY 18: prevent deref after free.
+ Event deref_after_free: Dereferencing freed pointer "pi".
+
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2543 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-11-05 Andrew Beekhof <abeekhof@redhat.com>
+
+ Fix compilation on RHEL-4: If _GNU_SOURCE isn't defined, then neither is pthread_spinlock_t and compilation fails
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2542 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-10-28 Andrew Beekhof <abeekhof@redhat.com>
+
+ Prevent daemon from suppressing corefile generation
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2541 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-10-23 Steven Dake <sdake@redhat.com>
+
+ Bump version to 1.1.2.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2537 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Revert commit 2523 which results in segfaults under some workloads.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2536 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-10-21 Steven Dake <sdake@redhat.com>
+
+ Bump revision to 1.1.1.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2533 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-10-20 Steven Dake <sdake@redhat.com>
+
+ Resolve shutdown problems for pacemaker use case.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2531 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-10-18 Angus Salkeld <asalkeld@redhat.com>
+
+ Add a log_printf function to coroipcs so we can pass the log level
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2530 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-10-15 Angus Salkeld <asalkeld@redhat.com>
+
+ Avoid array out of bound error.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2529 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-10-14 Steven Dake <sdake@redhat.com>
+
+ Patch from jflesch to fix segfault when using sysv semaphores that the thread state is checked prior to the semaphore operation, not after it has completed.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2524 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ totem process group optimization to not copy data into staging buffer if it is to be immediately ordered by totemsrp. Instead pass that data as an iovector element.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2523 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-10-14 Angus Salkeld <asalkeld@redhat.com>
+
+ stats: prevent a div by zero if totem_count is zero.
+ patch by Chrissie
+
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2522 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-10-13 Angus Salkeld <asalkeld@redhat.com>
+
+ Fix the OSX build (broken by stats patches)
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2521 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-10-13 Andrew Beekhof <abeekhof@redhat.com>
+
+ Add SIGTERM support and have the init script wait for corosync to actually terminate. Bud rh#525552
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2520 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-10-12 Angus Salkeld <asalkeld@redhat.com>
+
+ Add some missing calls to increment the relevant stats.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2519 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ allow coroipcs to work without calling stats initialization.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2518 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add totem stats to objdb.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2517 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Remove silly warning in corosync-objdb
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2516 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add per service-function statistics.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2515 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add connection related statistics to the object db.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2514 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Test the key value size for typed keys.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2513 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ teach object_key_increment() key types.
+ This is so we can increment all integer types correctly.
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2512 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-10-10 Angus Salkeld <asalkeld@redhat.com>
+
+ Add value types to objdb keys.
+ This allows you to create a key with a know type.
+ And then get the type with the key value.
+
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2511 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-10-06 Christine Caulfield <ccaulfie@redhat.com>
+
+ This patche fixes a couple of small problems with votequorum:
+ - if a single node is booted with votequorum loaded then
+ corosync-quorumtool shows zero nodes and no votes.
+ - votequorum doesn't always tell the main quorum module when a new node
+ has joined the cluster (principally itself. this bug is actually tied
+ into the above)
+
+ I've also added quorum to the default list of services. As quorum has
+ been decoupled from sync it will not interfere with normal operations as
+ it used to do and it makes more sense to have it there than not.
+
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2510 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-09-25 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ Update spec file to enable IBA support and sync with 1.1.0 release
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2507 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-09-25 Steven Dake <sdake@redhat.com>
+
+ Change version to 1.1.0 in trunk.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2504 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Totem IBA implementation.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2481 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ make main_service_ready function static.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2480 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Remove unused variable in stress_cpgfdget.c.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2479 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Remove pointless warning.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2478 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-09-25 Angus Salkeld <asalkeld@redhat.com>
+
+ turn off _POSIX_THREAD_PROCESS_SHARED for uclibc
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2477 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-09-22 Steven Dake <sdake@redhat.com>
+
+ Correct pload printing operation.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2473 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-09-21 Steven Dake <sdake@redhat.com>
+
+ Fix merge error in previous commit.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2472 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Patch from Jerome to fix segfault in dispatch functions.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2468 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix abort with multiple cpg clients under heavy load.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2467 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-09-20 Steven Dake <sdake@redhat.com>
+
+ Remove warning in logsys compile related to const correctness.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2463 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Remove warning in coroipcc.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2462 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix sigpipe handling to ignore sigpipes on systems which support them.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2419 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Make delete operation work properly in coropoll.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2418 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-09-16 Andrew Beekhof <abeekhof@redhat.com>
+
+ Darwin libraries need -install_name otherwise they're not usable without DYLD_LIBRARY_PATH (which is highly unrecommended)
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2417 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-09-14 Steven Dake <sdake@redhat.com>
+
+ Fix error with revision 2415.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2416 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix dispatch returning TRY_AGAIN when using DISPATCH_ALL parameter because of regression caused by revision 2046:lib/coroipcc.c.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2415 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-09-10 Angus Salkeld <asalkeld@redhat.com>
+
+ log the built-in features at startup
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2411 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-09-09 Angus Salkeld <asalkeld@redhat.com>
+
+ add small-memory-footprint option to configure
+ This adds the following option to configure:
+ --enable-small-memory-footprint
+
+ When enabled the following defines are set
+ to reduce the overall memory footprint.
+
+ MESSAGE_SIZE_MAX=1024*64
+ MESSAGE_QUEUE_MAX=512
+ PROCESSOR_COUNT_MAX=16
+ IPC_REQUEST_SIZE=1024*64
+ IPC_RESPONSE_SIZE=1024*64
+ IPC_DISPATCH_SIZE=1024*64
+
+
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2410 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ don't return the ip address when the mask is not found
+ Currently totemip_copy (boundto,&ipaddr) is called even when the
+ required mask is not found.
+
+ This patch changes the behavior to only copy the ipaddr when the
+ mask is found.
+
+ The current behavior makes debugging an incorrect config really
+ confusing.
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2409 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Only insert the filename into the log, not the path.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2408 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-09-08 Christine Caulfield <ccaulfie@redhat.com>
+
+ Really add corosync-quorumtool
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2407 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add corosync-quorumtool
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2406 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-09-07 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ Fix missing symbol error when loading plugins without executive
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2405 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-09-07 Angus Salkeld <asalkeld@redhat.com>
+
+ Remove a double unlock in logsys.
+ In logsys there are a number of XYZ_unlocked() functions that are called
+ like this:
+
+ pthread_mutex_lock (&logsys_config_mutex);
+
+ XYZ_unlocked();
+
+ pthread_mutex_unlock (&logsys_config_mutex);
+
+ The XYZ_unlocked() functions should not do any (un)locking.
+ But _logsys_config_subsys_get_unlocked() unlocks if it finds the subsys.
+ This means that there is 1 lock and 2 unlocks.
+
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2404 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-09-07 Christine Caulfield <ccaulfie@redhat.com>
+
+ Return CS_ERR_NOT_EXIST if a client tries to contact a plugin that isn't loaded.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2403 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-09-07 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ Fix corosync-tools linking
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2402 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-08-31 Jan Friesse <jfriesse@redhat.com>
+
+ Real add of corosync-cpgtool
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2401 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Initial version of corosync-cpgtool
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2400 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Implementation of cpg_iteration functions
+ This functions allows iterate available cpg groups
+ and their members. API is modelled like ckpt iteration
+ functions.
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2399 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-08-28 Steven Dake <sdake@redhat.com>
+
+ Fix off by one calculation error resulting in assertion.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2398 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-08-28 Christine Caulfield <ccaulfie@redhat.com>
+
+ Send CURRENT callbacks to the dispatch FD rather than the callback one.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2397 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix nodelist passed to the quorum subsystem.
+ When a node left, the old nodelist was sent, sigh
+
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2396 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-08-28 Steven Dake <sdake@redhat.com>
+
+ Fix incorrect assertion with frame sizes of 9000.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2395 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-08-24 Steven Dake <sdake@redhat.com>
+
+ Allow finalize routines to occur inside dispatch routines.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2394 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-08-20 Jan Friesse <jfriesse@redhat.com>
+
+ Handle NULL callbacks in cpg, evs and confdb lib
+ Attached patches handle NULL callbacks in *_initialize
+ and *_dispatch. Handling is same as in quorum service. Now, when
+ callback is NULL -> no memcpy -> instance callbacks will have all
+ items set to NULL and in *_dispatch function is not called.
+
+ It changes cfg so now we are using continue instead of exit.
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2392 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-08-19 Jan Friesse <jfriesse@redhat.com>
+
+ Fix found_service_ver handling
+ Sometimes, when object_key_get doesn't return found_service_ver it
+ doesn't change old value and this value is then used in atoi what
+ will can cause fall of corosync. Patch fixes this case by setting
+ found_service_ver to NULL before call of object_key_get.
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2391 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix systems without _POSIX_THREAD_PROCESS_SHARED
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2390 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-08-17 Steven Dake <sdake@redhat.com>
+
+ Add test program that finds limits of cpg message size.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2389 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Proper limits checking for message sizes to allow ~1mb max message sizes for corosync.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2388 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Request user enter characters into terminal if entropy pool is empty for keygen rather then exiting without creating an auth key.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2387 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-08-17 Jérôme Flesch <jerome.flesch@netasq.com>
+
+ Fix value returned by lib/coroipcc_dispatch_get() in case recv() fails
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2386 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-08-12 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ Delay forking and closing of fds as much as possible to allow startup wrappers (such as cman_tool) to collect as much errors as possible in case of startup failure
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2385 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-08-10 Jan Friesse <jfriesse@redhat.com>
+
+ Swap item in cpg_joinlist
+ This patch add swab of header->size so big endian architectures
+ works with LE list and vica versa.
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2384 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-08-10 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ corosync: move logsys thread config with all the others
+ logsys thread priority was configured after forking the
+ wthread process and spread the scheduler priority config
+ across a large chunk of code in main.c
+
+ Now that logsys scheduler priority can be invoked at any time,
+ move the code together with corosync_setscheduler code.
+
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2383 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ logsys: fix segfault in logsys_thread_priority_set
+ logsys_thread_priority_set expects that wthread is already running
+ but doesn't perform any check if it is.
+
+ if logsys_thread_priority_set is invoked before forking the thread,
+ a segfault is guaranteed.
+
+ this changes to logsys_thread_priority_set ensure that a request
+ for a new scheduler priority is queued if the wthread is not
+ created yet and the new scheduler parameters are applied as early
+ as possible after the thread is created.
+
+ At the same time:
+
+ - add a few comments on clean up that needs to be done
+ - remove a redundant check for policy != SCHED_OTHER as that's
+ corosync need specific. logsys should simply accept the request
+ and apply it.
+
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2382 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-08-04 Jan Friesse <jfriesse@redhat.com>
+
+ Support for -v (version) feature
+ This can be usefull for easier way to get informations
+ of the corosync version from users. Version and SVN
+ revision (get by svninfo -c) are displayed.
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2381 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-08-04 Christine Caulfield <ccaulfie@redhat.com>
+
+ This patch makes a copy of the notifications list before calling the reload_notifications callbacks. This allows callback functions to manipulate the notifications list without causing corruption or strange loops.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2380 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-08-04 Steven Dake <sdake@redhat.com>
+
+ Use unnamed shared posix semaphores on platforms which support them.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2379 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Man page cleanups from Steven Whitehouse for cpg service.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2378 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Always keep autogenerated node ids in totem as LE even on BE arches. Have testcpg print out autogenerated nodeid properly on BE arch.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2377 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-08-03 Jan Friesse <jfriesse@redhat.com>
+
+ Support for systems where clock_gettime is not available
+ On some systems clock_gettime is not available so we are
+ testing availability and value of _POSIX_MONOTONIC_CLOCK.
+
+ On system without support of clock_gettime, we are using
+ old behaviour with function gettimeofday.
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2376 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-07-28 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ Fix spec file and update macro usage
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2374 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-07-27 Jan Friesse <jfriesse@redhat.com>
+
+ Support for monotime timer
+ This patch should solve problems with corosync and ntp, by using
+ clock_gettime where it make sense.
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2373 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-07-27 Steven Dake <sdake@redhat.com>
+
+ Add notification when totem has completed initialization.
+ This triggers the initialization of the service engines which may need totem
+ for initialization.
+
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2372 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add a target token set completed callback in totemrrp and below layers. Handle management of callback in totemsrp.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2371 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-07-23 Jan Friesse <jfriesse@redhat.com>
+
+ Handle NULL ver string in service
+ In case user not enter ver: in service section, whole
+ corosync falled with segfaul, because atoi was called
+ on NULL.
+
+ Now, in case of NULL, we rather not use atoi, and
+ return 0 directly.
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2370 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-07-23 Steven Dake <sdake@redhat.com>
+
+ Optimization of totemsrp and below by removing hdb usage. cpgbench shows results of 4% to 20% increase in tps and mbs depending on hardware.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2369 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-07-22 Jan Friesse <jfriesse@redhat.com>
+
+ Support for service.d
+ This patch is very similar to uidgid.d patch, but support for loading
+ services (so read service section).
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2368 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-07-21 Steven Dake <sdake@redhat.com>
+
+ Initial infrastructure changes to support iba. Split totemnet into totemiba and totemudp and have totemnet call the appropriate transport calls.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2367 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Darwin is missing the sched_setscheduler system call. Patch detects it and resolves the build failure.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2366 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-07-20 Jan Friesse <jfriesse@redhat.com>
+
+ Cpg synchronization patch for conf change messages
+ The root of the theoretical problem is that cpg_join or cpg_leave
+ messages are being sent via the C apis between synchronization. With
+ the current cpg, synchronization happens in confchg_fn, and then later
+ in cpg_sync_process. cpg_sync_process is called much later after
+ confchg_fn and introduces a small probability of a window of time for
+ queued in totem (but not yet ordered by totem) for those cpg_join and
+ cpg_leave operations to interact with the synchronization process which
+ should happen in one atomic operation but currently is two distinct
+ operations.
+
+ This patch deletes confchg_fn and make sends joinlist/downlist
+ in cpg_sync_process.
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2365 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Allow only one connection per (node, pid, grp)
+ This patch allows only one connection per (node, pid, grp_name) tuple.
+ This means, you cannot make more connection from one process to same
+ group_name. This is (I hope) how cpg should behave. In case, you will
+ try to do that, CPG_ERR_EXISTS error is returned.
+
+ Of course, there is no problem with creating:
+ - more connection with same (pid, grp) if nodeid is different
+ - more connection with same (node, grp) if pid is different (for example
+ after fork, or two distinct processes)
+ - more connection with same (node, pid) if grp is different (connect
+ one process to more cpgs).
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2364 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-07-16 Jan Friesse <jfriesse@redhat.com>
+
+ Add lcoroipcc as build requirement for stress_cpgcontext
+ This is needed for build without errors on system, where
+ lcoroipcc is not installed on system yet.
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2363 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-07-14 Andrew Beekhof <abeekhof@redhat.com>
+
+ Use the preferred prefix for the Pacemaker service
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2362 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-07-13 Steven Dake <sdake@redhat.com>
+
+ Add NAME entries to manpages.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2360 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-07-10 Steven Dake <sdake@redhat.com>
+
+ add stress_cpgcontext.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2359 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add stress_cpgfdget test case.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2358 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add stress test case for cpg and coroipcc zero copy buffer alloc and free operations.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2357 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix segfault when using zcb api of coroipcc under certain loads.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2356 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-07-10 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ Bump version in trunk
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2355 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-07-08 Steven Dake <sdake@redhat.com>
+
+ Add poll destroy to coroipcs.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2348 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add more tested platforms to list.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2347 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Updated INSTALL file.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2346 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-07-02 Jérôme Flesch <jerome.flesch@netasq.com>
+
+ BSD support: Fix EOF handling in coroipcs.c:req_setup_recv() and coroipcs:coroipcs_handler_dispatch()
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2345 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-07-01 Steven Dake <sdake@redhat.com>
+
+ Add ring id field to evs.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2341 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Set version field in totem header in case it isn't set by default.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2340 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Pass handle is evs callback functions.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2339 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Send ERR_SECURITY when invalid security context is provided via ipc clients.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2338 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Set ERR_SECURITY to 100 to give plenty of room for other people's error codes.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2337 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix build on bsd systems.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2336 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Align syncv2 on 8 byte boundaries.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2335 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Make compatibility mode none work properly.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2334 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Code cleanup for evs service from Wojtek.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2333 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-07-01 Jan Friesse <jfriesse@redhat.com>
+
+ Don't deliver cpg messages from unknown nodes
+ This patch fixes situation, when in the middle of
+ sync some node will send regular message before
+ another node will receive confch message, and regular
+ message is delivered to application. From application
+ point of view, this node is unknown -> don't expect
+ any messages.
+
+ Now, no such messages are delivered to application.
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2332 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-07-01 Steven Dake <sdake@redhat.com>
+
+ Add context get set man pages for evs.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2331 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add new man pages to Makfile.am
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2330 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add context get and set operations to evs handles and man pages.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2329 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add context get/set to See Also section of cpg man pages.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2328 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add see also reference to context get/set operation.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2327 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add votequorum_context_get/set man pages.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2325 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add man pages for confdb_context_get/set operations.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2324 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-06-30 Jim Meyering <jim@meyering.net>
+
+ remove unnecessary #include
+ * exec/evil.c: Don't include <signal.h>.
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2323 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ remove trailing blanks
+ * corosync.spec.in:
+ * exec/evil.c:
+ * exec/main.c:
+ * exec/mainconfig.c:
+ * exec/syncv2.c:
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2322 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-06-30 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ Reset version to 0.99 in configure.ac to unbreak rpm/srpm.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2321 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-06-30 Steven Dake <sdake@redhat.com>
+
+ Reset 0.98 in configure.ac to trunk so toplevel makefile works properly
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2319 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Export poll handle via coroapi.h.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2318 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix segfault during dispatch within confdb library.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2317 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-06-28 Steven Dake <sdake@redhat.com>
+
+ Static-ize some main.c variables.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2316 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Simplify notifications from totem at the notice level.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2315 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Remove hard coded sync values and use defines from coroapi.h.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2314 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Slay the debug messages coming out at notice level in totem.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2313 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Remove totemsrp warning.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2312 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Allow syncv2 to determine membership list when run in compatibility mode.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2311 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Follow synchronization model of event service so corosync without openais service engines can communicate with the openais whitetank event service in compatibility mode.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2310 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Send fake barriers for the event service when operating in compatibility mode whitetank.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2309 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-06-27 Angus Salkeld <asalkeld@redhat.com>
+
+ add "-p" option to corosync-objctl
+ This just adds a "-p" option to corosync-objctl.
+
+ So you can do the following (like sysctl).
+
+ corosync-objctl -p /path/to/object.conf
+
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2308 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-06-27 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ Fix rpm version generation and adapt release manager Makefile.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2307 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-06-27 Steven Dake <sdake@redhat.com>
+
+ Remove some debug printfs that snuck in.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2306 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Change sync_init api call to pass information relevant for making synchronization decisions.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2305 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-06-26 Steven Dake <sdake@redhat.com>
+
+ Add ability to detect process pause and not implode the membership algorithm when this occurs.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2304 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Previously if a process was interrupted by a signal it could become unkillable because the operation was retried on signal interrupts.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2303 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add syncv2.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2302 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add AMF_V2_SERVICE defintion
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2301 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix build error in evil.c
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2300 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix no boottime support warning.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2299 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add compatability option in config file. Defaults to whitetank. Add sync_mode to coroapi to indicate to corosync the service engine's desired compatibility mode.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2298 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ definition error in corodefs.h
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2297 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ sync-v1 onwire compat layer for raw corosync to communicate with whitetank.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2296 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-06-25 Steven Dake <sdake@redhat.com>
+
+ Define CMAN and CRM service ids.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2295 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Convert got joinlist message notice to debug level.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2294 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-06-25 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ Add support for make srpm and make rpm targets
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2293 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix make dist target
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2292 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-06-25 Jan Friesse <jfriesse@redhat.com>
+
+ Add database lock init to hdb_* functions
+ Without this, lock can be called to unitialized and locking unitialized
+ lock isn't good idea.
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2291 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add locking of database in hdb_handle_refcount_get
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2290 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-06-24 Steven Dake <sdake@redhat.com>
+
+ Remove totempg debug message.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2289 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add assembly to free list when it is removed from a configuration change as indicated by being in the left list.
+ This has side effect of clearing the assembly buffer the next time it is
+ referenced from the free list. This fixes a defect that stops forward
+ processing of the message streams because sync fails to finish when receiving
+ a sync message from a restarted processor because it throws away the message.
+
+
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2288 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-06-24 Ryan O'Hara <rohara@redhat.com>
+
+ Add hdb_handle_refcount_get call.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2287 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-06-23 Steven Dake <sdake@redhat.com>
+
+ Tidy's up startup printfs.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2286 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Change startup notice to Corosync Cluster Engine. Change 2008 to 2009 in copyright.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2285 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Remove "AIS" string from exit notice.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2284 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-06-22 Steven Dake <sdake@redhat.com>
+
+ Remove warning by casting properly in totemnet.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2283 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Rename request_shutdown to shutdown_request in coroapi.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2282 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add dump_state to coroapi.h. Need to remove logging output from signal handlers.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2281 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Sanitize -p option to not set scheduling parameters in all software.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2280 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-06-21 Jim Meyering <jim@meyering.net>
+
+ totemsrp: remove unnecessary cast to avoid "make syntax-check" failure
+ * exec/totemsrp.c (message_handler_memb_join): Remove unnecessary
+ cast of alloca return value.
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2279 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-06-21 Steven Dake <sdake@redhat.com>
+
+ Use HAVE_ALLOCA_H define before including alloca.h
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2278 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add tests for posix scheduling apis to configure.ac and use them to determine if we should set scheduling priorities or not.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2277 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Work around dlopen'ed objects not executing constructors on solaris platform.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2276 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Remove hdb constructor usage.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2275 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-06-20 Steven Dake <sdake@redhat.com>
+
+ Remove timersub redefine.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2274 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Set nosigpipe socket option on platforms that send sigpipes in coroipcc.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2273 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Remove use without init warning which is harmless.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2272 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Remove shadow warnings.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2271 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-06-19 Steven Dake <sdake@redhat.com>
+
+ Add (void *) casts for iovector assignments to remove compile warnings.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2270 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix unused variable on linux because of portage work.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2268 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Patch from Wojtek to fix Solaris segfault with compiler optimization.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2267 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-06-19 Jim Meyering <jim@meyering.net>
+
+ maint: remove trailing blanks
+ By running this command from a git-cloned directory:
+ git grep -z -l -E '[[:blank:]]+$' | xargs -0 perl -pi -e 's/[ \t]+$//'
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2266 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-06-19 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ Fix handling of sysconfdir
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2265 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Install basic operational directories
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2264 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Remove tags from example configuration
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2263 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-06-19 Steven Dake <sdake@redhat.com>
+
+ Warn user of missing dirs and exit gracefully.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2262 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Remove requirement of having uid and gid of "ais" on the system and allow nonroot users to access ipc if their uid/gid is in the /etc/corosync/uidgid.d directory.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2261 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Sanitize output of autogen.sh.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2260 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-06-18 Steven Dake <sdake@redhat.com>
+
+ Ensure Linux, BSD, Solaris, Darwin function with security authentication in IPC system.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2259 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-06-18 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ Fix rec_ident encoding for IPC
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2258 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ use $(INSTALL) instead of install for portability to other OS'es
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2257 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ flight recorder: enable temporary 0 buffer size protection
+ The flight recoder doesn't handle a 0 byte allocation properly
+ and it would fail miserably by allocating a single PAGE_SIZE
+ to handle the logging. That means an enormous performance hit
+ because of the constant wrapping around the buffer.
+
+ If any requested buffer is < 64000 bytes, then force to at least
+ 64000.
+
+ In future we will be able to handle small buffers properly, but
+ for now enable a simple workaround to protect us and the user.
+
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2256 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ flight recorder: switch from int to bytes for requested allocation
+ The flight recoder buffer size as specified in LOGSYS_DECLARE_SYSTEM
+ or _logsys_rec_init was expressed in number of ints. A developer asking
+ to allocate 512K would get a 2M allocation on a machine with sizeof(int) = 4.
+
+ This is confusing and the patch addresses it:
+
+ - rename rec_size to fltsize for external API (no type change),
+ because rec_size is used many times internally for other reasons
+ and it can be confusing.
+
+ - rename size to fltsize in _logsys_rec_init.
+
+ - document what we allocate and why.
+
+ - swap comments around to match the code.
+
+ - introduce a simple macro to perform rounding (stolen from linux-2.6.git).
+
+ - start shaping fdata header to better handle dynamic values:
+ * write the flt_data_size as first unsigned int the header.
+ * change corosync-fplay to read the value and alloc the right amount
+ of memory instead of hardcoding it again.
+
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2255 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-06-18 Steven Dake <sdake@redhat.com>
+
+ Add Jerome to AUTHORS file
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2254 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ add madvise nosync calls for bsd platform.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2253 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-06-18 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ logsys: remove leftover files from running tests
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2252 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ flight recorder: don't hardcode max arguments everywhere
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2251 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ logsys: port to new packed rec_ident version
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2250 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ logsys: add macros to pack/unpack rec_ident
+ rec_ident should contain 3 info: log level, subsystem id and
+ message type.
+
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2249 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ logsys: allow to use header files for #define's
+ most of the values in logsys.h are very useful for non logsys library
+ API users.
+
+ Allow to import them without sucking the whole lib.
+
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2248 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ logsys: update man page to reflect new changes
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2247 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ logsys: merge tags into rec_ident
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2246 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ logsys: drop LOGSYS_LEVEL_SECURITY
+ LOGSYS_LEVEL_SECURITY is specific to corosync/openais and it
+ is used only in the totem configuration.
+
+ Drop the special case from logsys that's meant to be a generic
+ logging library and specify the correct equivalent for totem config.
+
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2245 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-06-17 Jim Meyering <jim@meyering.net>
+
+ build: silence automake portability warnings
+ * configure.ac: Enable automake's -Wno-portability option.
+ We depend on GNU make.
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2244 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ autogen.sh: simply to a one-liner: autoreconf -i
+ * autogen.sh: Don't use "which" or uname, or...
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2243 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-06-16 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ Add missing prototype and fix white spaces
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2242 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-06-15 Steven Dake <sdake@redhat.com>
+
+ Fix build error from recent solaris porting.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2241 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-06-14 Steven Dake <sdake@redhat.com>
+
+ Use PF_UNIX on Solaris platforms instead of PF_LOCAL.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2240 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Use rsync -a instead of cp -a to install on Solaris.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2239 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Port of coroipc system to Solaris.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2238 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Patch from Jerome Flesch to correctly reference count on bsd and solaris platforms in the IPC system to avoid cpu spinning.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2237 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add iface checking for Solaris platform.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2236 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-06-12 Jan Friesse <jfriesse@redhat.com>
+
+ Make /etc/corosync/corosync.conf default configuration file
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2235 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Handle LCR problem with unloading "unneeded" components
+ In LCR, global variable g_component_handle is used to keep handle of loaded
+ component. If this variable has magic value (0xFFFFFFFF) it means,
+ "we loaded library, but that library doesn't have any component_register
+ call -> don't try to destroy interfaces list).
+
+ If this variable has other value, it means "we loaded library, it registers,
+ but it exports some interface, what we currently don't need, so we can delete
+ that handle from libraries/interfaces list" and variable is set to magic value,
+ or "we loaded library, it registers and exports what we need -> great return some
+ nice value", but nobody resets variable to it's magic value.
+
+ Sadly, if you have loaded some component (needed), then try to load component,
+ which don't have component_register function, previously loaded component handle
+ is destroyed.
+
+ This problem happened to clm and quorum services, and cause, that loaded
+ clm handle was destroyed, so EVT (which need clm) just falls.
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2234 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-06-11 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ Fix library linking fallout.. again
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2233 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-06-10 Steven Dake <sdake@redhat.com>
+
+ Modify totemnet to work properly on Solaris by setting variables in sendmsg data structure.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2232 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-06-10 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ Shared libs should not call exit but return error
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2231 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-06-10 Steven Dake <sdake@redhat.com>
+
+ Remove unused variable on platforms other then Solaris.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2230 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix compile on BSD platforms.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2229 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix semun definitions for various platforms.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2228 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-06-10 Christine Caulfield <ccaulfie@redhat.com>
+
+ Fix corosync-cfgtool -a so that it actaully produces some output!
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2227 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-06-09 Steven Dake <sdake@redhat.com>
+
+ Use PF_LOCAL to match BSD semantics of api calls.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2226 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Resolve bug where config changes are delivered in the wrong order on nodes that join and then open a cpg.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2225 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-06-09 Andrew Beekhof <abeekhof@redhat.com>
+
+ Decouple the decouples shutdown/startup order of lcrso's from the internal objdb order.
+ This is needed as the objdb order will change as modules are loaded/unloaded and is
+ also set up to unload non-default services last (which is the opposite of what
+ something like Pacemaker needs).
+
+ In the worst case, the current behavior leads to cluster services (dlm, ocfs2, etc)
+ failing during shutdown. This patch also ensures that if, for example, cpg is unloaded
+ then anything that depends on it is unloaded first.
+
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2224 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-06-07 Steven Dake <sdake@redhat.com>
+
+ Remove quorum.c from lcrso build list since its linked into main binary.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2223 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add support for buildling on Solaris platforms.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2222 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Call initializer directly for broken platforms which don't honor ctors in the shared object on dlopen. This could probably be more tidy to detect those OS platforms which don't do this instead of hardcoding to a specific platform we intend to port to.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2221 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Include limits.h in coroparse.c to properly define PATH_MAX.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2220 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Change NAME_MAX to FILENAME_MAX to compile properly on Posix OS.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2219 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Define MSG_NOSIGNAL if it is undefined by the base OS such as Solaris.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2218 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Conditionally compile on Solaris platforms msg_* flags in sendmsg header.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2217 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Include string.h in sq.h for memset() calls.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2216 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Make readdir operation portable by removing BSDism from coroparse.c.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2215 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add strsep_cs to replace strsep. -This line, and those below, will be ignored--
+ M exec/mainconfig.c
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2214 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ First run at adding support for corosync totemip determination.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2213 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Make coroipcs compile on Solaris.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2212 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Rename queue datastructure to cs_queue data structure because some fail operating system struct queue in the globally scoped headers.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2211 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Port of totemip to Solaris.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2210 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Port of logsys to Solaris.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2209 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ coroipcc port to Solaris.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2208 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-06-04 Christine Caulfield <ccaulfie@redhat.com>
+
+ Don't let corosync-keygen fail if /etc/ais already exists
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2207 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-06-03 Andrew Beekhof <abeekhof@redhat.com>
+
+ Fix compilation on OSX/Darwin
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2206 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Forward port the clear_node_high_bit from whitetank
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2205 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-06-02 Jim Meyering <jim@meyering.net>
+
+ totempg.c: don't truncate group list
+ * exec/totempg.c (totempg_groups_join): Fix typo s/=/+/ that
+ would mistakenly truncate totempg group list.
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2204 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-06-01 Jan Friesse <jfriesse@redhat.com>
+
+ Fix coroipcc linking
+ Fixes rhbz#499918
+
+ Functions from ckpt library (like aCkptCheckpointOpen,
+ saCkptSectionIterationInitialize, ...) internally uses corosync functions
+ reply_receive, reply_receive_in_buf, ... This functions are included in
+ coroipcc.c source file and uses global static variable ipc_hdb.
+
+ Without patch, coroipcc is linked to shared library (libcoroipcc.so) AND linked
+ with every corosync libraries (like cpg, ....), so global variable ipc_hdb is
+ included not only in libcoroipcc.so, but also in libcpg.so, ...
+
+ dlm_controld has function retrieve_plocks, and whole binary is linked with
+ libcoroipcc and libcpg. So ipc_hdb is included TWICE (so has TWO addresses).
+
+ Main problem causing the bug was, that reply_receive uses address from one
+ library, and reply_receive_in_buf uses other. This confuses check of hdb_get
+ function.
+
+ After removing linking of coroipcc.o to cpg, and rather use of dynamic version,
+ (this means, there is only one instance of ipc_hdb) problem disappeared.
+
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2203 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-06-01 Christine Caulfield <ccaulfie@redhat.com>
+
+ Add broadcast option to corosync
+ This is a forward port of the openais, whitetank, code.
+
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2202 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-05-31 Steven Dake <sdake@redhat.com>
+
+ Fix race condition in cpg service.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2201 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-05-30 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ Public headers should not include private config.h
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2200 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-05-22 Christine Caulfield <ccaulfie@redhat.com>
+
+ This patch adds the definition VOTEQUORUM_NODEID_US to the library, which is already implicitly zero.
+ It also adds VOTEQUORUM_NODEID_QDEVICE and makes the code that checks
+ for them more generic. This now allows you to change the number of votes
+ assigned to a quorum disk (for example)
+
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2199 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-05-20 Jan Friesse <jfriesse@redhat.com>
+
+ Support for uidgid feature
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2198 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ *Dispatch returns CS_ERR_BAD_HANDLE only on first hdb_get
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2197 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-05-20 Christine Caulfield <ccaulfie@redhat.com>
+
+ Adapt the deliver_fn in the YKD quorum plugin to the new tpg API.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2196 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Print a list of quorum members when it changes.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2195 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-05-18 Jim Meyering <jim@meyering.net>
+
+ avoid spurious failure of 'make syntax-check's sc_makefile_check
+ * pkgconfig/Makefile.am (lib%.pc): Add extra quotes to avoid
+ triggering check for use of obsolescent @VAR@ notation.
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2194 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ don't include <signal.h> when it's not used
+ * exec/coroparse.c: Likewise.
+ * exec/quorum.c: Likewise.
+ * exec/sync.c: Likewise.
+ * exec/totemmrp.c: Likewise.
+ * exec/totemnet.c: Likewise.
+ * exec/totemrrp.c: Likewise.
+ * exec/totemsrp.c: Likewise.
+ * exec/vsf_quorum.c: Likewise.
+ * exec/vsf_ykd.c: Likewise.
+ * lcr/uic.c: Likewise.
+ * lcr/uis.c: Likewise.
+ * lib/cfg.c: Likewise.
+ * services/cfg.c: Likewise.
+ * services/cpg.c: Likewise.
+ * services/evs.c: Likewise.
+ * services/pload.c: Likewise.
+ * services/testquorum.c: Likewise.
+ * services/votequorum.c: Likewise.
+ * test/testconfdb.c: Likewise.
+ * test/testcpg.c: Likewise.
+ * test/testcpgzc.c: Likewise.
+ * test/testzcgc.c: Likewise.
+ * tools/corosync-cfgtool.c: Likewise.
+ * tools/corosync-objctl.c: Likewise.
+ * tools/corosync-pload.c: Likewise.
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2193 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ don't include <assert.h> when it's not used
+ * exec/apidef.c: Likewise.
+ * exec/mainconfig.c: Likewise.
+ * exec/service.c: Likewise.
+ * exec/timer.c: Likewise.
+ * exec/totemconfig.c: Likewise.
+ * exec/totemmrp.c: Likewise.
+ * exec/vsf_quorum.c: Likewise.
+ * services/testquorum.c: Likewise.
+ * test/cpgbench.c: Likewise.
+ * test/cpgbenchzc.c: Likewise.
+ * tools/corosync-fplay.c: Likewise.
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2192 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ always include <config.h> before any other file
+ * test/cpgbench.c: Include <config.h> before any other file.
+ * test/cpgbenchzc.c: Ditto.
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2191 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ exec/schedwrk.c: include <config.h>
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2190 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ cfg.c: avoid useless if-before-free
+ * lib/cfg.c (corosync_cfg_ring_status_get): Avoid useless if-before-free
+ and change syntax to avoid triggering false-positive failure of
+ the "make syntax-check" sc_cast_of_argument_to_free rule.
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2189 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ remove trailing blanks
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2188 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-05-18 Christine Caulfield <ccaulfie@redhat.com>
+
+ When doing a controlled shutdown of corosync, we now send out a JOIN message with our node removed. This should speed up the case where a lot of nodes leave at the same time as they don't need to wait for the token timeout for each node.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2187 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-05-18 Jan Friesse <jfriesse@redhat.com>
+
+ coroparse: Handle different EOLs and pass error_string
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2186 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Remove duplicity in logsys code
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2185 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-05-13 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ Fix output to syslog
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2184 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-05-13 Christine Caulfield <ccaulfie@redhat.com>
+
+ Convert votequorum to use the proper message delivery API rather than the tpg_ calls. Also remove a lot of mess around those calls, such as headers and things that were needed for cman compatibility but which we will not need.
+ Fixes some handle changes that did not get picked up when
+ handles were changed from unsigned ints to hdb_handle_t
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2183 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-05-13 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ Logsys header clean (comments and whitespaces)
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2182 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix totem logging after logsys changes
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2181 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix logsys TAG handling
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2180 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-05-12 Christine Caulfield <ccaulfie@redhat.com>
+
+ Fix spelling of "Received" in sync.c
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2179 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-05-12 Jim Meyering <jim@meyering.net>
+
+ logsys.c: avoid possibility of buffer overrun
+ * exec/logsys.c (strcpy_cutoff): Add buf_len parameter, and never
+ write more than this number of bytes into "dest".
+ Change type of "cutoff" parameter from int to size_t.
+ Sentinel value changes from -1 to 0.
+ (log_printf_to_logs): Adapt to those changes.
+ Reverse condition of test so the much-shorter block is the "if-block".
+ Factor out a common subexpression for readability.
+ Exit the loop if output_buffer_idx ever reaches sizeof(output_buffer).
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2178 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ logsys.c: avoid redundant strlen in else-block
+ * exec/logsys.c (strcpy_cutoff): Also, with a field width (aka cutoff),
+ and a shorter-than-field-width string, don't write the same memory
+ twice: once with strncpy using NUL bytes, then again with spaces
+ via the memset.
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2177 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ logsys.c: factor out some duplication
+ * exec/logsys.c (log_printf_to_logs): Factor out repeated calls to
+ strcpy_cutoff.
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2176 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-05-12 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ Add debugging code to logsys.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2175 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-05-11 Jim Meyering <jim@meyering.net>
+
+ totemnet.c: Make totemnet_initialize definition match just-changed decl.
+ * exec/totemnet.c (totemnet_initialize): Declare deliver_fn's msg_len
+ parameter to be of type "unsigned int" (not size_t) to match decl.
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2174 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-05-11 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ Fix logging date format and add missing daemon name
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2173 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-05-09 Steven Dake <sdake@redhat.com>
+
+ Remove most iovector-ized functionality from totem and only make one malloc and memory copy call in totemsrp_mcast. The rest of the stack minus totempg then uses zero copies.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2172 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-05-06 Jim Meyering <jim@meyering.net>
+
+ fix missing-dependency bug, so as not to install bogus .pc files
+ * pkgconfig/Makefile.am (all .pc files): Depend on Makefile, so that
+ a change in $(prefix) there provokes regeneration of these files.
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2170 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-05-04 Jim Meyering <jim@meyering.net>
+
+ votequorum.c: avoid a new warning and add a comment in cpg.h
+ * votequorum.c: Avoid declaration of unused: ‘votequorum_instance_destructor’
+ * include/corosync/cpg.h (cpg_deliver_fn_t) [msg]: Add a comment explaining
+ why this member is not const.
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2169 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ avoid 'incompatible pointer type' compiler warning
+ * test/cpgverify.c (cpg_deliver_fn): Remove const.
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2168 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-05-04 Angus Salkeld <asalkeld@redhat.com>
+
+ add NTF_SERVICE to the service list
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2167 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-04-30 Steven Dake <sdake@redhat.com>
+
+ Do checking of handle code after we verify that handle could actually be in the handle database.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2166 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-04-29 Steven Dake <sdake@redhat.com>
+
+ Implement thread saftey in corosync trunk.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2165 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix leak caused by invalid put in hdb_handle_destroy.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2164 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-04-28 Andrew Beekhof <abeekhof@redhat.com>
+
+ Call all configured exec_dump_fn's when SIGUSR2 is received
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2163 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-04-28 Steven Dake <sdake@redhat.com>
+
+ Add cpgverify program to test directory.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2162 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-04-27 Andrew Beekhof <abeekhof@redhat.com>
+
+ Minor fixes to the build process on OSX
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2161 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-04-27 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ Fix debug: on option for logging purposes
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2160 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ add max limit error checks in logsys
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2159 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-04-27 Steven Dake <sdake@redhat.com>
+
+ Add mechanism to use logsysrec from inside totem stack.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2157 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Improve security of NSS implementation in totem.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2156 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-04-26 Steven Dake <sdake@redhat.com>
+
+ Fix evsverify failure.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2155 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-04-26 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ Fix --enable-nss default in configure.ac
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2154 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-04-26 Steven Dake <sdake@redhat.com>
+
+ Make libnss detection work properly.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2153 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-04-26 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ Fix pkgconfig file inclusion into release and pass distcheck
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2152 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-04-26 Steven Dake <sdake@redhat.com>
+
+ add Chrissie as author of totem NSS implementation.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2151 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Remove const from delivery callback to allow inplace endian changes of message contents.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2150 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ remove "AIS" from cfg.h header file.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2149 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Allow CPP linkage by adding extern "C" {} to external header files.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2148 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ remove config.h from public header file.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2147 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Remove useless APIs from coroipcs.c related to handling of overload conditions.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2146 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-04-25 Christine Caulfield <ccaulfie@redhat.com>
+
+ Add libnss security support to corosync.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2145 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-04-24 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ Bump SONAME to 4.0.0
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2144 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-04-24 Jim Meyering <jim@meyering.net>
+
+ logsys.c: avoid an unnecessary strlen call
+ * exec/logsys.c (strcpy_cutoff): Use strlen, then memcpy,
+ not strcpy, then strlen.
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2143 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-04-24 Jan Friesse <jfriesse@redhat.com>
+
+ Add Jan Friesse (me) to the list of Corosync authors
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2142 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-04-23 Steven Dake <sdake@redhat.com>
+
+ Remove mempool since it is unused and isn't going to be a feature in this release.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2141 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ add request_shutdown call to coroapi.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2140 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add logsys yield counter for the logsys thread.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2139 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-04-23 Jim Meyering <jim@meyering.net>
+
+ corosync.pc.in: Define Cflags
+ * pkgconfig/corosync.pc.in (Cflags): Define.
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2138 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ pkgconfig: correct and clean up Makefile.am
+ * pkgconfig/Makefile.am: Factor, add missing deps.
+ (pkgconf_LIBS): Remove unused var.
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2137 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-04-23 Steven Dake <sdake@redhat.com>
+
+ Modify property of loc script to be executable.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2136 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ remove rmd.h header file.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2135 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Include file cleanups.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2134 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Cleanup coroipcc.h header file to remove saHandleXXX and friends.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2133 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ coroipcs.h cleanup.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2132 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-04-23 Christine Caulfield <ccaulfie@redhat.com>
+
+ This patch removes the (now redundant) call to sync_primary_callback_fn when quorum changes.
+ As we established a while ago, quorum is independent of sync and all
+ this code does is segfault when called!
+
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2131 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-04-23 Steven Dake <sdake@redhat.com>
+
+ Remove priority inversion in logsys.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2130 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-04-23 Jim Meyering <jim@meyering.net>
+
+ exec/Makefile.am: require that copied code stays in sync
+ * exec/Makefile.am (check_logsys_log_printf_functions): New rule.
+ (check): Depend on check_logsys_log_printf_functions.
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2129 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ logsys.c: indent consistently
+ * exec/logsys.c (_logsys_log_printf): Indent with TABs to be
+ consistent with copied-from function, _logsys_log_vprintf.
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2128 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-04-23 Jan Friesse <jfriesse@redhat.com>
+
+ Make ipc_log_printf function working by adding _logsys_log_vprintf, which is mostly same as _logsys_log_printf but takes va_list as argument.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2127 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-04-23 Steven Dake <sdake@redhat.com>
+
+ use uint64_t for hdb_handle_t type and also specify some formatting strings for printing handles out of the handle database.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2126 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-04-22 Steven Dake <sdake@redhat.com>
+
+ Remove saHandleXXX and friends and use hdb instead.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2125 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-04-22 Jan Friesse <jfriesse@redhat.com>
+
+ Rewrite of CPG. It solves problems with double delete.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2124 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-04-22 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ Stop hardcoding /var
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2123 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-04-22 Jan Friesse <jfriesse@redhat.com>
+
+ Remove MESSAGE_REQ_CPG_GROUPS_GET call and all function using that.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2122 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-04-22 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ Kill all asserts from logsys and handle proper error return
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2121 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-04-22 Steven Dake <sdake@redhat.com>
+
+ Add missing header from last commit.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2120 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Reworking of include file dependencies.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2119 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-04-22 Jim Meyering <jim@meyering.net>
+
+ remove empty lines at end-of-file
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2118 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ remove all trailing blanks
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2117 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ perf: avoid writing 1MB of zero bytes
+ Don't initialize the entire just-allocated buffer to all zeroes.
+ The very next lines initialize all members except "data".
+ * exec/totempg.c (assembly_ref): Initialize the first byte of
+ assembly->data to 0, just in case someone uses it as a string.
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2116 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-04-22 Steven Dake <sdake@redhat.com>
+
+ Change shared memory to use mmap() system calls.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2115 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Zero copy feature for IPC transmits. Also integrated into CPG library service.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2114 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-04-21 Steven Dake <sdake@redhat.com>
+
+ Remove memory leak from new dispatch circular buffer mapped system.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2113 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-04-21 Jim Meyering <jim@meyering.net>
+
+ rename function: s/strstr_rs/strchr_rs/ to reflect new semantics
+ * exec/coroparse.c (parse_section):
+ * exec/util.c (strchr_rs, strstr_rs):
+ * exec/util.h (corosync_exit_error):
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2112 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ rewrite strstr_rs not to use strdup
+ strstr_rs used strdup and didn't handle failure. This change removes
+ the use of strdup as well as the uses of strstr, since all callers
+ passed a string of length 1 as the second argument. This also changes
+ the prototype so that the 2nd parameter is a byte, not a string.
+
+ * util.h (strstr_rs): Adjust prototype.
+ * util.c (strstr_rs): Rewrite/simplify.
+ * sa-confdb.c (strstr_rs): Remove duplicate definition.
+ * coroparse.c (parse_section): Update callers.
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2111 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-04-21 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ Fix pthread linking
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2110 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix uid and gid determination
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2109 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Move include config.h at the top as it's supposed to be
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2108 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-04-21 Jim Meyering <jim@meyering.net>
+
+ exce/main.c: handle strdup failure
+ * exec/main.c (main): Upon strdup failure, log the error and exit.
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2107 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ remove useless if-before-free tests
+ * exec/coropoll.c (poll_destroy): Remove useless if.
+ * exec/main.c (main): Likewise.
+ * include/corosync/hdb.h (hdb_destroy): Likewise.
+ * lcr/lcr_ifact.c (scandir): Likewise.
+ * lib/sa-confdb.c (load_config): Likewise.
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2106 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ services/confdb.c: avoid four warnings
+ * services/confdb.c (m2h): New function.
+ (message_handler_req_lib_confdb_object_iter): Use m2h rather than a cast.
+ (message_handler_req_lib_confdb_object_find): Likewise.
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2105 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-04-21 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ Guarantee that all logging buffers are flushed before we die
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2104 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add logsys_flush logsys API call to signal the logging thread
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2103 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add logging configuration backward compatibility layer
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2102 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix output filtering when debug is enabled
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2101 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-04-20 Jim Meyering <jim@meyering.net>
+
+ corosync-cfgtool.c: handle strdup failure gracefully
+ * tools/corosync-cfgtool.c (xstrdup): New function.
+ (main): Use it in place of strdup.
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2100 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-04-20 Steven Dake <sdake@redhat.com>
+
+ Use spinlocks in library handle references.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2099 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-04-20 Jim Meyering <jim@meyering.net>
+
+ schedwrk.c: avoid two int-pointer cast conversion warnings
+ * exec/schedwrk.c (void2handle, handle2void): New functions.
+ (schedwrk_do): Use void2handle rather than an unportable cast.
+ (schedwrk_create): Use handle2void rather than an unportable cast.
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2098 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-04-20 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ Fix libconfdb linking
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2097 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Improve logsys error handling in logsys_format_set and logsys_config_file_set_unlocked.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2096 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Rename corosync.conf to corosync.conf.example take 2
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2095 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Rename corosync.conf to corosync.conf.example
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2094 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ readd early log level check for performance reasons.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2093 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-04-20 Steven Dake <sdake@redhat.com>
+
+ throw away mode in totempg was operating as a global variable, when it is possible for different nodes to be in different configurations of throw away. This patch makes the variable instanced.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2092 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-04-20 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ Add logsys v3
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2091 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-04-18 Steven Dake <sdake@redhat.com>
+
+ Add missing schedwrk files.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2090 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ add schedwrk_create and schedwrk_destroy coroapi functions.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2089 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Initialize pload context properly.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2088 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Move QUICKSTART to INSTALL and update it.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2087 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add AUTHORS file.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2086 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Remove declaration of data struct inside code.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2085 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Remove warning in evsbench.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2084 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add fatal error call to ipc initializations.y
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2083 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ check result of fgets in testcpg.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2082 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Remove warnings about objdb that casts a const char * to a char *.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2081 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Remove warnings about typedefs in apidef.c.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2080 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Rework how dispatch functions so service engines work properly.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2079 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-04-15 Jim Meyering <jim@meyering.net>
+
+ configure.ac: enable gcc's -Wshadow warning
+ * configure.ac (WARNLIST): Add -Wshadow to the list.
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2078 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ cpg.c: rename file-scoped global to avoid shadowing warnings
+ * services/cpg.c: s/req_exec_cpg_downlist/g_req_exec_cpg_downlist/
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2077 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ vsf_ykd.c: Rename param to avoid shadowing global "ydk_state"
+ * exec/vsf_ykd.c (ykd_state_endian_convert): Rename param:
+ s/ydk_state/state/
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2076 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ services/cfg.c move shadowed decl into scope where used
+ * services/cfg.c (message_handler_req_lib_cfg_tryshutdown):
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2075 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ corosync-fplay.c: don't shadow file-scoped global, "record"
+ * tools/corosync-fplay.c: Rename: s/record/g_record/.
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2074 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ testvotequorum1.c: don't shadow file-scoped global, "handle"
+ * test/testvotequorum1.c (main): Rename: s/handle/g_handle/.
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2073 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ corosync-fplay.c: avoid shadowin: s/index/idx/
+ * tools/corosync-fplay.c (printer_totempg_mcast_fits):
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2072 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ coroipcs.c: don't shadow functions read and write
+ * exec/coroipcs.c (req_setup_recv): rename locals:
+ s/read/n_read/; s/write/n_write.
+ Also declare param to be const.
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2071 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ totemnet.c: don't shadow crypto.h type, "hmac_state"
+ * exec/totemnet.c (encrypt_and_sign_worker): Rename a local var:
+ s/hmac_state/hmac_st/
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2070 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ don't shadow file-scoped global, "handle"
+ * test/testquorum.c: Rename: s/handle/g_handle/.
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2069 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ wthread.c: Rename file-scoped type to avoid shadows.
+ * exec/wthread.c (struct worker_thread_t): Rename from
+ struct worker_thread.
+ (start_worker_thread): Rename from function "worker_thread".
+ * exec/wthread.h (struct worker_thread_group) [threads]: Update
+ member type: s/struct worker_thread/struct worker_thread_t/
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2068 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ don't shadow the global type name, "timer_handle"
+ * exec/coropoll.c (poll_timer_delete): Rename locals and/or params.
+ * exec/timer.c (corosync_timer_delete): Likewise.
+ (corosync_timer_expire_time_get): Likewise.
+ * exec/tlist.h (timerlist_del, timerlist_expire_time): Likewise.
+ (timerlist_pre_dispatch, timerlist_post_dispatch): Likewise.
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2067 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ list.h: avoid shadowing warning
+ * include/corosync/list.h: Don't use "remove" as param name.
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2066 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ coroipcc.c: avoid shadowing warning
+ * lib/coroipcc.c: Don't use "read" as param name.
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2065 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ totemsrp.c: more "const" propagation
+ * exec/totemsrp.c (message_handler_memb_commit_token): Don't cast away
+ const on "memb_commit_token". This exposed a const violation.
+ Fix that with minor rearrangement and an added memcpy.
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2064 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ totemsrp.c: avoid a const-correctness problem
+ * exec/totemsrp.c (message_handler_memb_merge_detect): Don't modify
+ the now-const "msg" parameter. Instead, use a local copy.
+ Patch by Steven Dake.
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2063 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ totemrrp.h, totemsrp.h, totemnet.h: const+size_t
+ * exec/totemrrp.c (totemrrp_initialize):
+ * exec/totemrrp.h (totemrrp_initialize):
+ * exec/totemsrp.c (handler_functions, main_deliver_fn):
+ (main_iface_change_fn):
+ * exec/totemnet.c (totemnet_deliver_fn, totemnet_iface_change_fn):
+ (encrypt_and_sign_worker, ucast_sendmsg, mcast_sendmsg):
+ (totemnet_mcast_worker_fn, totemnet_initialize):
+ (totemnet_token_send, totemnet_mcast_flush_send):
+ (totemnet_mcast_noflush_send, totemnet_token_target_set):
+ * exec/totemnet.h (TOTEMNET_FLUSH):
+ * exec/totemrrp.c (totemrrp_deliver_fn, totemrrp_iface_change_fn):
+ (totemrrp_token_seqid_get, rrp_deliver_fn, rrp_iface_change_fn):
+ * exec/totemsrp.c (handler_functions, main_token_seqid_get):
+ (srp_addr_copy_endian_convert, message_handler_orf_token):
+ (message_handler_mcast, message_handler_memb_merge_detect):
+ (memb_join_endian_convert, memb_commit_token_endian_convert):
+ (orf_token_endian_convert, mcast_endian_convert):
+ (memb_merge_detect_endian_convert, message_handler_memb_join):
+ (message_handler_memb_commit_token):
+ (message_handler_token_hold_cancel, main_deliver_fn):
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2062 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ * README.devmap: Update a prototype.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2061 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ change a few "int msg_len" to "size_t msg_len"; adjust docs
+ * lib/cpg.c (cpg_mcast_joined):
+ * lib/evs.c (evs_mcast_joined, evs_mcast_groups):
+ * man/cpg_initialize.3:
+ * man/evs_initialize.3:
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2060 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ corosync-keygen.c: diagnose a few more failures
+ * tools/corosync-keygen.c (main): Diagnose short reads, failed mkdir
+ and fchmod; detect write failure. Close file descriptors.
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2059 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-04-14 Steven Dake <sdake@redhat.com>
+
+ Autodetect build environment for configure for developers.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2058 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-04-10 Steven Dake <sdake@redhat.com>
+
+ Fix compile warning in main.c.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2057 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Cast a const away in an iovector.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2056 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Remove warnings from wthread.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2055 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Remove qualifier check in warnings list.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2054 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Remove admin_state_set and admin_state_get.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2053 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Remove warning in keygen and report error on fchown appropriately.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2052 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Remove warning in corosync-objctl.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2051 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add spin locks for critical sections in hdb api.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2050 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-04-09 Jim Meyering <jim@meyering.net>
+
+ coroapi.h: Make totem_mcast's *iovec param const.
+ * include/corosync/engine/coroapi.h (struct corosync_api_v1):
+ [totem_mcast]: Make *iovec param const.
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2049 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ cpg.h, objdb.h, coroaph.h: more const/size_t
+ * include/corosync/cpg.h (cpg_callbacks_t):
+ * include/corosync/mar_cpg.h (marshall_to_mar_cpg_name_t):
+ * lib/cpg.c (cpg_join, cpg_leave):
+ * lib/cpg.c (cpg_mcast_joined): make iovec const.
+ * include/corosync/cpg.h (cpg_mcast_joined): update prototype
+ ...
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2048 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ coroapi.h: change lib_handler_fn's *msg to be const
+ Make a tiny type change and watch it propagate.
+ * include/corosync/engine/coroapi.h
+ (struct corosync_lib_handler) [lib_handler_fn]: Change type
+ of 2nd parameter: s/void *msg/const void *msg/.
+ Propagate the above into cfg.c and votequorum.c:
+ * services/cfg.c (message_handler_req_lib_cfg_get_node_addrs):
+ Constification exposed a bug in this function whereby it mistakenly
+ modified storage through its now-const *msg parameter. Since it
+ did that solely to store a temporary result, we've changed it
+ to use a local variable instead.
+ * services/votequorum.c (message_handler_req_lib_votequorum_setvotes):
+ Likewise.
+ * exec/vsf_quorum.c: add const to msg param.
+ * services/evs.c: Likewise.
+ * services/pload.c: Likewise.
+ * services/cpg.c: Likewise.
+ * services/confdb.c: Likewise.
+ * exec/coroipcs.h: signature of coroipcs_handler_fn_lvalue must match
+ that of lib_handler_fn; noted via main.c.
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2047 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ testevsth.c: const+size_t: evs_deliver_fn, evs_confchg_fn
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2046 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-04-08 Jim Meyering <jim@meyering.net>
+
+ coroipcc.h (coroipcc_msg_send_reply_receive): Make res_len size_t.
+ * include/corosync/coroipcc.h (coroipcc_msg_send_reply_receive):
+ change type of res_len parameter.
+ * lib/coroipcc.c (coroipcc_reply_receive): Likewise.
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2045 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ sync the rest of the code with previous header changes
+ * exec/coroipcs.c (coroipcs_response_send)
+ (coroipcs_dispatch_send):
+ * exec/coroipcs.h (handler_fn_get):
+ * include/corosync/cpg.h (cpg_deliver_fn_t, cpg_confchg_fn_t):
+ * test/cpgbench.c (cpg_bm_confchg_fn, cpg_bm_deliver_fn):
+ * test/testcpg.c (print_cpgname, DeliverCallback)
+ (ConfchgCallback):
+ * test/testcpg2.c (deliver, confch):
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2044 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ cpg.h, coroapi.h: more size_t and const changes
+ * include/corosync/cpg.h (cpg_deliver_fn_t, cpg_confchg_fn_t)
+ (cpg_groups_get_fn_t):
+ * include/corosync/engine/coroapi.h (ipc_response_send)
+ (ipc_dispatch_send, tpg_join, tpg_leave, tpg_groups_mcast)
+ (tpg_groups_reserve):
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2043 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ sync the rest of the code with previous header changes
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2042 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ make all priv_data_pt pointers non-"const"
+ I'd suspected this would be necessary, but until now hadn't
+ found a case in which it actually was. That case:
+ totemconfig.c's totem_key_change_notify.
+ It has a priv_data_pt parameter that is used like this:
+
+ struct totem_config *totem_config = priv_data_pt;
+
+ and totem_config is in turn passed as arg #2 to
+ totem_volatile_config_read, where it is decidedly non-const.
+
+ git grep -l 'const void \*priv' \
+ |xargs perl -pi -e 's,const (void \*priv_data_pt),$1,'
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2041 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ coroapi.h, confdb.h, objdb.h: big s/int/size_t/ change
+ * exec/mainconfig.c (objdb_get_string, objdb_get_int):
+ * exec/totemconfig.c (objdb_get_string, objdb_get_int)
+ (totem_config_keyread, totem_key_change_notify):
+ * include/corosync/confdb.h (confdb_callbacks_t):
+ * include/corosync/engine/coroapi.h (group_len, object_len)
+ (key_len, validate_callback, object_key_change_notify_fn_t)
+ (object_create_notify_fn_t, object_destroy_notify_fn_t)
+ (object_notify_callback_fn_t, object_reload_notify_fn_t)
+ (object_create, object_key_create, object_find_create)
+ (object_key_get, object_key_replace, object_key_delete)
+ (object_iter, object_key_iter, object_name_get)
+ (object_key_iter_from, object_key_increment)
+ (object_key_decrement):
+ * include/corosync/engine/objdb.h (object_key_change_notify_fn_t)
+ (object_create_notify_fn_t, object_destroy_notify_fn_t)
+ (object_len, key_len, validate_callback, object_create)
+ (object_key_create, object_find_create, object_key_get)
+ (object_key_replace, object_key_delete, object_iter)
+ (object_key_iter, object_name_get, object_key_iter_from)
+ (object_key_increment, object_key_decrement):
+ * lib/confdb.c (confdb_object_create, confdb_key_create)
+ (confdb_key_delete, confdb_key_get, confdb_key_increment)
+ (confdb_key_decrement, confdb_key_replace, confdb_object_find)
+ (confdb_object_iter, confdb_key_iter):
+ * lib/sa-confdb.c (confdb_sa_object_create, confdb_sa_key_create)
+ (confdb_sa_key_delete, confdb_sa_key_get)
+ (confdb_sa_key_increment, confdb_sa_key_decrement)
+ (confdb_sa_key_replace, confdb_sa_object_find)
+ (confdb_sa_object_iter, confdb_sa_key_iter):
+ * lib/sa-confdb.h:
+ * services/confdb.c (message_handler_req_lib_confdb_key_replace):
+ * services/votequorum.c (objdb_get_string, objdb_get_int)
+ (quorum_key_change_notify, votequorum_objdb_reload_notify):
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2040 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ totemconfig.c: don't hard-code "128"...
+ * exec/totemconfig.c (read_keyfile): Don't hard-code "128".
+ Use sizeof(...) instead.
+ Avoid duplicate "close(fd)" calls.
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2039 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ totemconfig.c: don't let a key of length > 128 clobber memory
+ * exec/totemconfig.c (totem_config_keyread): Reject a key with length
+ greater than that of our private_key buffer.
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2038 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ totem.h: use symbolic array dimensions in public struct members
+ * include/corosync/totem/totem.h:
+ (TOTEM_PRIVATE_KEY_LEN, TOTEM_RRP_MODE_BYTES): Define.
+ (struct totem_config): Use the new names, rather than literals.
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2037 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ totempg.h: change type of totempg_group.group_len from int to size_t
+ * include/corosync/totem/totempg.h (struct totempg_group) [group_len]:
+ Change member type from int to size_t.
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2036 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ rmd.h: adjust types (const+size_t) of prototype
+ * include/corosync/rmd.h: ...even though there are no definitions
+ for these functions.
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2035 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ sync.c: avoid printf format warning
+ * exec/sync.c (sync_deliver_fn): cast to unsigned long int, use %lu
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2034 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ sync.c: avoid warning about now-unused variables
+ * exec/sync.c (vsf_none, vsf_iface): Remove decls of now-unused
+ file-scoped variables.
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2033 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ convert each "size_t iov_len" declaration to "unsigned int iov_len"
+ Via this command:
+ git grep -l -E 'size_t[[:blank:]]+iov_len' \
+ | xargs perl -pi -e 's/((?:^|,)\s*)size_t\s+(iov_len)/${1}unsigned int $2/'
+
+ Affected files and (functions/macros):
+ * exec/totempg.c (totempg_groups_mcast_groups)
+ (totempg_groups_send_ok_groups):
+ * include/corosync/evs.h (evs_callbacks_t):
+ * include/corosync/totem/totempg.h (TOTEMPG_SAFE):
+ * lib/evs.c (evs_mcast_joined, evs_mcast_groups):
+ * man/cpg_mcast_joined.3:
+ * man/evs_mcast_groups.3:
+ * man/evs_mcast_joined.3:
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2032 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Convert all "int iov_len" decls to "unsigned int iov_len".
+ Used this command:
+ git grep -l 'int iov_len' \
+ | xargs perl -pi -e 's/((?:^|,)\s*)(int iov_len)/${1}unsigned $2/'
+
+ Here's an approximate (autogenerated by vc-chlog) list of affected
+ file names and functions/macros:
+ * README.devmap:
+ * exec/coroipcs.c (sending_allowed_private_data)
+ (coroipcs_response_iov_send, msg_send, msg_send_or_queue)
+ (coroipcs_dispatch_iov_send):
+ * exec/coroipcs.h (handler_fn_get):
+ * exec/main.c (deliver_fn, main_mcast):
+ * exec/main.h (FALSE):
+ * exec/sync.c (vsf_iface, sync_deliver_fn):
+ * exec/totemmrp.c (totemsrp_handle_in, pg_deliver_fn)
+ (totemmrp_deliver_fn, totemmrp_initialize, totemmrp_mcast):
+ * exec/totemmrp.h (TOTEMMRP_H_DEFINED):
+ * exec/totemnet.c (iov_len, encrypt_and_sign_worker)
+ (ucast_sendmsg, mcast_sendmsg, totemnet_token_send):
+ * exec/totemnet.h (TOTEMNET_FLUSH):
+ * exec/totempg.c (deliver_fn, totempg_deliver_fn, mcast_msg)
+ (totempg_groups_initialize, totempg_groups_mcast_joined)
+ (totempg_groups_joined_reserve):
+ * exec/totemsrp.c (iov_len, totemsrp_recv, totemsrp_deliver_fn)
+ (totemsrp_initialize, totemsrp_mcast, token_send):
+ * exec/totemsrp.h (TOTEMSRP_H_DEFINED):
+ * exec/vsf_ykd.c (ykd_deliver_fn):
+ * include/corosync/coroipcc.h (handleInstanceDestructor):
+ * include/corosync/cpg.h (cpg_callbacks_t):
+ * include/corosync/engine/coroapi.h (ipc_response_iov_send)
+ (ipc_dispatch_iov_send, totem_mcast, tpg_init, tpg_joined_mcast)
+ (tpg_joined_reserve, tpg_groups_mcast, tpg_groups_reserve):
+ * include/corosync/totem/totempg.h (TOTEMPG_SAFE):
+ * lib/coroipcc.c (coroipcc_msg_send)
+ (coroipcc_msg_send_reply_receive)
+ (coroipcc_msg_send_reply_receive_in_buf):
+ * lib/cpg.c (cpg_mcast_joined):
+ * lib/util.h (versionsSupported):
+ * services/pload.c (send_message):
+ * services/votequorum.c (conn, quorum_deliver_fn):
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2031 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ continue pulling previous thread: mostly constification
+ * exec/apidef.c (typedef_tpg_join, typedef_tpg_leave)
+ (typedef_tpg_groups_mcast, typedef_tpg_groups_send_ok):
+ * exec/sync.c (barrier_data_process, sync_barrier_send)
+ (sync_start_init, sync_service_init, sync_start_process)
+ (sync_service_process, sync_deliver_fn, sync_request_send)
+ (sync_request):
+ * exec/sync.h (name):
+ * exec/totemmrp.c (totemmrp_callback_token_create):
+ * exec/totemmrp.h (TOTEMMRP_H_DEFINED):
+ * exec/totempg.c (list, app_confchg_fn)
+ (callback_token_received_fn, totempg_callback_token_create)
+ (totempg_groups_mcast_joined, totempg_groups_joined_release)
+ (totempg_groups_mcast_groups):
+ * exec/totemsrp.c (callback_fn, totemsrp_confchg_fn)
+ (totemsrp_initialize, totemsrp_callback_token_create):
+ * exec/totemsrp.h (TOTEMSRP_H_DEFINED):
+ * exec/vsf_ykd.c (ykd_state_send_msg, ykd_attempt_send_msg)
+ (ykd_confchg_fn):
+ * include/corosync/engine/coroapi.h (timer_add_absolute)
+ (totem_ifaces_print, totem_ip_print, totem_callback_token_create)
+ (sync_request, plugin_interface_reference):
+ * include/corosync/totem/totempg.h (TOTEMPG_SAFE):
+ * services/cpg.c (cpg_confchg_fn):
+ * services/pload.c (msgs_sent, pload_service_engine)
+ (send_message, start_mcasting):
+ * services/votequorum.c (conn, quorum_confchg_fn):
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2030 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ *_confchg_fn: make pointer params const, change *_entries to be size_t
+ * exec/main.c (confchg_fn):
+ * exec/quorum.h (sync_callback_fn_t):
+ * exec/sync.c (sync_ring_id, barrier_data_process)
+ (sync_start_init, sync_service_process, sync_primary_callback_fn)
+ (sync_deliver_fn, sync_confchg_fn):
+ * exec/sync.h (name):
+ * exec/totemmrp.c (totemsrp_handle_in, pg_confchg_fn)
+ (totemmrp_confchg_fn, totemmrp_initialize):
+ * exec/totemmrp.h (TOTEMMRP_H_DEFINED):
+ * exec/totempg.c (confchg_fn, totempg_confchg_fn)
+ (totempg_groups_initialize):
+ * include/corosync/engine/coroapi.h (tpg_init, confchg_fn)
+ (sync_abort):
+ * include/corosync/totem/totempg.h (TOTEMPG_SAFE):
+ * services/cfg.c (shutdown_reply, cfg_confchg_fn)
+ (message_handler_req_exec_cfg_ringreenable):
+ * services/cpg.c (api, cpg_confchg_fn):
+ * services/evs.c (MESSAGE_REQ_EXEC_EVS_MCAST, evs_confchg_fn):
+ * services/pload.c (MESSAGE_REQ_EXEC_PLOAD_MCAST)
+ (pload_confchg_fn):
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2029 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ no-op change: s/gruop/group/ in prototypes and documentation
+ * include/corosync/engine/coroapi.h (tpg_join, tpg_leave):
+ * man/evs_mcast_groups.3:
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2028 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ totem: const+unsigned+size_t
+ * exec/totempg.c (totempg_groups_mcast_groups):
+ (totempg_groups_send_ok_groups):
+ * include/corosync/totem/totem.h (interface_count):
+ (private_key_len, threads, heartbeat_failures_allowed):
+ * include/corosync/totem/totempg.h:
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2027 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ rmd.h: s/int/size_t; const-correctness changes...
+ * include/corosync/rmd.h: in spite of these being unused interfaces
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2026 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ lcr_ckpt.h: unused file: const/size_t
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2025 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ ipc_evs.h: s/int/size_t
+ * include/corosync/ipc_evs.h (msglen, member_list_entries):
+ (left_list_entries, joined_list_entries, group_entries, msg_len):
+ (group_entries, msg_len, member_list_entries):
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2024 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ evs.h: s/int/size_t; const-correctness changes
+ * exec/sync.c (barrier_data_confchg_entries):
+ * include/corosync/evs.h (evs_deliver_fn_t, evs_confchg_fn_t):
+ (evs_callbacks_t):
+ * lib/evs.c (MIN, evs_join, evs_leave, evs_mcast_joined):
+ (evs_mcast_groups, evs_membership_get):
+ * test/evsbench.c (evs_deliver_fn, evs_confchg_fn):
+ * test/evsverify.c (evs_deliver_fn, evs_confchg_fn, main):
+ * test/testevs.c (evs_deliver_fn, evs_confchg_fn, main):
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2023 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ quorum.h (quorum_set_quorate_fn_t): make first param const
+ * exec/quorum.h (sync_callback_fn_t):
+ * exec/sync.c (current_members_cnt, sync_primary_callback_fn):
+ * exec/sync.h (name):
+ * exec/vsf_quorum.c (sync_primary_callback_fn):
+ (quorum_api_set_quorum):
+ * exec/vsf_ykd.c (ykd_primary_callback_fn):
+ * include/corosync/engine/coroapi.h (sync_callback_fn_t):
+ * include/corosync/engine/quorum.h (quorum_set_quorate_fn_t):
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2022 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ quorum.h (quorum_set_quorate_fn_t): s/int/size_t/
+ propagate the change:
+ * include/corosync/engine/quorum.h (quorum_set_quorate_fn_t):
+ * exec/vsf_quorum.c (quorum_view_list_entries):
+ (quorum_api_set_quorum, quorum_exec_init_fn):
+ * exec/vsf_ykd.c (ykd_primary_callback_fn):
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2021 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-04-07 Steven Dake <sdake@redhat.com>
+
+ Remove wrong project name.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2020 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Forward port of sync v1 engine from whitetank and rework of quorum engine to not break syncing.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2019 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-04-07 Jim Meyering <jim@meyering.net>
+
+ accommodate iov_len of type size_t (i.e., never negative)
+ * services/pload.c (send_message): Don't test for iov_len < 0,
+ since it can no longer happen.
+ * lib/evs.c: Fix a typo in an iov_len-related FIXME comment.
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2018 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ jhash.h (jhash2): make first parameter const
+ * include/corosync/jhash.h (jhash2): const.
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2017 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ lcr_comp.h: size_t
+ * include/corosync/lcr/lcr_comp.h (struct lcr_comp, struct lcr_iface):
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2016 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ list.h (list_empty): Make param const.
+ * include/corosync/list.h (list_empty): Make param const.
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2015 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ mar_cpg.h: make "src" params const.
+ * include/corosync/mar_cpg.h:
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2014 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ mar_gen.h: make params const
+ * include/corosync/mar_gen.h (get_mar_name_t, mar_name_match): const
+ * exec/util.h (get_mar_name_t, mar_name_match): Remove unneeded decls.
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2013 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ totemip.h: const'ify
+ * include/corosync/totem/totemip.h: Add const to prototypes.
+ * exec/totemip.c (totemip_equal, totemip_copy): Adjust.
+ (totemip_copy_endian_convert, totemip_localhost_check): Likewise.
+ (totemip_sockaddr_to_totemip_convert): Likewise.
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2012 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ sq.h: const'ify, and avoid NULL-deref
+ * include/corosync/sq.h (sq_init): Avoid NULL-deref on malloc failure.
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2011 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ queue.h: Replace #ifdef COROSYNC_SOLARIS...
+ * include/corosync/queue.h: Remove #ifdef COROSYNC_SOLARIS
+ in favor of agnostic "#ifdef queue".
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2010 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ logsys.h (logsys_format_set): Change return type, adjust param type.
+ * include/corosync/engine/logsys.h:
+ * exec/logsys.c (logsys_format_set): Return -1 upon strdup failure.
+ Change type of param to "const char *".
+ * exec/logsys.c (logsys_init): Adjust use.
+ * exec/mainconfig.c (corosync_main_config_read_logging): Adjust uses.
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2009 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-04-03 Steven Dake <sdake@redhat.com>
+
+ Revert constructor priority in logsys.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2008 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Remove extra printf from coropoll.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2007 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix timers not expiring.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2006 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-04-03 Jim Meyering <jim@meyering.net>
+
+ remove 3 useless casts
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2005 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ confdb.h (confdb_reload) Add errbuf_len parameter and propagate.
+ * include/corosync/confdb.h (confdb_callbacks_t):
+ * lib/confdb.c (confdb_reload):
+ * lib/sa-confdb.c (confdb_sa_reload):
+ * lib/sa-confdb.h:
+ * test/testconfdb.c (main):
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2004 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ confdb_sa_write: propagate errbuf_len parameter
+ * lib/sa-confdb.c (confdb_sa_write): Propagate errbuf_len parameter.
+ * lib/sa-confdb.h: Update prototype
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2003 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ confdb.h: error_text vs. buflen
+ * lib/confdb.c (MIN): Define.
+ (confdb_write): Use new errbuf_len parameter.
+ Also note bugs (Chrissie confirms) that error_text is not
+ set in two error-return cases.
+ * test/testconfdb.c (do_write_tests): Update use of confdb_write.
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2002 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ confdb.h: continue API changes: const+size_t
+ * include/corosync/confdb.h (confdb_object_create_notify_fn_t):
+ (confdb_object_delete_notify_fn_t):
+ * tools/corosync-objctl.c (tail_object_created, tail_object_deleted):
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2001 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ print "?" in place of non-printing bytes of obj/key/val values
+ * tools/corosync-objctl.c: Include <ctype.h>
+ (print_name): New function.
+ (tail_key_changed): Use it to avoid printing garbage to screen.
+ * include/corosync/confdb.h (confdb_key_change_notify_fn_t): Convert
+ type of "int" length params to "size_t".
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2000 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ confdb.h (confdb_key_change_notify_fn_t): Make 3 params "const"
+ * include/corosync/confdb.h (confdb_key_change_notify_fn_t):
+ Make 3 params const.
+ * tools/corosync-objctl.c (find_object_of_type_t, callbacks):
+ (tail_key_changed): Don't write into would-be-const members.
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1999 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ cfg.h: mark "address_length" as an unused member
+ * include/corosync/cfg.h: Add a FIXME comment.
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1998 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ cfg.h: adjust parameter types: const+s/int/size_t/
+ * lib/cfg.c (corosync_cfg_get_node_addrs): Make "max_addrs" size_t.
+ (corosync_cfg_kill_node): Make "reason" const.
+ * include/corosync/cfg.h: Update prototypes.
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1997 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ cfg.h: add const
+ * lib/cfg.c (corosync_cfg_service_load): Make service_name "const".
+ (corosync_cfg_service_unload): Likewise.
+ * include/corosync/cfg.h: Update prototypes.
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1996 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ coroipcc. h (coroipcc_dispatch_recv): Add a buflen parameter.
+ * lib/coroipcc.c (coroipcc_dispatch_recv): Update definition, and...
+ (memcpy_swrap): ... add a parameter here, too.
+ * include/corosync/coroipcc.h (coroipcc_dispatch_recv):
+ * lib/cfg.c (corosync_cfg_dispatch):
+ * lib/confdb.c (confdb_dispatch):
+ * lib/cpg.c (cpg_dispatch, cpg_flow_control_state_get):
+ * lib/evs.c (evs_dispatch):
+ * lib/quorum.c (quorum_dispatch):
+ * lib/votequorum.c (votequorum_dispatch):
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1995 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ coroipcc.h: add "const" to msg_send_reply_* "iov" parameters
+ * include/corosync/coroipcc.h (coroipcc_msg_send_reply_receive_in_buf):
+ Make "iov" const.
+ * lib/coroipcc.c (coroipcc_msg_send): Make iov const.
+ (coroipcc_msg_send_reply_receive): Likewise.
+ (coroipcc_msg_send_reply_receive_in_buf): Likewise.
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1994 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ confdb.c: add missing mutex-unlock calls after coroipcc_dispatch_recv
+ * lib/confdb.c (confdb_dispatch):
+ The code in lib/cfg.c's (corosync_cfg_dispatch) is nearly identical
+ to that in lib/confdb.c's (confdb_dispatch), but lacked two
+ pthread_mutex_unlock calls.
+
+ 2009-04-03 Jim Meyering <meyering@redhat.com>
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1993 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-04-03 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ Drop unrequired struct
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1992 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix logsys construct execution priority
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1991 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-04-02 Steven Dake <sdake@redhat.com>
+
+ Patch to use snprintf where appropriate to avoid buffer overrun.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1990 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-04-01 Jim Meyering <jim@meyering.net>
+
+ corosync-objctl.c: remove a just-added "const"
+ * tools/corosync-objctl.c (get_key): Remove just-added const from
+ 2nd parameter.
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1989 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-04-01 Steven Dake <sdake@redhat.com>
+
+ Patch to document uid/gid and to default to allowing ais user to access services of corosync.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1988 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-04-01 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ add fileline/function_name support in corosync
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1987 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix last build warning in mainconfig.
+ Add a missing const.
+
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1986 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-04-01 Jim Meyering <jim@meyering.net>
+
+ remove unused file-scoped global
+ * tools/corosync-fplay.c (records_printed): Remove.
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1985 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ avoid prototype warnings, constify
+ * tools/corosync-fplay.c: Make many parameters and local pointers const.
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1984 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ remove unused functions and variable
+ * tools/corosync-fplay.c (sync_printer_nada): Remove function.
+ * tools/corosync-objctl.c (get_child_name): Remove function.
+ * test/evsverify.c (msg): Remove unused variable.
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1983 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ avoid prototype warnings
+ * test/evsbench.c: Declare functions/vars static.
+ * test/evsverify.c: Likewise.
+ * test/testcpg2.c: Likewise.
+ * test/testcpg.c: Likewise.
+ * test/logsysbench.c: Likewise.
+ * test/cpgbench.c: Likewise.
+ * exec/sync.c: Likewise.
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1982 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ * test/testevs.c: avoid 2 warnings, decl "static"
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1981 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ declare many functions "static" (also avoids missing prototype warnings)
+ * exec/main.c (sigintr_handler, serialize_lock, serialize_unlock):
+ (serialize_lock, serialize_unlock):
+ * exec/sync.c (sync_start_init, sync_callbacks_load):
+ * exec/vsf_ykd.c (ykd_state_init):
+ * lcr/uis.c (cmd1):
+ * services/pload.c (send_message, token_callback, start_mcasting):
+ * tools/corosync-cfgtool.c (service_load_do, service_unload_do):
+ (shutdown_do, showaddrs_do, killnode_do, usage_do):
+ * tools/corosync-fplay.c (totemip_print, print_string_len):
+ (sync_printer_confchg_set_sync, sync_printer_set_sync_state):
+ (sync_printer_process_currentstate):
+ (sync_printer_process_get_shouldsync):
+ (sync_printer_checkpoint_release):
+ (sync_printer_checkpoint_transmit, sync_printer_section_transmit):
+ (sync_printer_checkpoint_receive, sync_printer_section_receive):
+ (sync_printer_nada, sync_printer_confchg_fn):
+ (printer_totemsrp_mcast, printer_totemsrp_delv):
+ (printer_totempg_mcast_fits, sync_printer_service_process):
+ * tools/corosync-objctl.c (get_child_name, get_parent_name):
+ (get_key):
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1980 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ * exec/apidef.c: Include "apidef.h".
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1979 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ timer.c: connect with its published prototypes
+ * exec/timer.c: Include "timer.h".
+ * exec/timer.h (corosync_timer_init): Make return type in prototype
+ match the one in the function definition.
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1978 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ add "void" parameter list to avoid "isn't prototype" warning
+ * exec/objdb.c (objdb_wrlock, objdb_rdlock, objdb_rdunlock):
+ (objdb_wrunlock):
+ * services/cfg.c (send_shutdown, check_shutdown_status):
+ * services/votequorum.c (send_expectedvotes_notification):
+ * tools/corosync-cfgtool.c (shutdown_do):
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1977 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-04-01 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ Fix internal API usage and add support for file_name
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1976 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix build warning
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1975 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-03-30 Jim Meyering <jim@meyering.net>
+
+ totemip.c: avoid 1 warning
+ * exec/totemip.c (totemip_print): Add const.
+ * include/corosync/totem/totemip.h: Ditto.
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1974 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ evsverify.c: avoid 1 warning
+ * test/evsverify.c: Add a const.
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1973 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ testcpg.c: avoid 1 warning
+ * test/testcpg.c (sigintr_handler): Mark as "noreturn".
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1972 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ evsbench.c: avoid 1 warning
+ * test/evsbench.c (sigintr_handler): Mark as "noreturn".
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1971 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ apidef.c: avoid 1 warning
+ * exec/apidef.c (_corosync_public_exit_error): Mark as "noreturn".
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1970 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ main.h: avoid 1 warning
+ * exec/main.c (corosync_exit): Mark as "noreturn".
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1969 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ logsys.c: avoid 1 warning
+ * exec/logsys.c (logsys_conf): Add const.
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1968 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ util.h: avoid 2 warnings
+ * exec/util.h (_corosync_out_of_memory_error): Mark as "noreturn".
+ (_corosync_exit_error): Likewise.
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1967 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ logsys.c: avoid 1 warning
+ * exec/logsys.c (logsys_worker_thread): Mark function as "noreturn".
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1966 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ wthread.c: avoid 1 warning
+ * exec/wthread.c (worker_thread): Mark function as "noreturn".
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1965 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ uis.c: don't infloop upon poll failure (e.g., ENOMEM)
+ * lcr/uis.c (lcr_uis_server): Return NULL for any poll failure
+ other than EINTR. This also avoids a warning.
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1964 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ mar_gen.h, cfg.c: avoid 1 warning
+ * services/cfg.c (message_handler_req_exec_cfg_killnode):
+ * include/corosync/mar_gen.h (marshall_to_mar_name_t):
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1963 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ mainconfig.c: avoid 2 warnings
+ * exec/mainconfig.c (uid_determine, gid_determine): Add const.
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1962 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ service.c: avoid 5 warnings
+ * exec/service.c (struct default_service): Make "name" const.
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1961 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ totempg.h: avoid a warning
+ * include/corosync/totem/totempg.h (struct totempg_group):
+ Make "group" const.
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1960 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ main.c: avoid a few warnings FIXME: merge with another?
+ * exec/main.c (ipc_log_printf): Add const.
+ (main): tweak config_iface handling
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1959 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ testvotequorum1.c: avoid 5 warnings
+ * test/testvotequorum1.c (node_state): Return "const char *".
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1958 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ evsbench.c; avoid a format mismatch warning
+ * test/evsbench.c (evs_deliver_fn): %s vs. void*
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1957 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ coroparse.c: add const: avoid 2 warnings
+ * exec/coroparse.c: Add const. Tweak s/fp==0/fp==NULL/
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1956 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ services/testquorum.c: avoid a warning
+ * services/testquorum.c (key_change_notify): Add const attributes.
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1955 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ avoid format mismatch warning
+ * test/testquorum.c (quorum_notification_fn): Add casts to
+ match formats. Use unsigned formats for unsigned values.
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1954 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ testcpg2.c: avoid 1 warning
+ * test/testcpg2.c (main): Add a const-discarding cast.
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1953 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ testevs.c: avoid 2 more warnings
+ * test/testevs.c: Declare global to be "static const".
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1952 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ * test/testcpg.c (main): Remove decl of unused var.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1951 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ confdb.c, objdb.h, coroapi.h: add a few const, remove one: 4 fewer warnings
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1950 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ confdb.c: add a few const: avoid 3 more
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1949 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ coroipcs.h: avoid 3 warnings
+ * exec/coroipcs.h: Forward-declare "struct iovec".
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1948 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ avoid 1 warning
+ * services/evs.c (message_handler_req_exec_mcast): Introduce
+ a deliberate const-discarding cast and mark it with a comment.
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1947 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ object_write_config: add const to remove one more
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1946 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ logsys.c: fix two more warnings
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1945 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ merge with "in progress" -- down 6 to 73 warnings
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1944 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ in progress: avoid warnings
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1943 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ votequorum.c (votequorum_qdisk_register): add "const" to avoid 1 more warnings
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1942 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ votequorum.c: add "const" to avoid 2 more warnings
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1941 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ avoid 3 warnings
+ votequorum.c (kill_reason): Use "const char*" as return type, not "char *".
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1940 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ avoid 7 warnings
+ (struct sync_callbacks), (struct corosync_service_engine) [name]:
+ Make member const.
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1939 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ votequorum.c: add "const" to avoid 2 more warnings
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1938 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ totem*: add "const" to avoid 3 more warnings
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1937 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ totem*: add "const" to avoid 1 more warning
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1936 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ totem*: add "const" to avoid 1 more warning
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1935 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ vsf_type: add "const" to avoid warning
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1934 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ totemconfig.c: avoid another warning
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1933 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ * exec/totemconfig.c: eliminate 8 const-related warnings
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1932 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ objdb.c (object_reload_config): add const
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1931 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ * exec/objdb.c (object_create): make "object_name" param const
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1930 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ add const to 3 params
+ * include/corosync/engine/objdb.h (object_key_change_notify_fn_t):
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1929 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ objdb.c, etc: add "const" to avoid warnings
+ * exec/objdb.c:
+ * include/corosync/engine/coroapi.h:
+ * include/corosync/engine/objdb.h:
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1928 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ uis.c: avoid warnings
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1927 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ corosync-fplay.c: make more robust, avoid warnings
+ * tools/corosync-fplay.c (main): Diagnose malloc,open, and read failures
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1926 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ service.[ch]: remove 7 const-related warnings
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1925 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ coroipcs.[ch]: remove 4 const-related warnings
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1924 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ totempg.c: remove one const-related warning
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1923 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ objdb.h: sync const-related from coroapi.h
+ * include/corosync/engine/objdb.h: mirror const-related changes
+ to coroapi.h. FIXME: all of these identical API's should not
+ be separately modifiable.
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1922 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ totempg.c: remove one const-related warning
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1921 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ pload.c: make a couple functions/interfaces const-correct
+ * services/pload.c: Remove unused file-scoped global "msg_no".
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1920 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ logsys_config_facility_set: make "name" parameter const
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1919 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ cfg.c: nearly warning-free
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1918 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ cpg.c: resolve almost all warnings
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1917 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ timer.c: don't infloop upon poll failure (e.g., ENOMEM)
+ * exec/timer.c (prioritized_timer_thread): Remove unreached
+ call to pthread_exit after infloop.
+ Return NULL for any poll failure other than EINTR.
+ Use "continue" rather than an equivalent "goto".
+ Return NULL upon failed pthread_setschedparam.
+ This also avoids a warning.
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1916 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ logsys: detect write failure and avoid a file descriptor leak
+ * exec/logsys.c (logsys_log_rec_store): Close output file descriptor
+ and detect any failure.
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1915 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ totemconfig: avoid a file descriptor leak in the common case
+ * exec/totemconfig.c (read_keyfile): Don't leak a file descriptor.
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1914 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-03-30 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ Fix pkgconfig generation
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1913 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-03-25 Steven Dake <sdake@redhat.com>
+
+ Make all threads use same scheduling priority even with -p option specified to avoid deadlock in spinlocks.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1912 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-03-25 Christine Caulfield <ccaulfie@redhat.com>
+
+ Fix IPC when running on mac OS/X
+ Note that OS/X seems to be rather stingy about its IPC resources, so if things
+ crash you will probably have to clean up before starting it all again.
+
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1911 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ The IPC system smply concatenates SOCKETDIR with run/<socketname> so if th euser forgets to add a trailing slash to the name: eg
+ ./configure --with-socket-dir=/var/run
+
+ then the socket is created as /var/runcorosync.ipc
+
+ This patch adds the slash into the name generation printf.
+
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1910 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-03-24 Steven Dake <sdake@redhat.com>
+
+ Appears to fix compile errors on macosx.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1909 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Change strcpy to sprintf to fix compile error.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1908 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-03-24 Jim Meyering <jim@meyering.net>
+
+ Do not perform arithmetic on "void*" pointers.
+ * exec/vsf_ykd.c (ykd_deliver_fn): Do not perform "void*" arithmetic.
+ * services/votequorum.c (quorum_deliver_fn): Likewise.
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1907 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ avoid performing 'void *' arithmetic, and add a few const attributes
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1906 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ avoid 6 warnings
+ * services/votequorum.c (objdb_get_int): Make "key" const.
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1905 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ avoid 8 warnings
+ * exec/totemconfig.c (objdb_get_string): Make "key" const.
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1904 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ avoid 9 warnings
+ * test/logsysbench.c (bm_finish): Make parameter "const".
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1903 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ avoid 13 warnings
+ * exec/mainconfig.c (objdb_get_string): Make "key" const.
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1902 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ avoid 22 warnings
+ * exec/totemconfig.c (objdb_get_int): Make "key" const.
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1901 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ avoid compiler warnings
+ * lcr/lcr_ifact.c (lcr_component_register): Remove decl of unused var.
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1900 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ avoid infloop upon out-of-memory or out-of-semaphores
+ * coroipc.c (cslib_service_connect): Upon shmget failure
+ loop only when errno == EEXIST. Any other error now translates
+ to res_setup.error.
+ Likewise for semget.
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1899 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-03-24 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ Make confdb log level consistent with the other services
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1898 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-03-23 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ Fix expansion order within the Makefile.am with the pleasent effect to avoid to include .lcrso files in make dist target
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1895 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-03-23 Jim Meyering <jim@meyering.net>
+
+ autogen.sh: prefer "automake" over automake-1.9
+ * autogen.sh: ...and don't accept ancient versions of automake.
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1893 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-03-23 Steven Dake <sdake@redhat.com>
+
+ Change dist to build corosync-trunk.tar.gz.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1891 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-03-22 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ Fix pkgconfig list of libraries we provide after ipc rework
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1890 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix 64bit alignment issue in totempg
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1889 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-03-22 Steven Dake <sdake@redhat.com>
+
+ Change OPENAIS to COROSYNC in libversions definitions.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1888 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Change OPENAIS to COROSYNC in ipc ifdefs.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1887 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Allow ipcc library to work on some arches which have different parameter passing requirements for enums.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1886 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Abstracted Shared Memory IPC library
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1885 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-03-21 Steven Dake <sdake@redhat.com>
+
+ This patch fixes a crash in cpg.c where a group is left befopre cpg_finalise is called. It can cause the process_info structure to be removed twice from the group list.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1884 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-03-20 Jim Meyering <jim@meyering.net>
+
+ avoid buffer overrun when there are more than 128 path entries
+ * lcr_ifact.c (PATH_LIST_SIZE): Define.
+ (path_list): Use it.
+ (ld_library_path_build): Don't store into path_list[path_list_entries]
+ if the counter is too large.
+ (ldso_path_build): Likewise.
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1883 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ don't store (and later deref) NULL upon strdup failure
+ * lcr_ifact.c (ld_library_path_build, ldso_path_build):
+ Handle strdup failure.
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1882 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ don't segfault upon failed strdup
+ * sa-confdb.c (load_config): Handle out-of-memory.
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1881 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-03-20 Steven Dake <sdake@redhat.com>
+
+ Revert last change which broke corosync.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1880 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Reworked not to require stmt-after-decl support, plus another to fix a bug that would arise when parsing more than 128 paths.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1879 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ While looking at used of LCRSODIR, I saw an unchecked strdup. That could lead to a NULL dereference.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1878 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-03-19 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ - Every .c file should include "config.h" to get the right defines...
+ - services/Makefile.am: add include search paths for config.h
+
+ - include/corosync/cs_config.h.in exports LCRSODIR and SOCKETDIR
+
+ - tools/Makefile.am: drop -D defines for dirs that are now in
+ cs_config.h or config.h
+
+ - configure.ac: sanitize prefix and exec_prefix paths. Export DIRS in
+ *config.h
+
+ - lib/Makefile.am: : drop -D defines for dirs that are now in
+ cs_config.h or config.h. Add rule to build lcr_ifact.o or building from
+ lib/ fails miserably
+
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1877 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-03-19 Steven Dake <sdake@redhat.com>
+
+ Remove some unnecessary serializer functions.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1876 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Dont clobber stck on strings with length of zero.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1875 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Don't clobber stack on strings with length of zero.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1874 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Updated TODO for corosync.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1873 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-03-19 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ Fix corosync.pc installation
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1872 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add missing libs from pkgconfig generation
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1871 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix logsys SONAME
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1870 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Don't use EXTRA_DIST in install/uninstall
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1869 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-03-18 Steven Dake <sdake@redhat.com>
+
+ Serialize access to service engines.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1868 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix coroapi.h header errors.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1867 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-03-18 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ Add missing uninstall-local targets and fix configuration intall target
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1866 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ More cleanup for distcheck to work
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1865 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-03-18 Christine Caulfield <ccaulfie@redhat.com>
+
+ Add a dummy parameter to totemip_iface check so that it compiles on Darwin.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1864 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-03-18 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ Fix DARWIN_OPTS expansion
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1863 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix more soname= at linking
+ Start fixing distcheck
+
+ White space cleanups
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1862 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-03-17 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ - tidy up whitespaces
+ - try to keep everything < 80 cols
+
+ - stop installing testing lcrso
+
+ - fix soname= invokation
+
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1861 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix doc stuff
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1860 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Update index.html to reflect new changes in man/Makefile.am
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1859 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Drop tarball name from AC_INIT as it confuses the hell out of what we need
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1858 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix the whole manpage stuff
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1857 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add support for SOCKETDIR
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1856 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add corosync.pc support
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1855 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ remove hardcoded /var and use localstatedir instead.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1854 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-03-16 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ configure.ac: - Fix white space for --help. - Drop LCRSODIR as global and move it to local directory.
+ all */Makefile.am:
+ - export -DDIRECTORY_NAME as required (for now only LCRSO and
+ SYSCONFDIR)
+
+ top level Makefile.am:
+ - drop hardcoded ETCDIR that is just wrong and use the configured one
+
+ *.c files around:
+ - drop hardcoded ETCDIR and use configured one.
+
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1853 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix LCRSO handling
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1852 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Make everything < 80 cols
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1851 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ remove comment
+ fix quoting
+
+ make GCC test portable
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1850 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Major configure.in/ac cleanup
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1849 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-03-13 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ - Fix macro typo for PROG_CC_C_O.
+ - add --enable-debug configure option to #define DEBUG 1 and set
+ compiler options to default to -O0.
+
+ - restore default -O3.
+
+ - Drop some random leftovers (CC_IN_CONFIGURE, AISPREFIX, SSH path check
+ and ppc64 -m64).
+
+ - Remove yet another GCC test as -g is automatically detected by
+ autoconf macros.
+
+ - Cleanup a bit deprecated ARCH section.
+
+ - Tidy up RESULT section.
+
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1848 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ - remove --enable-static option as it is not required. This was a leftover from gcc-2.x something time. corosync binary should always be built dynamic.
+ - fix quorum_* target as it was missing the list of objects to be linked
+ in.. doh!
+
+ - fix object dependencies between TARGET, TARGET_OBJS and TARGET_SRC.
+ This also fixes the build/relink issues at install times that have been
+ noted before.
+
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1847 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-03-12 Steven Dake <sdake@redhat.com>
+
+ All integers received from objdb_get_int had invalid handle type.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1846 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Use nocheck flagging on confchg iteration of handle ids.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1845 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-03-12 Christine Caulfield <ccaulfie@redhat.com>
+
+ Fix testconfdb use of object handles.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1844 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-03-12 Steven Dake <sdake@redhat.com>
+
+ Set correct OBJECT_PARENT_HANDLE define in coroapi.h
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1843 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add handle checking to the hdb system.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1842 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix several errors in objdb notification handling, hdb_handle_t type conversion errors, indentation, and do hdb_handle_put after instance data is used instead of before.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1841 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Use hdb_handle_t for handle type in service.c.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1840 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Use hdb_handle_t for handle type in lcr_ifact.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1839 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-03-11 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ Fix library linking
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1838 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix more build/install glitches
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1837 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-03-11 Steven Dake <sdake@redhat.com>
+
+ Fix broken error check in commit 1818.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1836 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-03-11 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ 1) kill all those "for" shell loops. They are dangerous (as they don't report install failures) and it's just overhead since $(INSTALL) can do the same.
+ 2) make sure to create our directories with $(INSTALL). Not sure I did
+ catch them all yet, but at least a good bunch. This also fix the
+ corosync.conf install error I introduced in the previous commit.
+
+ 3) Handle SONAME automatically. This is the most intrusive change across
+ the board:
+
+ * configure.in now defines the system wide SOMAJOR, SOMINOR, SOMICRO
+ and SONAME and exports them to the Makefile.
+ * exec/Makefile.am, lib/Makefile.am are now updated to use those vars
+ rather than hardcoded version.
+
+ 4) Bump the SOMAJOR to 3 as agreed since we did change both API and ABI.
+
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1835 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Dear pacemaker.. you will not take over this project! MUAHAH
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1834 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Drop ld.conf file that is now unrequired
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1833 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Readd pkgconfig subdir to the build system and port it to autoconf
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1832 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add entries to maintainer-clean target
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1831 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-03-11 Steven Dake <sdake@redhat.com>
+
+ Remove warnings from coroipc.c.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1830 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Remove warnings from ipc.c
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1829 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-03-10 Christine Caulfield <ccaulfie@redhat.com>
+
+ Fix some const warnings
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1828 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-03-10 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ Add dynamic timestamp on/off
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1827 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-03-10 Steven Dake <sdake@redhat.com>
+
+ Remove const warnings in crypto.c.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1826 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Remove qualifier errors in main.c
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1825 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Remove const warnings from uic system.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1824 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ change some char * to const char * to match usage in system in lcr.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1823 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix const qualifiers in lcr_ifact.c.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1822 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix missing prototypes in totempg.c.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1821 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix missing prototypes in totemmrp.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1820 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix missing prototypes and mismatched prototypes in totemmrp.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1819 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add missing hdb_handle_put in totemsrp and handle errors in mkdir and chdir properly.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1818 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Remove string literal warnings from totemsrp.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1817 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add missing prototypes in totemsrp.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1816 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Remove pointer math warnings from totemsrp.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1815 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Define undefined prototypes
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1814 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Remove string literal warnings from totemrrp.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1813 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Remove const warnings from main.c.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1812 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Remove type casting to (char *) in logsys.h.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1811 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Remove pointer math from totempg.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1810 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Remove pointer math warnings from totemnet.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1809 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Remove const warnings in totemip code.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1808 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-03-10 Christine Caulfield <ccaulfie@redhat.com>
+
+ Quorum checks the ring ID is new before initiating a sync. Unfortunately it copies the ring ID BEFORE checking it so there is always a match.
+ Sigh
+
+ This patch fixes it.
+
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1807 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-03-10 Steven Dake <sdake@redhat.com>
+
+ Remove const warnings relating to logsys global definitions.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1806 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Remove logsys warnings.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1805 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Remove const warnings in totempg.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1804 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Remove const warnings from totemsrp.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1803 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Remove qualifier warnings regarding totemrrp.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1802 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Remove const/nonconst assignment warnings in totemnet.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1801 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Remove leftover from automake merge.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1800 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add missing committed file for automake.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1799 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Automake. The journey begins.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1798 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-03-10 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ Add logsys_format_get to logsys API.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1797 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ logsys_format_set should use its own internal copy of format_buffer
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1796 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-03-09 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ Cleanup logsys format init around to use default settings
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1795 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-03-06 Christine Caulfield <ccaulfie@redhat.com>
+
+ The IPC patch broke CFG shutdown in several places, this patches fixes all of them.
+ In particular, cfg_try_shutdown asks all applications that are
+ registered for callbacks if they approve the shutdown. This caused a bit
+ of a re-entrancy problem because it also asked the process that called
+ for the shutdown! The patch causes cfg to only ask OTHER applications in
+ the assumption that any application that calls
+ corosync_cfg_tryshutdown() will approve of the action :-)
+
+ In addition it adds the response to cfg_replyto_shutdown which was
+ missing (it couldn't be used with the old system but is mandatory now),
+ and removes a double-free in the library finalise code.
+
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1794 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-03-06 Steven Dake <sdake@redhat.com>
+
+ Add reserve/release functionality to totem to reserve message queue space.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1793 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-03-06 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ Allow logsys_format_set to reset to default.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1792 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-03-06 Steven Dake <sdake@redhat.com>
+
+ Use list_del on process info in the condition that lib_exit_fn is called to prevent segfault from processes later processing that list entry.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1791 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-03-04 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ logsys: re-add support for timestamp that was lost in the upgrade from v1 to v2
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1790 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix logsys_set_format by updating the right bits
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1789 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-03-03 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ Fix uninitialized memory. Spotted by valgrind
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1788 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-03-03 Steven Dake <sdake@redhat.com>
+
+ Rework a bit of how lib_exit_fn works so that reference counts may be used in the exit functions for services such as cpg.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1786 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Lock cpg ipc connections into memory on lib_init_fn and remove lock on lib_exit_fn.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1785 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-02-26 Christine Caulfield <ccaulfie@redhat.com>
+
+ This patch fixes some minor bugs in the expected_votes behaviour and adds a couple of new features:
+ - When total_votes exceeds the expected_votes value then expected_votes
+ is increased to that value.
+
+ - A callback can be sent to a client whenever expected_votes is changed
+
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1784 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ The current object database allows duplicate key names per object. This is a bit of a nightmare to manage and provides no useful functionality that I can see. Making keys unique has been discussed on IRC several times and there seem to be no objections...so here is the patch:
+ Note that I have removed some now-useless parameters from the objdb API
+ too.
+
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1783 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-02-25 Steven Dake <sdake@redhat.com>
+
+ Unification around hdb_handle_t data type.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1782 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Send configuration changes to CPG listeners. (regression in IPC patch).
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1781 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-02-25 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ Install corosync-fplay and corosync-pload binaries
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1780 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-02-25 Steven Dake <sdake@redhat.com>
+
+ Fix possible segfault with IPC service.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1779 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Remove extra printf debug.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1778 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-02-24 Steven Dake <sdake@redhat.com>
+
+ Remove installation of static libcoroipc.a.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1777 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix problem with 1722 commit which broke ipc.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1776 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-02-23 Christine Caulfield <ccaulfie@redhat.com>
+
+ Move VOTEQUORUM_SERVICE to ipc_gen.h where it belongs.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1775 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ When a quorum device registers it tells the corosync quorum engine of the new quorum which then tries to do a new sync(). But that's no use because the nodelist and ring_id is identical to before. Also it can try and register while a sync is already in operation ... which gets it awfully stuck!
+ So this patch makes the sync conditional on there being a new ring ID to
+ do a sync on.
+
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1774 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-02-20 Christine Caulfield <ccaulfie@redhat.com>
+
+ Fix problem in disallowed mode that prevented a HASSTATE node joining a cluster without state or vice-versa see Red Hat BZ#485026
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1773 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Don't crash if a library tries to talk to a module that is not loaded
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1772 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Allow CPG messages to be sent on an inquorate cluster
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1771 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-02-19 Christine Caulfield <ccaulfie@redhat.com>
+
+ Fix crash in confdb_finalize
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1770 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Get rid of one crash in confdb. It still double-frees in confdb_finalize though.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1769 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix crashes in quorum_initialize & votequorum_initialize
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1768 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-02-19 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ Fix build error spotted by gcc-4.4
+ #elif with no clause is clearly wrong and continuing when we don't
+ know the byte order only defers the problem to a point where its much
+ harder to debug
+
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1767 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-02-19 Steven Dake <sdake@redhat.com>
+
+ Whitetank IPC Forward Port.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1766 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-02-18 Steven Dake <sdake@redhat.com>
+
+ Remove redundant statement in totemsrp.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1764 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Use definition instead of magic number.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1763 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Update link for upstream crypto code.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1762 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-02-18 Ryan O'Hara <rohara@redhat.com>
+
+ Add timer_expire_time_get Add timer_expire_time_get corosync API call.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1761 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-02-14 Ryan O'Hara <rohara@redhat.com>
+
+ Add timer_time_get to the corosync API.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1760 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-02-13 Christine Caulfield <ccaulfie@redhat.com>
+
+ Add corosync_cfg_local_get() call to get the local NodeID in libcfg
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1759 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-02-12 Ryan O'Hara <rohara@redhat.com>
+
+ Add TMR_SERVICE to the list of service_types.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1758 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-02-03 Christine Caulfield <ccaulfie@redhat.com>
+
+ Fix "leave" function where the remaining nodes recalculate quorum when a node leaves. Also add a timeout to the leave flag.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1757 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-01-30 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ fix pkgconfig builddir creation
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1756 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add .pc file support for corosync libs
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1755 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-01-30 Christine Caulfield <ccaulfie@redhat.com>
+
+ Add quorum_fd_get and votequorum_fd_get prototypes
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1754 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Make cfg_get_node_addrs return CS_OK rather than 0 when it succeeds.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1753 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-01-29 Christine Caulfield <ccaulfie@redhat.com>
+
+ Fix votequorum_getinfo returning the wrong value for expected_votes
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1752 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Remove the last bicapitalised name from cfg
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1751 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-01-27 Christine Caulfield <ccaulfie@redhat.com>
+
+ Don't automatically load the quorum service.
+ This will, for the time being, unbreak synchronisation.
+
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1750 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-01-26 Steven Dake <sdake@redhat.com>
+
+ Fix node masking for 32 bit node ids.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1749 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Allow crypto to work on systems where unsigned long evaluates to 8 bytes. (s390x).
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1746 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-01-26 Christine Caulfield <ccaulfie@redhat.com>
+
+ Add the votequorum service
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1745 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-01-25 Steven Dake <sdake@redhat.com>
+
+ Fix error where entire message was not rejected during startup of a new node resulting in partial delivery of a complete message and segfaulting the executive.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1744 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix message rejection problem.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1743 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-01-23 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ cleanup handling of uid/gid config
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1742 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-01-23 Christine Caulfield <ccaulfie@redhat.com>
+
+ Fix a couple of memory leaks
+ The objdb occurred because object_find_destroy wasn't implemented!
+
+ The one in confdb occurred because object_find_destroy wasn't called if
+ object_find_next returned an error the first time it was invoked (ie
+ there were no subobjects).
+
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1741 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-01-23 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ fix logging reload operation and clean up main init
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1740 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ don't keep logsys fd open unless it's required
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1739 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-01-22 Christine Caulfield <ccaulfie@redhat.com>
+
+ Install quorum.h
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1738 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-01-21 Christine Caulfield <ccaulfie@redhat.com>
+
+ Install quorum library
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1737 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-01-20 Steven Dake <sdake@redhat.com>
+
+ Complete poll_stop function.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1735 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Cancel token holding mode when a totem token callback is added to the system.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1734 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-01-20 Christine Caulfield <ccaulfie@redhat.com>
+
+ Add OBJDB_RELOAD_NOTIFY_FAILED which was missing from coroapi
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1733 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-01-19 Christine Caulfield <ccaulfie@redhat.com>
+
+ Make all the bicapitalised names in cfg more sensible.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1732 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-01-16 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ Clean up tag handling and provide functions to match name with values and viceversa.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1731 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ restore the priority setting that was lost
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1730 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-01-15 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ Remove duplicate code and use the right library call into logsys that also cover cases that were not handled at all.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1729 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix small memory leak on config reload operations
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1728 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-01-14 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ Fix logsys write to file crash.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1727 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-01-14 Christine Caulfield <ccaulfie@redhat.com>
+
+ add corosync_cfg_get_node_addrs() call.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1726 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add some mussing pthread_mutex_lock() calls.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1725 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-01-08 Christine Caulfield <ccaulfie@redhat.com>
+
+ Build testquorum on Darwin
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1724 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Don't always overwrite /etc/corosync.conf when make install is run.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1723 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ If there was a quorum {} section in corosync.conf but no provider specified then we would always report inquorate.
+ This was wrong, if no provider is specified then we are always quorate.
+
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1722 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-01-08 Steven Dake <sdake@redhat.com>
+
+ Patch to allow cpg_membership_get to work properly.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1721 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-01-07 Angus Salkeld <asalkeld@redhat.com>
+
+ Fix coverity bug ID 6: FORWARD_NULL
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1720 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-01-07 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ Check against the right var and silence a few warnings at build time
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1719 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2009-01-06 Angus Salkeld <asalkeld@redhat.com>
+
+ Fix coverity bug ID 9: OVERRUN_STATIC
+ CID: 9
+ Checker: OVERRUN_STATIC (help)
+ File: lib/cfg.c
+ Function: corosync_cfg_service_unload
+ Description: Overrun of static array
+ "&(req_lib_cfg_serviceunload).service_name" of size 1024 bytes by
+ passing it to a function which indexes it with argument "1023" at byte
+ position 4088
+
+ The main problem here is the way the service_name is defined:
+ - char *service_name[256] __attribute__((aligned(8)));
+ + char service_name[256] __attribute__((aligned(8)));
+
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1718 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2008-12-28 Angus Salkeld <asalkeld@redhat.com>
+
+ Fix coverity bug ID 4: remove unused code & fix compile error
+ In evs_dispatch() the local ignore_dispatch is not used.
+ So I have removed this code.
+
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1717 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix coverity bug ID 1: overused local variable
+ coverity says that in exec/objdb.c: 1075 the found is always == 1
+ therefore the code is dead. But this is just a case of an overused
+ local variable. "found" is used for two different searches.
+
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1716 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix coverity bug ID 7: add NULL pointer check
+ Here coverity checks that if in a function a pointer is checked
+ for NULL then it is checked through out the function.
+
+ So below I have just add some more checks for NULL.
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1715 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix coverity bug ID 5
+ In poll_timer_add() if you pass in a NULL for the callback function
+ the pointer will be dereferenced.
+
+ I have moved the check for the NULL up.
+
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1714 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2008-12-19 Christine Caulfield <ccaulfie@redhat.com>
+
+ If there is no quorum provider specified, then always return quorate.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1713 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2008-12-18 Christine Caulfield <ccaulfie@redhat.com>
+
+ If we exit with an error, set the returned status code for the shell.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1712 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2008-12-17 Angus Salkeld <asalkeld@redhat.com>
+
+ Don't segfault if the ais group is not found.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1711 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2008-12-17 Christine Caulfield <ccaulfie@redhat.com>
+
+ Add config reload support for logsys
+ If objdb is reloaded, then we re-parse the logging options.
+
+ This allows logging options to be changed/enabled/disabled without
+ restarting corosync
+
+
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1710 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2008-12-12 Christine Caulfield <ccaulfie@redhat.com>
+
+ This patch adds this capability for a limited number of totem keys using the existing reload mechanism.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1709 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2008-12-11 Christine Caulfield <ccaulfie@redhat.com>
+
+ Install quorum.h file
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1708 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2008-12-09 Christine Caulfield <ccaulfie@redhat.com>
+
+ Add another missing file
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1707 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add some missing files, sorry
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1706 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2008-12-08 Steven Dake <sdake@redhat.com>
+
+ Patch to fix compilation of macosx and linux in some platform configurations.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1705 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2008-12-08 Christine Caulfield <ccaulfie@redhat.com>
+
+ quorum is now an optional loadable module (though I've put it into the defaults in services.c) and can load another module to do the quorum work (eg YKD which I've made more compliant too). All the quorum code has been removed from sync.c. quorum.c is simply a shim later for the coroapi, the main module is in vsf_quorum.c
+ There are coroapi calls to query quorate status and also to get
+ notifications when it changes.
+
+ I've included the testquorum.lcrso module in this patch because I think
+ it's really helpful for testing. It sets the quorum state based on an
+ objdb variable, this can be set or cleared using corosync-cfgtool
+
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1704 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2008-12-02 Steven Dake <sdake@redhat.com>
+
+ Fix deadlock in logsys during startup.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1703 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2008-12-02 Andrew Beekhof <abeekhof@redhat.com>
+
+ Correctly compare local addresses with bindnetaddr
+ This patch allows whitetank/corosync to behave correctly when the supplied value of bindnetaddr has more precision than the netmask, but is not a full IPv4 address.
+
+ For example, currently, if the netmask is /16 but the user specifies 192.168.1.0, then OpenAIS is unable to determine the correct address and uses the loopback address instead.
+
+ The following patch allows OpenAIS to correctly determine which interface/address to use.
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1702 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2008-12-01 Angus Salkeld <asalkeld@redhat.com>
+
+ change get node_id() to return an unsigned int
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1701 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ depending on your ip address, cpg doesn't always send config changes
+ If you ip addresses are larger than 0xffffff then you will never
+ get sent group leave notifications.
+
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1700 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2008-11-13 Christine Caulfield <ccaulfie@redhat.com>
+
+ Don't crash if we get a message for a service that isn't loaded.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1699 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Make the port numbers into Network Byte Order.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1698 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2008-11-12 Angus Salkeld <asalkeld@redhat.com>
+
+ LINT: fix confd_sa API error.
+ remove extra parent_object_handle parameter.
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1697 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2008-11-11 Angus Salkeld <asalkeld@redhat.com>
+
+ LINT: fix "Assignment of ssize_t to int" warnings
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1696 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ LINT: tweek the lint make rules.
+ Makefile.inc: add -unrecog (don't complain about things like strdup().
+ tools/Makefile: don't use *.c as it complains about duplicate main() functions
+
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1695 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ LINT: rename the overlay struct so they are uniq.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1694 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ LINT: fix or ignore unchecked return values.
+ If we don't care about the return value then typecase the return
+ value to void.
+ Else do something useful with the return value.
+
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1693 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2008-11-10 Steven Dake <sdake@redhat.com>
+
+ Fix missing message in delivery of messages under certain circumstances.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1692 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix received_flg to contain proper values.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1691 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2008-11-07 Angus Salkeld <asalkeld@redhat.com>
+
+ Add corotype.h and delete saAis.h
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1690 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2008-11-06 Angus Salkeld <asalkeld@redhat.com>
+
+ cleanup the last of the SAF headers and types
+ This includes the rename of identifiers from corosync to cs.
+
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1689 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2008-11-06 Steven Dake <sdake@redhat.com>
+
+ Make width of service 6 bytes instead of 5.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1688 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Null terminate string which resulted in failure of confdb during logging.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1687 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2008-11-04 Angus Salkeld <asalkeld@redhat.com>
+
+ Make lib/ clean up after itself properly.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1686 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2008-11-01 Angus Salkeld <asalkeld@redhat.com>
+
+ fix build error, can't complie if openais not installed.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1685 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add a top level "make lint"
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1684 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2008-10-31 Christine Caulfield <ccaulfie@redhat.com>
+
+ This patch adds two extra features to the CFG service in corosync, these are taken (conceptually at least) from cman.
+ 1. corosync_cfg_killnode() this will tell a remote node to exit.
+ 2. corosync_cfg_tryshutdown() this will do a semi-controlled shutdown in
+ that it will consult any interested attached daemons if they are willing
+ to let corosync be shut down. If they all agree then the rest of the
+ cluster will be informed before the node dies.
+
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1683 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2008-10-30 Steven Dake <sdake@redhat.com>
+
+ performance loading service engine first implementation.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1682 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Logsys flight recorder.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1681 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2008-10-30 Angus Salkeld <asalkeld@redhat.com>
+
+ Fix a memory violation in objdb (caught by valgrind)
+ If the new length is larger then memory will be overwritten.
+
+ I could make this ">=" but we can save memory if the new size is smaller by using "!=".
+
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1680 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2008-10-27 Christine Caulfield <ccaulfie@redhat.com>
+
+ Improve the usage message of corosync_objctl.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1679 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Currently if a reload operation fails, any subsystems listening for notifications will get a RELOAD_NOTIFY_START callback but not a RELOAD_NOTIFY_END callback.
+ This patch adds a RELOAD_NOTIFY_FAILED callback so that interested
+ parties will know when the reload has finished and that it failed.
+
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1678 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2008-10-21 Angus Salkeld <asalkeld@redhat.com>
+
+ remove some new warnings from corosync
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1677 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Remove unused global debug option from the man page.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1676 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2008-10-20 Steven Dake <sdake@redhat.com>
+
+ Remove unneeded totem_timeout_types global define.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1675 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2008-10-13 Christine Caulfield <ccaulfie@redhat.com>
+
+ This is an initial pass at a top-level quorum system. As it stands, this module doesn't provide quorum itself, merely a framework for setting and querying it. I envisage YKD plugging into this rather than straight into sync() eventually.
+ I've plugged this into the sync() routines rather than replacing them so
+ that quorum is itself a VSF, rather than a replacement - I'm not sure if
+ that is best or not. Opinions are welcome.
+
+ I've added an extra enum member to the service_handler so that we can
+ send IPC messages when the cluster isn't quorate. This will default to
+ NO (as now) but allows us to query and set quorum when we don't have it
+ .. a useful feature !
+
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1674 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2008-10-06 Christine Caulfield <ccaulfie@redhat.com>
+
+ Add locking around objdb calls so that reloads and writes are atomic.
+ Also add a notification callback for reload. Both the start and the stop
+ are notified so that the user can decide what to do with the flurry of
+ updates that occur.
+
+ Note than the reload callback notification MUST be registered against
+ OBJECT_PARENT_HANDLE. Registering it lower down the hierarchy makes no sense.
+
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1673 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix some compile warnings.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1672 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2008-10-05 Steven Dake <sdake@redhat.com>
+
+ Fix CFLAGS and LDFLAGS overrides to work for DEBUG and RELEASE modes.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1671 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2008-09-25 Steven Dake <sdake@redhat.com>
+
+ Fix makefile error in test directory.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1669 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2008-09-23 Steven Dake <sdake@redhat.com>
+
+ Add evs verify tool and allow Makefile to build in test directory properly.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1668 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2008-09-17 Angus Salkeld <asalkeld@redhat.com>
+
+ Propagate the flow control state between AIS exec and library
+ This patch causes the flow control state in the library to be set
+ properly when the flow control is turned off (disabled). Then it can be
+ read properly by the flow control apis.
+ This also fixes the case where the application is no longer sending
+ messages and it has already dispatched all its received messages
+ before flow control is disabled.
+
+ Also, CPG response messages with a TRY_AGAIN error did NOT contain
+ a valid flow control state value. This meant the library could get
+ stuck with flow control enabled (flow control was never enabled
+ for the EXEC, so no disable event occurred).
+ This case was hit when a new node was joining - sync_in_process()
+ resulted in a TRY_AGAIN for error cpg_mcast_joined).
+
+ Also, in message_handler_req_exec_cpg_mcast() the state passed
+ back to the library defaulted to disabled for messages received
+ from another node (even if flow control was still enabled)
+ - this meant if multiple nodes were sending CPG messages,
+ then the library flow control state flip-flopped between
+ enabled and disabled.
+
+ Author: Steven Dake <sdake@redhat.com> &
+ Tim Beale <tim.beale@alliedtelesis.co.nz>
+
+
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1667 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add support for AMF (sync_request)
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1666 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ If syslog() blocked, node-leave events were incorrectly reported
+ In some cases, the syslog() call may block. If this happened, the AIS worker
+ thread would block waiting on the syslog() call. However, the worker thread
+ is still holding a logsys mutex, which is needed to enqueue any more log
+ messages from the other AIS threads. So the main AIS thread blocks waiting
+ on the logsys mutex. This can then cause aisexec on other nodes to detect
+ the node as leaving the cluster.
+
+ Author: Tim Beale <tim.beale@alliedtelesis.co.nz>
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1665 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2008-09-16 Fabien Thomas <fabien.thomas@netasq.com>
+
+ use getifaddrs to enumerate interface on FreeBSD and Darwin (patch from Mathieu Virbel)
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1664 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2008-09-03 Christine Caulfield <ccaulfie@redhat.com>
+
+ Reinstate key_iter_reset that got removed by mistake in 1660
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1663 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ This patch adds key_increment and key_decrement calls to the objdb and confdb subsystems.
+ This is useful to provide atomic counters (ag handle numbers) for
+ long-running (though not persistent) connections. It's not currently
+ possible via confdb to atomically get a new number from objdb due to the
+ lack of locking. Doing it via increment operations in the IPC thread
+ provides enough atomicity to make it useful. Fabio has already
+ identified a use for these calls.
+
+ It could also provide some form of basic co-operative locking mechanism
+ for IPC-using processes (not direct objdb calls).
+
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1662 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2008-08-27 Christine Caulfield <ccaulfie@redhat.com>
+
+ Fix the names of confdb_object_find_destroy and confdb_object_iter_destroy.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1661 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2008-08-26 Christine Caulfield <ccaulfie@redhat.com>
+
+ Remove the disliked *_from calls from the objdb and recast the confdb library to use the new find_create/find_next/find_destroy API calls instead.
+ I've kept the libcondfb API the same as before with the single change of
+ adding a confdb_object_find_destroy to tidy up the find handle after
+ use. If you don't call this then libcondfb will do it for you when
+ confdb_finalize is called.
+
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1660 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2008-08-20 Angus Salkeld <asalkeld@redhat.com>
+
+ Zero out unused totemsrp my_proc_list entries
+ When making my_proc_list smaller, ensure that the
+ now non-used entries are zero-ed out. There are some suspect
+ assert's that assume that there is always 2 entries in the list.
+ These fail when my_proc_list is reduced to 1 entry (and the
+ valid [0] entry is the same as the 'unused' [1] entry).
+
+ Author: Mark Wutzke <mark.wutzke@alliedtelesis.co.nz>
+
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1659 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ aisexec crash on exit
+ Cause:
+ As part of its exit procedure, ais cancels its worker thread then manually
+ processes any outstanding items that were still in the worker thread's queue.
+ The worker thread has a low priority so normally it does not execute any
+ further before ais finishes exiting, but if the main thread's exiting is
+ delayed for any reason, there is a chance the worker thread could execute and
+ try to process items which have already been processed and freed by the main
+ thread - often leading to the worker thread seeing NULL data and ultimately
+ causing a segmentation fault.
+
+ Fix:
+ Modified worker_thread_group_exit() so it does a pthread_join() after the
+ pthread_cancel() call, so that the worker thread always shuts down cleanly
+ before the main thread does its cleanup.
+
+ Author: Author: Mark McKinstry <mark.mckinstry@alliedtelesis.co.nz>
+
+
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1658 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix to display strings safely in debug messages.
+ Display strings safely, even if they are invalid, e.g. data in a received
+ message was corrupted.
+
+ Author: Tim Beale <tim.beale@alliedtelesis.co.nz>
+
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1657 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Provide a way to configure (at compile time) message and queue sizes.
+ This patch makes it possible to override the following #defines:
+ MESSAGE_SIZE_MAX
+ MESSAGE_QUEUE_MAX
+ SIZEQUEUE
+ FLOW_CONTROL_ENTRIES_ENABLE
+
+ If MESSAGE_SIZE_MAX is defined as 1024*64 (64K) and
+ MESSAGE_QUEUE_MAX defined as 512 you can change corosync's
+ memory footprint from ~48M to ~8M
+
+ So if you define MESSAGE_QUEUE_MAX, the queue size will
+ not be based on the message size any more.
+
+ To use this define the defines on the command line:
+ make CFLAGS="-DMESSAGE_SIZE_MAX=1024*64 -DMESSAGE_QUEUE_MAX=512"
+
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1656 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix an assert caused by faulty sort-queue management.
+ sq.h
+ - sq_items_release(): When clearing the items_inuse array, ensure that
+ all of the memory is cleared. items_inuse is a uint array, not a
+ byte array.
+
+ Author: Mark Wutzke <markw@alliedtelesis.co.nz>
+
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1655 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2008-08-15 Steven Dake <sdake@redhat.com>
+
+ Repair typo which caused init script not to start corosync daemon.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1649 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Make rpmlint pass without warnings.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1648 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Set the override for LCRSODIR properly.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1647 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Finish the renaming of openais to corosync in the tree.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1646 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2008-08-14 Steven Dake <sdake@redhat.com>
+
+ Fix build breakage.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1645 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ New and improved loc command.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1644 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ New LOC command.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1643 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ turn on executeable bit for loc.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1642 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Install saAis.h header file.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1641 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Update svn commit scripts so they work properly and have proper permissions.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1640 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Move QUICKSTART to proper directory.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1639 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Few man page cleanups and removal of amf.conf.5.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1638 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Proper rename of openais usage to corosync throughout tree.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1637 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Revert patch 1633 which breaks build.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1636 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Move openais* to corosync* in man pages.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1635 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Build corosync-keygen.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1634 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Change all occurances of openais to corosync.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1633 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2008-08-14 Fabien Thomas <fabien.thomas@netasq.com>
+
+ reorganize include file to match installed tree to build openais without installing corosync; correct some warnings and error under FreeBSD and Darwin
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1632 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2008-08-14 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ Revert config_verifyconf logic that is unnecessary
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1631 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2008-08-13 Christine Caulfield <ccaulfie@redhat.com>
+
+ Change AIS names to corosync
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1630 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2008-08-13 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ Add support for reload operations within objdb and plugins.
+ Use a 2 phase "commit" operation:
+ 1) Invoke verifyconfig that should catch the errors before the reload operation
+ 2) Invoke reloadconfig that performs the operation and should _never_ fail
+
+ Implementation note: if step 2 fails, there is no fall back at the moment.
+
+ Fix the IPC table for confdb:
+ MESSAGE_REQ_CONFDB_XPATH_EVAL_EXPRESSION = 12 was added to include/ipc_confdb.h
+ without an associated call. Thanks Chrissie for spotting this.
+
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1629 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2008-08-12 Steven Dake <sdake@redhat.com>
+
+ Add some totem process group interfaces to the API.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1628 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2008-08-12 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ objdb: change list_add to list_add_tail when adding keys and objects
+ service: change openais_service_unlink_all to deal with the new objdb order
+
+ cleanup a few whitespaces
+
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1627 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2008-08-06 Steven Dake <sdake@redhat.com>
+
+ Add module load and unload to the exported coroapi.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1626 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2008-08-05 Steven Dake <sdake@redhat.com>
+
+ Add callback notification about changes to the object db and confdb apis.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1625 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2008-08-05 Fabio M. Di Nitto <fdinitto@redhat.com>
+
+ Fix crash in logsys new API
+ logsys_config_priority_set lacked a check for logsys_single_id that
+ left logsys_subsys_id uninitialized.
+
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1624 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix toplevel Makefile install target
+ - objctl is now called corosync-objctl
+ - keygen has been renamed corosync-keygen
+ - install corosync-cfgtool as part of the standard tools now
+
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1623 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2008-08-05 Steven Dake <sdake@redhat.com>
+
+ Split openais and corosync tree into two seperate repositories.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1622 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Make mar_name_t an inline function to remove warnings
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1621 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2008-08-04 Steven Dake <sdake@redhat.com>
+
+ Allow msg service test applications to build properly.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1620 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix errors in lib linking.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1619 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add a missing confdb_key_delete function to the confdb api.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1618 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Merge Angus's corosync-objctl tool and move cfgtool to a different directory.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1617 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2008-08-01 Patrick Caulfield <pcaulfie@redhat.com>
+
+ Fix the spelling of 'guarantee' in several places.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1616 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2008-07-24 Steven Dake <sdake@redhat.com>
+
+ Final fixup to build all things properly.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1613 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ openais now builds when make install is done from corosync.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1612 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Merge the object iteration repair patch into corosync so openais services load.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1611 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add files missing from build but in dev repo.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1610 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Building of all service engines now works properly. Install works as well.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1609 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Improve runtime loading of parser and move versions files to corosync.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1608 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add MESSAGE_SIZE_MAX to coroapi file.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1607 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Make external service engines (openais) work properly. Also fix up make install.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1606 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Patch from Angus to make corosync build for his environment.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1605 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add API definitions file.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1604 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Merge the API definitions of the objdb into the corosync api definition.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1603 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2008-07-23 Steven Dake <sdake@redhat.com>
+
+ The entire tree builds properly and all services have been ported to the new coroapi.h include header.
+ The services shipped with corosync are CPG, CFG, CONFDB, and EVS.
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1602 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2008-07-22 Steven Dake <sdake@redhat.com>
+
+ Make from top level directory now works.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1601 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ API changes and code to make cfg and cpg service operate properly with corosync.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1600 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2008-07-21 Steven Dake <sdake@redhat.com>
+
+ Cause libraries to build.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1599 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Set default services to load.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1598 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add the default corosync parser.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1597 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Rename AIS parts to Corosync.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1596 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Rename aispoll to coropoll.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1595 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ corosync/exec builds.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1594 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Remove depends in Makefile.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1593 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Initial makefile for corosync plugin service engines.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1592 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Move services around to service directory.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1591 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ move README.amf into openais directory.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1590 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Remove unnecesssary files.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1589 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add makefile and loc infrastructure to openais directory.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1588 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add license file to openais tree.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1587 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Move mismove to proper location.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1586 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Move test, lib, exec, and include files that are openais specific into openais directory.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1585 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Put conf directory in openais directory.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1584 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Move test directories and remaining loc files to test directory.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1583 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Initial move of corosync and openais trees into seperate directories.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1582 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Test queue group tracking feature.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1581 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add ability to track changes to queue groups in the messaqge service.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1580 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2008-07-14 Steven Dake <sdake@redhat.com>
+
+ Allow setting of the logsys priority to one lower then was already specified.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1579 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Revert incorrect patch.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1578 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Allow setting of lower priority which is currently disabled.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1577 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Allow users of logsys to disable output of logging LOG_LEVEL_DEBUG messages via log_mode_set.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1576 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2008-07-11 Patrick Caulfield <pcaulfie@redhat.com>
+
+ * Adds documentation for the LOG_MODE_NOSUBSYS mode flag, * Adds documentation for the LOG_MODE_SHORT_FILELINE mode flag, and * Fixes (typo) 'declartion' -> 'declaration'
+ -- Lon
+
+
+
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1575 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2008-07-11 Steven Dake <sdake@redhat.com>
+
+ Fix error in a previous logsys patch.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1574 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2008-07-07 Patrick Caulfield <pcaulfie@redhat.com>
+
+ Add a missing object_find_reset() call.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1573 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2008-07-03 Steven Dake <sdake@redhat.com>
+
+ Add init/config entry points for those that dont with to use macros in logsys.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1572 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2008-07-02 Patrick Caulfield <pcaulfie@redhat.com>
+
+ Add cpg_groups_get call to libcpg.
+ This call causes a complete list of active groups and their
+ membership lists to be sent to a callback function.
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1571 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2008-07-02 Steven Dake <sdake@redhat.com>
+
+ Add two new modes LOG_MODE_SHORT_FILELINE and LOG_MODE_NOSUBSYS. LOG_MODE_SHORT_FILELINE strips the leading path from the file name in a debug output. LOG_MODE_NOSUBSYS removes a global variable and provides the ability to set or unset this via config_mode_set.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1570 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2008-07-01 Patrick Caulfield <pcaulfie@redhat.com>
+
+ this patch fixes a segfault/crash in confdb_write.
+ If the operation is succesful there is no need to set error_string. If error_string is not set, don't try to access it or we crash.
+
+ At the same time perform the same check in libconfdb when we receive the reply.
+
+ Fabio
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1569 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2008-06-24 Steven Dake <sdake@redhat.com>
+
+ Allow syslog priority configurations per subsystem in logsys.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1568 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Remove warnings of unused variables in main.c
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1566 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Allow make in the exec directory to work even if root/lcr isn't yet built.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1565 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add #include assert.h to some AMF files.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1564 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Forward port of the synchronization engine into trunk.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1563 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix a ton of bugs in totem by forward porting the whitetank totem code into trunk.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1562 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Remove totemip.h reference from file.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1561 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Remove totemip reference from file.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1560 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ remove totemip.h reference from file.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1559 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix unlock_algorithm in lock service.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1558 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Improve the async version of locking library patch from Xinwei Hu.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1557 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Patch from Xinwei Hu to clean up test locking program.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1556 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2008-06-20 Steven Dake <sdake@redhat.com>
+
+ Allow user to retrieve logsys mode.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1555 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Remove extra unneeded configuration option from logsys.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1554 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Use logsys_facility_id_get to do the string conversion instead of doing it in the openais configuration parser.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1553 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2008-06-13 Steven Dake <sdake@redhat.com>
+
+ Message service implemntation - more apis now supported.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1552 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2008-05-20 Steven Dake <sdake@redhat.com>
+
+ Fix linking of other projects against logsys on ppc64.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1550 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Remove exit when logsys files can't be created.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1549 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2008-05-14 Steven Dake <sdake@redhat.com>
+
+ Fix loading of multiple objects.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1547 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2008-05-12 Steven Dake <sdake@redhat.com>
+
+ Repair invalid commit.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1545 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add ckpt service back in from incorrect patch that was committed found during tesitng of rpm of 0.83-1.fc10.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1544 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Change all email addresses that were sdake@mvista.com to sdake@redhat.com.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1541 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Repair loading of external services.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1540 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Remove executable permission from flow.c
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1539 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2008-05-09 Steven Dake <sdake@redhat.com>
+
+ Patch to remove segfault on the exiting of a service.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1538 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Patch to allow controlled exit of a service.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1537 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2008-05-07 Patrick Caulfield <pcaulfie@redhat.com>
+
+ Expose confdb write to the library.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1536 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2008-05-06 Patrick Caulfield <pcaulfie@redhat.com>
+
+ Add LDFLAGS to libconfdb linking
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1535 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2008-05-05 Steven Dake <sdake@redhat.com>
+
+ Execute a test of the makefile system from Angus
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1534 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Apply suggestion from Andrew for srcdir functionality.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1533 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2008-05-02 Steven Dake <sdake@redhat.com>
+
+ Allow make from the exec directory.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1532 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2008-04-30 Patrick Caulfield <pcaulfie@redhat.com>
+
+ Allow libconfdb to run standalone (without aisexec)
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1531 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add writeback call to objdb
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1530 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2008-04-29 Steven Dake <sdake@redhat.com>
+
+ Fix build error.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1529 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2008-04-28 Steven Dake <sdake@redhat.com>
+
+ load and unload service engines at runtime.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1528 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Patch to add new api to logsys to get priority names from subsystem names.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1527 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Change initialization order for logsys logging to files to work properly.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1526 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2008-04-23 Steven Dake <sdake@redhat.com>
+
+ Fix building on OSX
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1525 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix syscall usage for keygen application
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1523 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2008-04-23 Patrick Caulfield <pcaulfie@redhat.com>
+
+ Fix logsys_config_priority_set() so that it sets the priority of the local subsystem and not always "MAIN".
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1522 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2008-04-22 Steven Dake <sdake@redhat.com>
+
+ Build on latest glibc.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1520 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2008-04-21 Steven Dake <sdake@redhat.com>
+
+ Patch to reinitialize logsys internal variables after a fork for correct operation.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1519 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2008-04-17 Patrick Caulfield <pcaulfie@redhat.com>
+
+ Add man pages for confdb functions.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1518 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix some typos in the CPG man pages
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1517 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2008-04-16 Patrick Caulfield <pcaulfie@redhat.com>
+
+ Add confdb, a library to access the configuration object database.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1516 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix locking in logsys.
+ Patch from Fabio M. Di Nitto <fabbione@fabbione.net>
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1515 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2008-03-10 Patrick Caulfield <pcaulfie@redhat.com>
+
+ Add some new calls into objdb.
+ These allow replacing/removing keys, and deleting a whole object subtree,
+ iterator functions to enumerate all objects/keys on an object,
+ and a dump call for debugging.
+
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1505 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2008-01-08 Steven Dake <sdake@redhat.com>
+
+ Patch to install liblogsys
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1495 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Remove closing of ttys that slipped in improperly.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1494 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2007-12-10 Steven Dake <sdake@redhat.com>
+
+ srcdir is not set when realpath & abspath don't work
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1492 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Force logging to stderr if the -f flag is specified.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1491 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Allow multiple config plugins to be loaded at start time and set the config object database objects.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1490 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2007-11-28 Steven Dake <sdake@redhat.com>
+
+ fix install broken when O=<DIR> is used
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1489 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Patch to make sure make clean works as advertised.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1488 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Properly daemonize and dup file descriptors to /dev/null.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1487 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Make sure to unlock the handle database on a failure condition.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1485 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Patch to set system from field properly in retransmitted messages.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1484 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Remove & when regular reference works properly.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1483 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Patch to not increment the ring seq id on the first operational ring.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1482 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ make install now works properly on systems which produce wierd uname results
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1481 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2007-10-25 Fabien Thomas <fabien.thomas@netasq.com>
+
+ add missing objdb for static build
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1476 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2007-10-22 Steven Dake <sdake@redhat.com>
+
+ Patch to provide generic init script that is generically useful for most distributions or can be used as a starting point for making a distribution custom init script.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1475 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Patch to close all open files on background run operation.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1474 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix missing commit from timer.c in trunk.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1472 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Endian convert downlist messages from cpg.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1470 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2007-10-16 Fabien Thomas <fabien.thomas@netasq.com>
+
+ correct ifdef that must be ifndef because under FreeBSD alloca.h is in stdlib.h
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1468 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2007-10-10 Patrick Caulfield <pcaulfie@redhat.com>
+
+ Remove some includes from .h files so they can be installed. Also install flow.h & ipc.h for external services.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1467 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix openais.conf example and man page to match the new logsys directives.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1466 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2007-10-02 Steven Dake <sdake@redhat.com>
+
+ Fix problem where adding a timer in a timer callback would lock system and also timer additions were not protected by mutex because of backwards pthread_equal comparison.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1463 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2007-09-28 Steven Dake <sdake@redhat.com>
+
+ segfault does not use source.conn unless the originating request is local. The actual code tries to dereference pointers created on another node.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1462 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ lock_algo queues lock requests rather than ignoring them if an exclusive lock is held on a resource. This led to stale processes trying to acquire an exclusive lock forever.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1461 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Patch to fix dependencies in build of test programs.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1460 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix linking of library objects.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1459 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2007-09-27 Steven Dake <sdake@redhat.com>
+
+ Allow override of the LCRSO directory from the Makefiles or command line
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1458 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix static libs installation logic inversion
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1457 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Makefile system improvements from Angus Salkeld
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1456 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2007-09-20 Patrick Caulfield <pcaulfie@redhat.com>
+
+ Install logsys.h rather than print.h
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1454 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2007-09-15 Steven Dake <sdake@redhat.com>
+
+ Fix reference counting in LCR code. Also fix problem with inability to compile from the exec directory because PREFIX wasn't defined for lcr_ifact.c.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1451 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Allow missing spots in the synchronization engine
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1448 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fixes the following problems: 1) the encapsulated and not encapsulated values for multicast messages are now enumerated instead of magic number. 2) the endian detector is now set for new encapsulated messages intended for transmission. previously these messages would use whichever endian detector value happened to be in memory which could be a) correct endian b) incorrect endian from another machine byte order message c) junk values. 3) The retransmission flag is not set by default on new originated tokens in the recovery state. Instead it is set based upon whether the node actually can retransmit any messages. 4) some workaround code was removed that was necessary to make the system work when #3 was incorrect 5) the my_install_seq and my_aru fields are compared based upon a window instead of static comparison because it could be that the my_aru is 0xFFFFFF5 where my_install_seq is 5. In this case (after a lot of messages are sent) the comparison would return the incorrect result in the recovery phase of the algorithm. 6) The queue chosen for adding messages to the retransmission queue is now set based upon the encapsulated bit rather then the current state of the state machine. 7) the encapsulated bit is set properly in an endian conversion operation for a multicast message header.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1447 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2007-09-11 Steven Dake <sdake@redhat.com>
+
+ Add missing files from the ais utils exporting patch.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1445 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2007-09-09 Steven Dake <sdake@redhat.com>
+
+ Calculate the default path based on the project value of PREFIX
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1444 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Ensure DESTDIR and PREFIX are properly used in Makefiles
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1443 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Expose utils to the user
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1442 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Now that -l is set correclt yuse #include <header.h> instead of using quotes.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1441 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Static libraries become out of date on Darwin once they are copied or moved
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1440 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Use makefile loops where possible
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1439 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Provide information as to why a plugin refused to load
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1438 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add extra brackets to clarify scope.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1437 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix build dependencies
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1436 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ If iface_ver0_p is not reset, then as long as the first plugin loads then all subsequent plugins will report success.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1435 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Missing stdlib.h from lcr_ifact.c.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1434 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ HZ not always defined on all Linux systems.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1433 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Patch to allow CFLAGS and LDFLAGS modifications to take effect
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1432 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Logsys testing system.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1431 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fixes for the logsys system.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1430 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ The man page for the logsys logging system.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1429 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ The logsys logging system. Read logsys_overview.8.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1428 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ totem srp merge from whitetank
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1427 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Patch to log security warnings when invalid identifier is used in message header for a totem message.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1425 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix problem in synchronization engine which results in possible failures of the synchronization engine.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1424 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2007-08-24 Steven Dake <sdake@redhat.com>
+
+ Patch to allocate event dispatch data in saEvtInitialize instead of directly on the stack for small thread-stack sized dispatch functions.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1421 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2007-08-11 Steven Dake <sdake@redhat.com>
+
+ Patch to not overwrite defualt configuration file or amf.conf file when executing make install
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1420 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Allow make doxygen to work properly
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1418 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Patch to add amf_strdup instead of malloc and then copy for amf service.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1417 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2007-08-08 Steven Dake <sdake@redhat.com>
+
+ Fix minor leaks caused by not calling pthread_mutex_destroy throughout the tree.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1412 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Patch to fix compile warning on mac platforms.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1411 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2007-07-02 Steven Dake <sdake@redhat.com>
+
+ Add the testcpg2 file missing from a previous commit.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1405 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2007-07-02 Fabien Thomas <fabien.thomas@netasq.com>
+
+ remove warnings under Darwin for missing includes and too many parameters in TRACE2
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1404 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2007-06-25 Patrick Caulfield <pcaulfie@redhat.com>
+
+ Clear pid when we leave a process group
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1399 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2007-06-25 Steven Dake <sdake@redhat.com>
+
+ Fix bug where if checkpoint section is expired about the same time as a checkpoint is deleted, a warning would be displayed.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1398 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Update testckpt program to properly test checkpoint system.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1397 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add cpg_local_get api to cpg service
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1391 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2007-06-24 Steven Dake <sdake@redhat.com>
+
+ Add IP address takeover as an AMF component
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1388 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2007-06-23 Steven Dake <sdake@redhat.com>
+
+ Add passive monitoring support to AMF.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1386 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2007-06-14 Patrick Caulfield <pcaulfie@redhat.com>
+
+ Add man pages for cpg_context_* and fix library exports to include them too.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1385 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2007-06-13 Patrick Caulfield <pcaulfie@redhat.com>
+
+ Install the timer.h file so it can be used by external services and remove a dependency on tlist.h
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1384 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Currently saLckResourceUnlockAsync leaves the lockid in the handle database even when the lock has been unlocked. This can cause exec crashes if the lock is unlocked twice.
+ This patch adds an extra field to the res_lib_lck_resourceunlockasync structure
+ so that the library can remove the lock from the handle database when the lock
+ is unlocked successfully, as well as code to do it, obviously.
+
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1383 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2007-06-12 Fabien Thomas <fabien.thomas@netasq.com>
+
+ repair BSD/Darwin build by moving HZ constant in tlist.h
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1381 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2007-06-05 Patrick Caulfield <pcaulfie@redhat.com>
+
+ Cast away a compile warning
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1380 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2007-06-05 Steven Dake <sdake@redhat.com>
+
+ Remove this_ip from the source tree and replace with accessor functions.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1379 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Change timers to add duration and absolute timers. Use nanoseconds since epoch to track timers.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1378 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2007-05-31 Patrick Caulfield <pcaulfie@redhat.com>
+
+ Add get/set context API calls to the cpg service.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1377 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2007-05-30 Patrick Caulfield <pcaulfie@redhat.com>
+
+ Don't try and remove a lock from a list if it's not on one, but DO remove it from the resources list when it gets unlocked.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1376 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2007-05-22 Steven Dake <sdake@redhat.com>
+
+ Sanitize the ETCDIR usage in the Makefiles.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1375 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Use rync -a when cp -a is not available on MAC OSX platform install
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1374 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2007-05-18 Patrick Caulfield <pcaulfie@redhat.com>
+
+ This patch fixes the marshalling of lock names in libSaLck, they were copied using memcpy, but the alignment of a mar_name_t is not necessarily the same as SaNameT. This patch changes memcpy() to marshall_to_mar_name_t().
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1373 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2007-05-17 Steven Dake <sdake@redhat.com>
+
+ on 32 bit platforms, the message source conn info could have uninitialized values.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1371 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2007-05-05 Patrick Caulfield <pcaulfie@redhat.com>
+
+ In trunk, totemip.h and totem.h call for "../include/swab.h" - this works fine when building openais itself but causes problems when installed as those files will not be in the right place.
+ So, I've moved these includes out of totemip.h and totem.h and into the .c files
+ that call them.
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1370 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2007-04-25 Steven Dake <sdake@redhat.com>
+
+ Fix section iteration size comparison
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1367 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Print Unknown Time if the time is unknown of an event.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1366 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Change tab alignment on checkpoint write operation to match coding style guidelines
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1365 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fixes problem where if attributes list is zero, library would segfault
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1362 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2007-04-22 Steven Dake <sdake@redhat.com>
+
+ change references to evs to cpg to match API
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1361 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2007-04-21 Steven Dake <sdake@redhat.com>
+
+ Patch from Angus to fix return code of saAmfResponse if the handle was invalid.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1360 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2007-03-21 Steven Dake <sdake@redhat.com>
+
+ Fix documentation errors in cpg service.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1358 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2007-03-14 Steven Dake <sdake@redhat.com>
+
+ Solaris port patch to fix a few problems from last big patch.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1355 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2007-03-12 Steven Dake <sdake@redhat.com>
+
+ Patch to allow BSD/Linux systems to compile with latest Solaris porting patch.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1354 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2007-03-06 Steven Dake <sdake@redhat.com>
+
+ Patch from Renaud to report some broken Solaris porting from past.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1353 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2007-01-26 Hans Feldt <hans.feldt@ericsson.com>
+
+ This patch improves AMF's behaviour for handling component instantiation level. AMF is complemented to handle termination and instantiation with respect to instantiation level also for the following scenarios: - SU restart - termination/instantiation errors during component/SU restart - instantiation error during cluster start up
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1352 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2007-01-25 Hans Feldt <hans.feldt@ericsson.com>
+
+ Was writing to random mem using an uninitialized pointer
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1351 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2007-01-23 Steven Dake <sdake@redhat.com>
+
+ Display the names of the configuration files used by openais.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1350 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add two notifications about things to avoid to ensure proper operation of the parser.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1349 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fixes from Zoltan regarding AMF mispellings and type errors.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1348 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2007-01-18 Lon Hohberger <lhh@redhat.com>
+
+ - improves the inclosed dokumentation in amfsu,amfsg and amnode. - improves error handling caused by the INSTANTIATE or CLEANUP command while recovering with component_restart or su_restart
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1347 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-12-21 Lon Hohberger <lhh@redhat.com>
+
+ 1 The patch contains mainly updates of the header documentation in the amf_files 2 Correction of the misspelling in lib/cfg.c
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1346 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-12-18 Steven Dake <sdake@redhat.com>
+
+ Fix unaligned access for ia64 arch.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1343 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix typo in pthread_mutex_destroy.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1342 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Execute pthread destroy in queue_free in trunk.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1341 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-12-12 Steven Dake <sdake@redhat.com>
+
+ Fix mutex leak on various platforms.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1336 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Remove leak when pthread mutex isn't released
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1335 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix leak by forward porting a change already in whitetank.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1333 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Change timing parameters for trunk to something more reasonable for a busy network.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1332 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Convert some spaces to tabs that was already in the whitetank branch.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1331 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix leak in uid and gid determination.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1328 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix flow control problem in trunk.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1327 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add rundir patch to /var/lib/openais.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1326 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-12-12 Patrick Caulfield <pcaulfie@redhat.com>
+
+ Fix ordering of join messages
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1324 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-12-11 Lon Hohberger <lhh@redhat.com>
+
+ Correct not initialized value of amf_comp in amf_comp_find_from_conn_info ()
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1322 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ This patch contians:
+ - AMF handles a component report of injurious health.
+
+ - AMF handles saAmfHealthcheckConfirm() SA_AIS_ERR_FAILED_OPERATION
+ so that if it's a recent recovery ongoing amf does nothing but if it's
+ no immediate recovery in progress, AMF invokes the recovery action
+ specified by the component when the health check is started If
+ the individual recommendation was SA_AMF_NO_RECOMMENDATION,
+ then AMF uses the configured recovery action for the component
+ (saAmfCompRecoveryOnError). If this recommendation also is
+ SA_AMF_NO_RECOMMENDATION, then AMF makes a component restart or
+ component/SU fail over counts on the value of
+ saAmfCompDisableRestart and saAmfSUFailover.
+
+ - Handling of cleanup of a component and health check response hardened.
+
+
+ - Time supervision and check return value of clc-cli CLEANUP command.
+
+
+ - Handle 'recommended recovery' specified by a component in an error
+ report. The potential recovery action to choose
+ implemented is - component restart - and - node fails over.
+
+ - The attribute saAmfCompDisableRestart is now recognizable which means
+ that if the component specifies 'Component restart' and restart is
+ disabled
+ then the SU in which the component is contained shall fall over.
+
+ - The attribute saAmfSUFailover will not be recognized. SU will always
+ fail
+ over as a single entity.
+
+ - A component can report an error on another component than itself.
+
+
+ - Implementation 'Instantiation Level' according to chapter 3.9.2 in the
+ AMF specification.
+ - Implementation of the escalation levels, component restart, SU
+ restart, SU fail over and Node fail over.
+
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1321 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-12-06 Hans Feldt <hans.feldt@ericsson.com>
+
+ Corrected amf.c bug that could cause segv
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1320 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-12-05 Hans Feldt <hans.feldt@ericsson.com>
+
+ Correction to segv handler Added abort handler
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1318 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-12-04 Hans Feldt <hans.feldt@ericsson.com>
+
+ - Use of sync_request() in SYNC service - sync_abort() callback implemented
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1317 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-11-23 Fabien Thomas <fabien.thomas@netasq.com>
+
+ handle case where POLLHUP or POLLERR are not supported by OS
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1311 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-11-17 Hans Feldt <hans.feldt@ericsson.com>
+
+ Cleaning up and preparing for later patch.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1310 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-11-16 Fabien Thomas <fabien.thomas@netasq.com>
+
+ set default downcheck value to 1000ms
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1309 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ remove invalid code / warnings detected by Intel compiler
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1308 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-11-13 Steven Dake <sdake@redhat.com>
+
+ Print information about when we enter the gather state and what state the membership protocol is in when the token is lost.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1304 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Forward port of IPC code from whitetank branch to fix known defects.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1303 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Flushed printing for trunk branch.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1302 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Improve behavior of IPC flow control for CPG service during configuration changes.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1301 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-11-10 Steven Dake <sdake@redhat.com>
+
+ Update checkpoint service from all qualifications that have occured in whitetank branch.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1299 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Recovery algorithms described in this document.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1298 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-11-10 Lon Hohberger <lhh@redhat.com>
+
+ improved cluster_applications_are_starting_sgs
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1297 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-11-08 Hans Feldt <hans.feldt@ericsson.com>
+
+ removed compiler warning in amfcomp.c
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1292 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-11-08 Lon Hohberger <lhh@redhat.com>
+
+ This patch contains several corrections concerning SU and Node fail over and some hardening concerning health check handling.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1291 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-11-07 Patrick Caulfield <pcaulfie@redhat.com>
+
+ 2.6.19 kernel headers do not include IFA_RTA so we provide it. Patch from Fabio Massimo Di Nitto
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1290 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-11-04 Steven Dake <sdake@redhat.com>
+
+ Forward port of flow control work from whitetank branch.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1289 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Updated readme.devmap file
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1287 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-10-27 Hans Feldt <hans.feldt@ericsson.com>
+
+ * Improvement of SU fail over to handle remove of those standby assignments that doesn't directly is associated to the failing over SU's active assignments in other SU's * Improvement of Node fail over to handle remove of those standby assignments that doesn't directly is associated to the failing over Node SU's active assignments in other SU's.
+ * Improvement of SU fail over to handle si assignments to spare SU:s
+
+ * Improvement of Node fail over to handle si assignments to spare SU:s
+
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1285 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-10-24 Hans Feldt <hans.feldt@ericsson.com>
+
+ AMF healthcheck keylen was not compared before matching key values
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1281 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ - sync_abort is called if there is a new config change during synchronization
+ - a new function sync_request() that can be called by a user to execute
+ synchronization on request of a specified service.
+
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1280 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-10-20 Hans Feldt <hans.feldt@ericsson.com>
+
+ Changes to testamf1.c to have two healthchecks running at the same time. One of type 'AMF invoked' and one of type 'component invoked'. testamf1.c code got a bit restructured at the same time.
+ Changes in amf.conf to complement testamf1
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1274 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ I found some (copy paste I guess) errors in the AMF library. It was the reason for why component invoked healthchecks did not work at all.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1273 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ A couple of errors was found when I did unit (component) testing of amf.c using CUnit. With this patch, amf.c can handle a full totem send queue. This is not easily reproducable with function test.
+ amf.c is also prepared for further component testing with this patch.
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1272 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-10-13 Lon Hohberger <lhh@redhat.com>
+
+ Patch contains:
+ A mechanism to defer and recall simultaneous
+ events in the state machines for amf_cluster,
+ amf_application and amf_sg.
+
+ The implication of this defer and recall mechanism is
+ that it's now possible to to recover from e.g. several
+ simultaneous SU failures in an ordered serialized manner.
+
+ The events that could be deferred/recalled so far is
+ SG_FAILOVER_NODE_EV,SG_START_EV,SG_FAILOVER_SU_EV,
+ CLUSTER_SYNC_READY_EV,APPLICATION_START_EV and
+ APPLICATION_ASSIGN_WORKLOAD_EV.
+
+ Files involved:
+
+ Index: exec/amfnode.c
+ Index: exec/amfsg.c
+ Index: exec/amfutil.c
+ Index: exec/amfapp.c
+ Index: exec/amfcomp.c
+ Index: exec/amfcluster.c
+ Index: exec/amf.h
+
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1266 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-10-12 Hans Feldt <hans.feldt@ericsson.com>
+
+ This simple patch solves a problem we see when testing AMF. If a node leaves and joins the cluster quickly (within one second is default), the config change messages will not indicate that the node left and rejoined. The patch introduces a short delay in main() to make sure the token_timeout expires.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1259 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-10-09 Steven Dake <sdake@redhat.com>
+
+ Enable commit tokens to be processed properly in all circumstances.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1255 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix subset set operation to work properly.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1254 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Remove some debbugging code from totemsrp impacting performance.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1253 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-10-04 Lon Hohberger <lhh@redhat.com>
+
+ The patch contains:
+ The instantiaton of the component is performed with some new steps:
+
+ 1. SU invoke Comp to instantiate
+ 2. Comp multicast a new event
+ MESSAGE_REQ_EXEC_AMF_COMPONENT_INSTANTIATE
+ 3. Comp receive the new event
+ MESSAGE_REQ_EXEC_AMF_COMPONENT_INSTANTIATE
+ 4. If the Comp is within the SU hosted on the node. The
+
+ component invokes
+
+ the clc_cli instantiate script to start the component
+
+ and start a timer
+
+ to supervise the start and registration of the component.
+ 5. If the instantiation time elapse before the component has
+ registered himself
+ Comp is sending a new multicasted event
+ MESSAGE_REQ_EXEC_AMF_COMPONENT_INSTANTIATE_TMO.
+ 6. Comp receive
+
+ MESSAGE_REQ_EXEC_AMF_COMPONENT_INSTANTIATE_TMO event.
+
+ 7. The Comp presence state is set to
+ SA_AMF_PRESENCE_INSTANTIATION_FAILED
+ 8. When all Components are in presence state
+
+ SA_AMF_PRESENCE_INSTANTIATED or
+
+ SA_AMF_PRESENCE_INSTANTIATION_FAILED the start or restart will
+ continue with
+ the assignment of load.
+
+ This implemntation means that the complete instantiation procedure
+ never will be endlessly waiting for a register. The
+
+ instantiation will
+
+ either turn out in a component instantiation failure or a success.
+
+
+ Hardening of the cluster start use case:
+
+ 1. A clearer separation of the responsibilities between
+
+ amf_cluster and
+
+ amf_application.
+
+ 2. A clearer interface and separation between amf_main (amf.c) and
+ amf_cluster.
+
+ 3. A clearer interface and separation between amf_cluster
+
+ and amf_node.
+
+
+ 4. A clearer separation of the responsibilities between amf_node and
+ amf_application.
+
+
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1251 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-09-29 Hans Feldt <hans.feldt@ericsson.com>
+
+ The configuration attribute 'saAmfSGNumPrefInserviceSUs' was not considered by AMF during initial start.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1250 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Two configuration attributes for SG objects were not handled correctly by the config parser.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1249 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-09-28 Hans Feldt <hans.feldt@ericsson.com>
+
+ Patches from Mathieu.Marie@sun.com: 2- On Solaris, the SA components executed have no names. 3- When killing the testamf1 component, it makes the aisexec process crash on both of my nodes. 4- max priority for RR on solaris is 59.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1247 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-09-25 Hans Feldt <hans.feldt@ericsson.com>
+
+ An update of README.amf to match current state of the implementation. README.amf now also includes a detailed list of what is currently NOT implemented.
+ README.amf includes now, as before, a "demo example".
+
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1244 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ - Fix for bug: 'default section created when syncing' - Section count synced correctly
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1243 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ global_ckpt_id fix #2 ckpt dump function
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1242 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-09-20 Hans Feldt <hans.feldt@ericsson.com>
+
+ Correction to a problem when a cluster consisting of several nodes starts initially in an order such that at least two nodes start after at least one node has been started and its SUs has been instantiated.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1241 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-09-12 Hans Feldt <hans.feldt@ericsson.com>
+
+ Created
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1240 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-09-11 Hans Feldt <hans.feldt@ericsson.com>
+
+ Fix for global_ckpt_id not synced
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1239 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-09-06 Hans Feldt <hans.feldt@ericsson.com>
+
+ - ckpt_id was not synced. - debug printout of list reduced
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1238 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-09-05 Hans Feldt <hans.feldt@ericsson.com>
+
+ 1. Improvement to manage more than one SG within an Application and to asymmetrically distribute the SG:s among the Nodes. 2. strcmp bug fixes several *_find functions. 3. Minor bug fixes.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1237 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ - "No need for DNS or /etc/hosts"
+ The call to gethostbyaddr() has been removed. This has been replaced by a
+ protocol where each node multicasts its hostname (obtained with gethostname()).
+
+ - "Logical AMF nodes"
+
+ The AMF node name is no longer a hostname. The saAmfNodeClmNode
+ configuration attribute of the AMF node is now the hostname. This config
+ attribute is now mandatory. The change to amf.conf file shows required changes.
+
+ - Some other AMF sync bug fixes
+
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1236 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-09-01 Hans Feldt <hans.feldt@ericsson.com>
+
+ Added file and line of caller, useful for troubleshooting.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1235 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ - enable the global debug flag again, individual 'logger' directives might be used to disable a certain logger source. - when DEBUG compiled it does not use the new printer threads (printouts are not buffered) - man page update - openais.conf update
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1234 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-08-28 Hans Feldt <hans.feldt@ericsson.com>
+
+ Allow AMF to handle health check responses while syncing.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1233 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ 1. Improvement of the use case 'Amf node leave spontaneously' 2. Improvement of the use case 'Amf node join' 3. Improvement to manage more than one SG within an Application. 4. Improvement to manage an arbitrary number of Csi-assignments associated to the Csi
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1232 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-08-28 Fabien Thomas <fabien.thomas@netasq.com>
+
+ add missing clean for libcfg
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1231 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-08-24 Fabien Thomas <fabien.thomas@netasq.com>
+
+ correct fd leak on error case
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1229 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ correct broken POLLHUP, POLLERR under BSD
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1228 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-08-24 Hans Feldt <hans.feldt@ericsson.com>
+
+ AMF sync improvements: change assert to return in mcast rec.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1227 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ testamf1.c improvements
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1226 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-08-23 Fabien Thomas <fabien.thomas@netasq.com>
+
+ return SA_AIS_ERR_INVALID_PARAM when vector ptr is NULL or len equal to 0
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1225 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-08-21 Fabien Thomas <fabien.thomas@netasq.com>
+
+ doc was not updated when switching command line options to lowercase
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1222 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-08-18 Fabien Thomas <fabien.thomas@netasq.com>
+
+ do not include alloca.h under BSD; alloca is in stdlib.h
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1221 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-08-17 Hans Feldt <hans.feldt@ericsson.com>
+
+ AMF sync #2
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1220 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-08-17 Fabien Thomas <fabien.thomas@netasq.com>
+
+ add command line support with: launch as a foreground application, do not set priority
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1219 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-08-16 Steven Dake <sdake@redhat.com>
+
+ Add scalability to 128 nodes by adding new parameter to protocol which is a random timeout bounded by a configuration parameter when sending join messages.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1214 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Return ERR_TIMEOUT if timeout value is zero in saEvtChannelOpen
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1211 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix make install to install clm shared object files properly.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1208 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Improve recovery code to produce correct printf notice outputs.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1207 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix debug output for testckpt service.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1206 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-08-11 Hans Feldt <hans.feldt@ericsson.com>
+
+ - New sync state machine, implemented and described in amf.c - One AMF node reads the AMF config file (IMM style) - One AMF node syncs others AMF nodes - One AMF object is serialized and sent as one message - Serialization/deserialization of most objects is trivial (memcpy) except for component and csi-attributes objects which have variable size arrays/strings. - Depth first AMF object tree traversal preserves relations when syncing - Ordered lists of SUs and SIs - Constructors/destructor per class - Serializers/deserializers per class - Config-change changes sync state - Sync callbacks executes the sync - "Use case" tracing for sync using the SYNCTRACE macro (trace6) - Sync master is initially the winner of a timeout race and if the master leaves the cluster, the node with the lowest node ID becomes new master. - amf_malloc implements an AMF central malloc routine with error handling.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1200 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-08-11 Patrick Caulfield <pcaulfie@redhat.com>
+
+ fixe a bug in cpg where get_group() will return the wrong group info structure if there is a hash collision.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1199 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-08-08 Steven Dake <sdake@redhat.com>
+
+ Fix checkpoint header file error
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1178 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-08-05 Steven Dake <sdake@redhat.com>
+
+ Committed a bunch of changes for testing scalability - reverting patch
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1177 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ non-blocking syslog and file logging support
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1176 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Solaris port for openais
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1175 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-08-03 Steven Dake <sdake@redhat.com>
+
+ Make sure sync_activate is called only once per service handler.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1174 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-08-02 Hans Feldt <hans.feldt@ericsson.com>
+
+ Removes the hardcoded limit of environment variables and argvs from components, now unlimited.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1172 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-08-01 Hans Feldt <hans.feldt@ericsson.com>
+
+ - Handling of HUP and other poll errors improved in saAmfDispatch. - Termination of testamf1 when saAmfDispatch returns an error.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1171 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-07-29 Steven Dake <sdake@redhat.com>
+
+ Patch so realloc reverts to old buffer if reallocation fails.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1170 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix lock marshalling.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1169 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-07-26 Steven Dake <sdake@redhat.com>
+
+ Endian conversion for evs service.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1168 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Endian cleanup for ykd.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1167 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Cleanup log_printf to use gnu attributes to do automatic type checking.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1166 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Endian conversion for the lock service.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1165 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Use memb_ring_id_copy for alignment purposes on 64 aligned arches and keep the port id in host byte order until it is used in the totem protocol stack.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1164 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add endian cleanup fixes.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1163 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Clean up endian swabbing for cpg service.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1162 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix where setsockopt is bound to in totemnet.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1161 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Cleanup comparisons in lcr_ifact and use strtok_r instead of junky parser.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1160 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add errno.h include since it was removed from swab.h.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1159 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Remove bunch of unused includes from swab.h.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1158 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix processor count in evs interface.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1157 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Endian cleanup for the clm service.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1156 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-07-24 Steven Dake <sdake@redhat.com>
+
+ Allow build type of COVERAGE for code coverage analysis
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1152 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-07-21 Steven Dake <sdake@redhat.com>
+
+ Ensure make install works with recent libcfg changes.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1151 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-07-21 Patrick Caulfield <pcaulfie@redhat.com>
+
+ Add a 'family' parameter to totemip_parse so it can be told to look for either IPv4 or IPv6 addresses, or both.
+ As we get the (unambiguous) multicast address first, we can make sure we always
+ look for the right type of node address afterwards.
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1150 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-07-21 Steven Dake <sdake@redhat.com>
+
+ Increase IPC thread stack size from 100k to 200k to accomodate larger data structures in ipc message handlers (for the CLM service).
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1149 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Remove TODO for swabbing conn data structure
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1148 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Validate IO Vector elements in a saCkptCheckpointWrite operation
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1147 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Remove TODO comment that has long been fixed in the code.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1146 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Correct malloc of checkpoint iteration size from 500 bytes to max section id size bytes for the created checkpoint
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1145 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Reduce memory usage in large configurations by dynamically allocating fragmentation assembly buffer.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1144 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Remove marshall TODO items as they are not needed
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1143 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Remove unnecessary exit from testevs
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1142 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-07-20 Steven Dake <sdake@redhat.com>
+
+ Remove debug printf in totemsrp
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1141 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Don't segfault if unauthorized user connects
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1140 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Make checkpoint service work according to specifications with regards to the unlink operation.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1139 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-07-19 Steven Dake <sdake@redhat.com>
+
+ Remove compile warning from cfgtool commit.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1138 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add support for reenabling a failed redundant ring and printing ring status through the test/opeanis-cfgtool application.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1137 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-07-19 Patrick Caulfield <pcaulfie@redhat.com>
+
+ Send the new joinlists using the sync service, so it happens atomically. This should fix some odd sequencing bugs.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1136 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-07-18 Patrick Caulfield <pcaulfie@redhat.com>
+
+ printing ipv6 addresses often needs more than a 32 byte buffer. THis could causes a crash with sone ipv6 installations.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1135 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-07-18 Steven Dake <sdake@redhat.com>
+
+ Support for ia64 arch builds.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1133 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-07-17 Steven Dake <sdake@redhat.com>
+
+ Fix synchronization not working properly.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1132 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Event marshalling patch for 32/64/endian support.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1131 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ If version field is NULL as passed to saClmInitialize, return INVALID_PARAM
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1130 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ If TRACK_CURRENT is specified in CLM service and notify buffer is null, return tracking data in callback as per specification.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1129 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Remove debug printf in track stop operation
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1128 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Check for invalid handles first in API calls.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1127 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ If the max section size is less then the read size, return INVALID_PARAM.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1126 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Return INVALID_PARAM when section read is larger then checkpoint section
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1125 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-07-16 Steven Dake <sdake@redhat.com>
+
+ CheckpointRead wasn't checking the active replica was set.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1124 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ The creation attributes set bit wasn't set from the library to executive message handlers causing significant problems with open was called from a app.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1123 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ The open flags are used before they are verified to be valid.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1122 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-07-14 Steven Dake <sdake@redhat.com>
+
+ Proper barrier operation as requested.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1121 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add support for s390 and s390x architectures.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1120 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-07-13 Steven Dake <sdake@redhat.com>
+
+ Fix library renames to 2.0.0 as needed by distros.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1119 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-07-12 Steven Dake <sdake@redhat.com>
+
+ Update to checkpoint service to use new APIs as rest of services do.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1118 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-07-11 Steven Dake <sdake@redhat.com>
+
+ Fix broken timers when release type set to RELEASE
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1117 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Remove dead definition of struct queue
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1116 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Missing commit from previous rename of saServiceConnectTwo
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1115 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Rename saConnectServiceTwo to saConnectService
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1114 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix typo in saMsg.h header file.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1113 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Rev versions to 2.0 and update versions script for all services
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1112 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-07-07 Steven Dake <sdake@redhat.com>
+
+ The member list, joined list, and left list in configuration changes was not valid.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1111 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-07-07 Fabien Thomas <fabien.thomas@netasq.com>
+
+ remove commited conflict
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1110 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-07-07 Patrick Caulfield <pcaulfie@redhat.com>
+
+ testcpg -i shows node ids as IP addresses.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1109 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-07-07 Hans Feldt <hans.feldt@ericsson.com>
+
+ - Error escalation improved, SU failover recovery action added - Most runtime attributes in the inf. model calculated in runtime from more fundamental information. (improves consistency) - sg_assign_si can now recalculate workloads considering existing assignments - Logging improvements, similar to what is required as notification in AMF spec. - CLC-CLI INSTANTIATE now exits aisexec when it fails (should later be sent as an NTF alarm) - CLC-CLI CLEANUP correctly handles already terminated processes - testamf1.c printouts removed for normal operation - Iterator functions for SI/CSI assignments
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1108 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-07-07 Steven Dake <sdake@redhat.com>
+
+ Make sure RELEASE version detaches from tty
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1105 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ The testcpg tool now prints IP addresses instead of a hex value indicating the node id.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1103 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ The recent endian/32/64 changes broke cpg callbacks. The left list address was incorrectly calculated.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1102 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-07-06 Steven Dake <sdake@redhat.com>
+
+ The totem rrp incorrectly increased the wrong failure counter.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1101 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-06-30 Steven Dake <sdake@redhat.com>
+
+ marshall of cpg_join name field is wrong.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1100 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Rework of the timer system to allow timers to be added in dispatch handlers.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1099 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-06-29 Steven Dake <sdake@redhat.com>
+
+ Rewrite of the checkpoint benchmark using threads tool
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1098 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ set serialize lock to proper function.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1097 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Rework of IPC layer once again
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1096 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-06-28 Steven Dake <sdake@redhat.com>
+
+ Fix problem where AMF locks up system if two or more components are members of the same service unit. Also fixes problem where AMF asserts if two or more components are specified in a service unit.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1095 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix 32/64 endian for all services from a previous missed commit.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1094 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix double free problem in ipc by reworking libais_disconnect to match previous rewritten model in picacho.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1092 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-06-27 Hans Feldt <hans.feldt@ericsson.com>
+
+ AMF changes: - Revised cluster start - Includes Steven's "amf invalid write patch" - Includes "components not started with 0.76" patch - New timer API use backed out of AMF (temporary)
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1091 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-06-26 Steven Dake <sdake@redhat.com>
+
+ Finally remove all references to ais_amf.h and replace with saAmf.h.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1090 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Corrected timer deadlock that occurs when a timer add or delete operation occurs within a timer expiration event.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1089 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Removed ais_amf.h and instead point all refs to saAmf.h
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1088 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-06-25 Steven Dake <sdake@redhat.com>
+
+ Remove dead file
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1087 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-06-23 Steven Dake <sdake@redhat.com>
+
+ Missed commit of marshall file for some reason.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1086 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Make cpg 32/64 userland safe and endian safe.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1085 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-06-22 Patrick Caulfield <pcaulfie@redhat.com>
+
+ Fix message alignment in CPG. we now unpack the message in the same way as we pack it.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1084 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-06-22 Steven Dake <sdake@redhat.com>
+
+ Change makefile to install swab from correct place
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1081 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ New make release in top level makefile
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1077 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-06-21 Steven Dake <sdake@redhat.com>
+
+ Modify AMF to use new timer.c/timer.h routines properly
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1076 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ 32/64/mixed endian support for checkpoint service.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1074 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix for early logging from Hans.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1073 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix error where pathlist buffer is overrun resulting in segfault
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1072 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-06-20 Hans Feldt <hans.feldt@ericsson.com>
+
+ Refactoring of AMF into several files (based on classed in inf. model). A central header file (amf.h) keeps all the definitions and prototypes needed.
+ New things apart from that:
+ - some doxygen html generated from AMF e.g. each file has a description
+ - saAmfHAStateGet() now works
+ - component invoked healthchecks implemented (but not tested)
+
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1071 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-06-20 Steven Dake <sdake@redhat.com>
+
+ Fix off by one error in totemsrp.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1070 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-06-19 Steven Dake <sdake@redhat.com>
+
+ Missed timer commit.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1069 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ missed commit
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1068 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-06-16 Steven Dake <sdake@redhat.com>
+
+ deferred timer system so that timers may be deferred during synchronization.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1067 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix dependencies and install all header files for external service handlers. New defination required to build external service handlers.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1066 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Allow CFLAGS and LDFLAGS to be overridden through the environment or command line.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1065 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-06-06 Steven Dake <sdake@redhat.com>
+
+ Remove warnings in AMF executive service.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1061 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Update TODO file with cluster membership 32/64/endian work being completed.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1060 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ 32/64/endian everything should work now for openais clm service.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1059 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-05-31 Hans Feldt <hans.feldt@ericsson.com>
+
+ - (Re-)introduction of event based multicast messages (not all yet) - Use of Distinguished Names (DN) in API and multicast messages - CSI resassignment properly handled (by using restarting state) - State 'setter' functions with uniform printouts - Simple 'assign SU to host' algorithm: - based on saAmfSUHostedByNode config attribute - see config file for example - Debug print runtime attributes upon user request: $ pkill -USR2 aisexec - Object-oriented naming of functions started (but not finished) - testamf1.c updated with some new tests - Minor fix in print.h and print.c - AMF can be started on two nodes (example config file needs modification for this)
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1058 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-05-29 Steven Dake <sdake@redhat.com>
+
+ Set to SCHED_RR:1 to match ipc layer
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1057 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ sched_setscheduler was passing wrong argument
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1056 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-05-27 Steven Dake <sdake@redhat.com>
+
+ Update TODO to match 2006 project priorities.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1055 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ This sanitizes the makefiles in several ways * .so and .so.1 files are linked to library.so.1.0.0 and installed with make install * renames all build targets to library.so.1.0.0 from library.so.1.0 * puts ld.so.conf.d files in the correct place * allows not installing static libraries by using make install STATICLIBS=NO
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1054 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ This patch checks the result of read operations on a socket which can return errors or 0. Now if those cases happen, the operation is ignored. This part of the code needs more attention later to handle short reads. This removes a warning when fortify source is defined to the compiler.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1053 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ This patch does the following things: * changes the default search path for lcrso files to /usr/libexec/lcrso * checks the result of getcwd which can fail and return an error - in that case handle the error appropriately * changes a comment that was incorrectly stating only the cwd was being searched for lcrso files
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1052 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Under load, it was observed that the token could be lost because the totem protocol was not being scheduled above the other I/O processes. This patch reinstalls the sched_setscheduler call which for some reason was commented out.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1051 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-05-26 Steven Dake <sdake@redhat.com>
+
+ defect 1270 Fix checkpoint read operation which would return invalid operation in some circumstances.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1050 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Remove scandir error=%s printf since it spews a bunch of errors when the aisexec is run after a make install
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1049 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ sanitize make install in Makefile
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1048 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix segfault if rrp_mode: MODE isn't set in configuration file.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1047 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Remove warning about memb_set_print not being used. This is only useful for debugging.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1046 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Remove deliver_fn which is not the ipc delivery function handler but the executive multicasted messages delivery function. This was inadvertantly copied and pasted from main.c
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1045 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Properly process the ld.so.conf file if it has includes.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1044 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Remove warning about unsigned/signed passed to strcpy
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1043 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Modified initscript to not start by default on redhat systems
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1042 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Return unsigned char as needed by gcc 4.1
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1041 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ code analysis found a memset overwrote a data structure.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1040 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-05-25 Patrick Caulfield <pcaulfie@redhat.com>
+
+ Add missing endian conversion to memb_merge_detect
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1039 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-05-23 Patrick Caulfield <pcaulfie@redhat.com>
+
+ Remove poinless man-page. bug fix CPG example.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1038 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-05-22 Steven Dake <sdake@redhat.com>
+
+ commit for redundant ring take 4 was only done from exec directory missing all of the commits for the rest of the directories. This commit will now allow the tree to compile.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1035 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ First take at doxygen support for openais APIs.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1034 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-05-19 Steven Dake <sdake@redhat.com>
+
+ Endian fixes for the recent redundant ring protocol work plus the cluster membership API support.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1033 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ The redundant ring take 4 patch. This includes modes for active, passive, and none. Read openais.conf.5 for information regarding how to configure redundant ring.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1032 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Patch to allow system to work if no ld.so.conf is present. ld.so.conf is optional and may not be present on a system.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1031 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-05-19 Patrick Caulfield <pcaulfie@redhat.com>
+
+ Don't crash if we get an unathenticated connection from a library.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1030 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Allow the syslog facility type to be set in the configuration file.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1029 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-05-17 Patrick Caulfield <pcaulfie@redhat.com>
+
+ Move CPG_SERVICE into service_types where it belongs.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1028 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Close ld.so.conf file descriptor when finished with it.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1027 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-05-17 Hans Feldt <hans.feldt@ericsson.com>
+
+ Introduction of SA Forum information model for AMF as specified in SAI-Overview-B.02.01.pdf. Other AMF changes as specified in SAI-AIS-AMF-B.02.01.
+ Summary:
+
+ - SA Forum B.02 Information model for AMF
+ - groups.conf renamed to amf.conf
+ - amf.conf syntax changed heavily to follow SA Forum specs.
+ - AMF works when daemon.
+ - linux lists removed from AMF
+ - component cmd environment variables support
+ - component argv support
+ - multi value csi attributes
+
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1026 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-05-15 Patrick Caulfield <pcaulfie@redhat.com>
+
+ getaddrinfo() doesn't actually set errno, it has its own error variable, so returning -errno is not useful (it may be zero even if getaddrinfo failed).
+ So, simply return -1 if getaddrinfo fails, to indicate a name resolution
+ or badly formed address.
+
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1025 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-05-11 Steven Dake <sdake@redhat.com>
+
+ Environment variable cleanup, documentation of environment variables in man pages, and rename of one of the environment variables used to specify the main openais configuration file.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1024 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-05-10 Fabien Thomas <fabien.thomas@netasq.com>
+
+ fix compile under darwin: sched_setscheduler does not exist
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1023 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-05-10 Hans Feldt <hans.feldt@ericsson.com>
+
+ - Preprocessor flags to control user, group and directory for configuration files removed.
+ - Environment variables for the same thing added:
+ OPENAIS_AISPARSER_FILE
+ OPENAIS_AMF_CONFIG_FILE
+ OPENAIS_TOTEM_AUTHKEY_FILE
+
+ - Make depend target in exec makefile updated with missing source files.
+
+
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1022 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-05-03 Hans Feldt <hans.feldt@ericsson.com>
+
+ - printouts buffered before log_setup() has been called, flushed at early exit. - rests of old logging removed from all code (#define LOG_SERVICE...). - line feed added if not in message. - new trace() function added so that trace macros adds minimum of code and runtime penalties to user code. - ENTER_ARGS macro changed to ENTER. ENTER macro now requires arguments. - openais.conf.5 man page updated with logger directives.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1021 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-05-02 Patrick Caulfield <pcaulfie@redhat.com>
+
+ Cope with >32 groups on a node that goes down. Add a missing endian conversion.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1020 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-04-30 Steven Dake <sdake@redhat.com>
+
+ Fix comile failures for BSD/Darwin port
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1019 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ add vsf none option for those that don't want a virtual synchrony filter
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1018 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-04-28 Steven Dake <sdake@redhat.com>
+
+ Fix up mutexes to avoid deadlocks
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1017 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-04-28 Patrick Caulfield <pcaulfie@redhat.com>
+
+ A misplaced close brace, caused cpg to only return the first node in the list went several went down.
+ Also, replaced totemip_equal() calls with nodeid comparisons as CPG works
+ entirely on nodeIDs anyway.
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1016 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-04-27 Steven Dake <sdake@redhat.com>
+
+ Remove prio commented out code
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1015 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add invalid handle definition
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1014 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Remove priority from aispoll since we now use the kernel scheduler for priorities for polling
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1013 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add IPC files from missing previous commit
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1012 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ This patch reworks IPC to use threads instead of the main poll loop
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1011 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix segfault because list was not reinitialized after its entry was deleted and it would later be deleted by closing the ipc. the
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1010 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-04-26 Hans Feldt <hans.feldt@ericsson.com>
+
+ test commit, one line amf.c change in clc_cli_cleanup
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1009 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-04-25 Fabien Thomas <fabien.thomas@netasq.com>
+
+ Remove warnings under Darwin
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1008 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-04-25 Steven Dake <sdake@redhat.com>
+
+ Fix scanning of LCRSOs not working on various systems
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1007 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Patch to ensure backlogs are never negative which would cause problems with the flow control algorithm and protocol in general.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1006 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Allow running with BUILD_DYNAMIC set to zero.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1005 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-04-24 Steven Dake <sdake@redhat.com>
+
+ Patch from Hans to clean up some error handling in main.c when service handlers do the wrong thing.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1002 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Patch from Hans to clean up main error handling a little bit
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1001 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Clean out private key memory area in case of parser override is used
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1000 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Patch from Hans to fix segfault in loading of LCR components
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@999 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-04-21 Steven Dake <sdake@redhat.com>
+
+ More make install work to install all necessary files
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@998 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-04-20 Mark Haverkamp <markh@osdl.org>
+
+ Updated copyright dates.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@997 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-04-19 Steven Dake <sdake@redhat.com>
+
+ Make install now works along with different search paths for openais's lcrsos.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@996 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-04-18 Steven Dake <sdake@redhat.com>
+
+ Patch from Hans to significantly improve the logging functionality read openais.conf.5 for info on how the new logging works.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@995 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-04-16 Steven Dake <sdake@redhat.com>
+
+ Remove segfault when object database can't be loaded
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@994 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Remove segfaults when object database can't be loaded for some reason.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@993 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-04-15 Steven Dake <sdake@redhat.com>
+
+ remove -DDEBUG from release build
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@992 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 1201 cleanup poll_dispatch_delete in trunk
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@991 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ remove warnings form totemrrp and also fix bug where send_flush wasn't being called for the active replication algorithm
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@990 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ remove printf on evs join because groups may be binary data and crash executive
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@989 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix warning about unsigned int passed to orf_token_rtr for flow control count
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@988 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix warning regarding unsigned int for node_id
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@987 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix object_priv_get to actually call object_priv_get instead of object_priv_set
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@986 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ cleanup warning in service.c because unsigned char * is passed to atoi instead of char *
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@985 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add missing vsf.h from previous commit
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@984 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-04-14 Steven Dake <sdake@redhat.com>
+
+ fix fc5 segfault correctly by removing code that violates strict aliasing rules.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@983 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ scale part 3 componentize YKD dynamic linear voting algorithm
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@982 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-04-13 Steven Dake <sdake@redhat.com>
+
+ Improvement of the rrp_algo data structure to support only running totemnet api calls on the appropriate totemnet interfaces.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@981 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Workaround possible optimizer bug in gcc 4.1 by forcing a function not to inline. This would cause segfaults on fc4.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@980 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ move nodeid from interface section to totem section
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@979 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-04-10 Patrick Caulfield <pcaulfie@redhat.com>
+
+ - Fix BUILD_DYNAMIC=0 (add amfconfig.o to SERV_OBJS) - add objdb->object_find_reset() before looking for user/group names.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@978 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Split the logging config options into three keys: to_file, to_stderr & to_syslog
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@977 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-04-09 Steven Dake <sdake@redhat.com>
+
+ defect 1191 Add more support for the redundant ring protocol.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@976 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 1190 scale to 128 nodes more effectively by dynamically sending partial structures in the commit token ahd memb_join messages.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@975 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 1139 reorg of code to better support creating external service handlers
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@972 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 1170 another fix for the assertion in memb_recovery_enter
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@971 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-04-07 Patrick Caulfield <pcaulfie@redhat.com>
+
+ Use the tmp variable in the right iterator loop ! With debug enabled, that's a guaranteed crash in cpg when a node leaves.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@970 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-04-06 Patrick Caulfield <pcaulfie@redhat.com>
+
+ Use objdb for configuration. All components now get a reference to the objdb rather than openais_config.
+ The default config object "aisparser" reads openais.conf as before, but can
+ be overridden by an environment variable.
+
+ Bug 1132
+
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@969 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-04-06 Steven Dake <sdake@redhat.com>
+
+ defect 1170 remove extra debug exit(1
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@968 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 1170 Fix recovery protocol to avoid assertion in memb_state_recovery_enter
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@967 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-04-04 Steven Dake <sdake@redhat.com>
+
+ defect 205 implement totem single ring protocol flow control algorithm
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@966 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-04-03 Patrick Caulfield <pcaulfie@redhat.com>
+
+ Set the object value length too.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@965 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-03-31 Steven Dake <sdake@redhat.com>
+
+ Fix typo is clc_cli_script
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@963 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 1172 checkpoint service asserts under load during configuration changes
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@962 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-03-31 Fabien Thomas <fabien.thomas@netasq.com>
+
+ defect 1178: use synchronous lock structure on reply
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@961 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-03-29 Steven Dake <sdake@redhat.com>
+
+ defect 1153 Fix segfault with sync service if syncronization is interrupted during recovery.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@960 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-03-28 Muni Bajpai <muni.osdl@gmail.com>
+
+ defect 1192 Fixes the issue of ckpt sections getting reordered and also fixes the issue of synchronizing ckpt while under the retention timer.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@959 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-03-28 Patrick Caulfield <pcaulfie@redhat.com>
+
+ Call a service's config_init_fn() as soon as it is loaded. Then call exec_init_fn() after other initialisation has happened.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@958 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-03-27 Steven Dake <sdake@redhat.com>
+
+ patch from Hans to support amf B types
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@957 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-03-24 Steven Dake <sdake@redhat.com>
+
+ enhancement 1145 Patch from Lars to implement csi attribute setting in config file and delivered via callback.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@956 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Patch from Hans to fix up the configurable /var/run and /etc/ais directory support.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@955 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-03-24 Fabien Thomas <fabien.thomas@netasq.com>
+
+ Bug 1130: add totempg log; remove warnings; add DPRINT macro
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@954 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-03-23 Steven Dake <sdake@redhat.com>
+
+ objdb merge add missing service.c file
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@953 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-03-18 Steven Dake <sdake@redhat.com>
+
+ defect 1139 merge object database and do a general refactor of the code
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@952 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-03-17 Steven Dake <sdake@redhat.com>
+
+ Patch from Hans This patch (against r950) makes it possible to change the directory where aisexec searches for configuration files. Pretty much in line with the possibility to specify user and group. Just do:
+ make OPENAIS_CONFDIR=/tmp/ais
+
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@951 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-03-16 Steven Dake <sdake@redhat.com>
+
+ Patch from Hans Feldt This small patch (against r948) adds variable CPPFLAGS to all make rules that compiles `.c' files into `.o' files.
+ This makes it possible to set CPPFLAGS on the command line as in:
+
+ $ make CPPFLAGS=-DAMFDEBUG
+
+ Editing the makefile when prototyping is then not needed.
+
+ Another reason is that some of the openais C files are built using the
+ implicit rule for C files (which uses CPPFLAGS). The change makes rules
+ consistent with the implicit rule.
+
+ It also adds a few missing files to the clean make target.
+
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@950 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-03-15 Muni Bajpai <muni.osdl@gmail.com>
+
+ Fix the innacurate dataSize in the Checkpoint Read response reported by Bjorn.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@949 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-03-08 Steven Dake <sdake@redhat.com>
+
+ defect 1113 Checkpoint iteration is totally broken. This patch makes checkpoint iteration work properly for multiple checkpoint iterators and now is compliant with the specifications for the trunk version.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@948 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 1117 binding to localhost doesn't work. This patch reenables that functionality.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@947 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 1120 The AMF code doesn't detect invalid healthcheck keys and crashes when an invalid healthcheck key is specified.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@946 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 1116 The IPC code spins in recvmsg in the library resulting in poor performance and deadlock in the AMF service.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@945 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-03-07 Fabien Thomas <fabien.thomas@netasq.com>
+
+ repair OPENAIS_COVERAGE, OPENAIS_PROFILE
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@944 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ use sched_get_priority_max to set the maximum priority
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@943 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-03-07 Muni Bajpai <muni.osdl@gmail.com>
+
+ defect 1115 added support for reinitializing synchrony to support ongoing sync during a re-configuration.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@942 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-03-06 Muni Bajpai <muni.osdl@gmail.com>
+
+ defect 1115 fix faulty check.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@941 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-03-06 Patrick Caulfield <pcaulfie@redhat.com>
+
+ Add man pages for the libcpg functions.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@940 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix testcpg.c so it actually works.
+ in exec/cpg: Don't regard a process as joined until all all nodes have
+ received the message.
+ Don't send other nodes' processes in a joinlist message!
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@939 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-03-06 Muni Bajpai <muni.osdl@gmail.com>
+
+ bug 1115. Fixes the synchronization algorithm which was skipping services.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@938 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-03-05 Muni Bajpai <muni.osdl@gmail.com>
+
+ Bug Fix for memory leak in ckpt section management. Bug 1112
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@937 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-03-03 Patrick Caulfield <pcaulfie@redhat.com>
+
+ Add cpg (closed process groups) component.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@936 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-03-03 Steven Dake <sdake@redhat.com>
+
+ defect 981 This patch fixes a problem where the synchronization engine would not work cross endian.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@935 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 981 This patch fixes a problem where ykd would not work cross endian
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@934 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 981 This patch fixes a problem where totempg would not work cross-endian.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@933 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-03-02 Muni Bajpai <muni.osdl@gmail.com>
+
+ reverting fix to man page as only 0.72 is broken with last byte zero in bindnetaddress
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@932 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-03-01 Muni Bajpai <muni.osdl@gmail.com>
+
+ Remove the reference to the use of 0 as last byte in the bindnetaddr
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@931 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-02-21 Steven Dake <sdake@redhat.com>
+
+ defect 1099 move "ais" init script to mvlcge add redhat init script from Bjorn
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@927 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fabien's patch for the BSD/Darwin port.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@926 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-02-15 Steven Dake <sdake@redhat.com>
+
+ Patch from Patrick This patch restores the functionality in previous versions where the node address could be specified as a network address in openais.conf
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@925 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ enhancement 1049 Patch from Patrick This simple patch stops a potential DoS. If a library tries to access a component that is not loaded into the exec then it will crash trying to deref ais_service_handlers[ service ]
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@924 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-02-11 Steven Dake <sdake@redhat.com>
+
+ enhancement 1088 This replaces MSG_DONTWAIT with an fcntl to O_NONBLOCK to be more portable for the BSD port since BSD doesn't support MSG_DONTWAIT properly.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@923 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 981 big endian and little endian in the same network causes infinite loop. This patch fixes that problem for the totem layer only. Other components are not resolved.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@922 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-02-10 Steven Dake <sdake@redhat.com>
+
+ Get rid of junk debug statement
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@921 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 1088 First patch for porting to BSD systems. This patch removes the WAITALL flag entirely from the library handlers, as it appears there may be some portability problems with this flag. The code already handles partial reads anyway, so it was not necessary.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@920 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 1066 original 1066 fix introduced new bug found with saftest
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@918 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Some versions of GCC were optimizing out the static ctor section. This patch makes the ctor non-static so it is not optimized out.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@917 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Cleanup of dynamic loading to allow using the same interface factory code for statically linked components.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@916 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-02-02 Steven Dake <sdake@redhat.com>
+
+ Patch from Patrick to enable configuring the list of dynamic service handlers in the configuration file.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@915 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-02-01 Steven Dake <sdake@redhat.com>
+
+ 1049 make all service handlers dynamically loadable or compilable statically use the BUILD_DYNAMIC flag in the makefile to set dynamic loading or static compile.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@914 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 1066 memory leak in saCkptSectionIterationInitialize
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@912 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 1065 memory leak in checkpoint iteration when IterationNext has a failure condition (like NO_MORE_SECTIONS)
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@910 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 1068 bug in saHandleDestroy could cause extra put on handle when the check is invalid
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@909 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-01-25 Mark Haverkamp <markh@osdl.org>
+
+ defect 1049 Fix compile error in testlck and testmsg. Use SA_AIS_OK.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@906 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-01-25 Steven Dake <sdake@redhat.com>
+
+ enhancement 1049 enhance services so dynamic service handlers are more easily possible
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@905 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-01-24 Mark Haverkamp <markh@osdl.org>
+
+ defect 1048 - make_event uses wrong handle database
+ Correct calls to saHandleDestroy to use the correct handle database.
+
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@903 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-01-24 Steven Dake <sdake@redhat.com>
+
+ defect 1046 SaErrorT in trunk branch, but only SaAisErrorT should be used
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@902 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-01-22 Steven Dake <sdake@redhat.com>
+
+ defect 1045 totempg is not thread safe, and AMF requires threads to instantiate components
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@898 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-01-20 Steven Dake <sdake@redhat.com>
+
+ This is a major rework of the service handling code. Now service handlers can be dynamically loaded via the live component replacement service. Sync handlers are also dynamically contributed.
+ It is possible to build using either dynamic loading via LCR or static
+ linking of the entire executive. This is controlled by the BUILD_DYNAMIC
+ configuration option in the Makefile.
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@892 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-01-16 Steven Dake <sdake@redhat.com>
+
+ remove old files that are no longer needed.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@891 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-01-14 Steven Dake <sdake@redhat.com>
+
+ Small man page cleanup
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@890 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-01-11 Mark Haverkamp <markh@osdl.org>
+
+ defect 1030
+ Check return pointer from malloc for NULL. Back out any previous malloc
+ to eliminate memory leaks. Return proper status.
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@887 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 1030 This fixes the event handle leak on failure, the malloc check for hl, removes the redundant memset when creating a handle, and makes sure that the put of the channel handle is a valid handle.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@886 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-01-07 Steven Dake <sdake@redhat.com>
+
+ defect 1024 YKD algorithm doesn't always work when new_message_queue is full.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@885 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-01-05 Mark Haverkamp <markh@osdl.org>
+
+ Fix for bug 1023. Fixes a problem where the dispatcher can lose track of available events if it gets SA_ERR_TRY_AGAIN from the exec.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@883 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-01-03 Steven Dake <sdake@redhat.com>
+
+ Add information about the event and amf directive in the openais.conf.5 man page.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@882 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Delete empty files.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@881 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ enhancement 1020 adds missing file from commit
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@880 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ enhancement 1020 Adds AMF B.01.01 support - still needs alot of work
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@879 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ enhancement 1019 Modify YKD to select primary component and execute the synchronization operation only in the main partition. In the non-primary partition, no new requests are allowed - they are all returned with the error code SA_AIS_ERR_TRY_AGAIN.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@878 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2006-01-02 Steven Dake <sdake@redhat.com>
+
+ defect 1006 on 64 bit platforms, the timer is not properly cleared resulting in segfaults
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@876 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ enhancement 1007 need way to install openais into user selectable directories
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@874 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ enhancement 1018 Add YKD dynamic voting algorithm to executive code
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@873 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-12-27 Steven Dake <sdake@redhat.com>
+
+ defect 999 clm library doesn't exit from poll when executive crashes
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@870 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ enhancement 989 improve process group membership interface in totem_pg
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@869 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-12-22 Steven Dake <sdake@redhat.com>
+
+ lock service locks up under certain conditions this patch fixes that problem from Mark
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@868 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-12-20 Steven Dake <sdake@redhat.com>
+
+ defect 993 ckpt-rd.c and ckpt-wr.c in the test directory don't run with the latest code.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@866 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 998 Sometimes the default section isn't synchronized
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@864 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-12-08 Steven Dake <sdake@redhat.com>
+
+ defect 982 Fixes ckpt list corruption on failure to allocate checkpoint replica
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@862 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-12-06 Steven Dake <sdake@redhat.com>
+
+ defect 988 The totem SRP handle is passed up the entire stack is not needed past certain functions.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@860 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-12-05 Steven Dake <sdake@redhat.com>
+
+ fix documentation error from specification which identifies SaLckResourceLockAsync as the function name in some places but saLckResourceLockAsync in other places. We settled on saLck since it matches the rest of the specifications.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@859 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-12-01 Steven Dake <sdake@redhat.com>
+
+ shared object name incorrectly set for the lock service to libSaLCK instead of libSaLck.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@858 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ fix documentation error from specification which identifies SaLckResourceLockAsync as the function name in some places but saLckResourceLockAsync in other places. We settled on saLck since it matches the rest of the specifications.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@857 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-11-30 Steven Dake <sdake@redhat.com>
+
+ defect 979 This enhancement adds support for IPV6 to the trunk of openais.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@856 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix defect 974 There was an infinite loop problem in the fix for defect 974
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@854 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-11-25 Steven Dake <sdake@redhat.com>
+
+ defect 932 This patch adds token sequence number and global sequence number rollover support. A window is used to ensure comparisons are done properly.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@852 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-11-23 Steven Dake <sdake@redhat.com>
+
+ defect 974 checkpoint service segfaults during synchronization because iteration item is deleted and iteration continues in unsafe fashion.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@850 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 969 processor_count_set is called in the wrong place causing the protocol to fail to receive.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@848 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 968 Heartbeat failure detection man page updates
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@846 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-11-22 Mark Haverkamp <markh@osdl.org>
+
+ Fix for Bug 875. Cleans up a channel that actually opened but the library request timed out.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@844 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-11-18 Steven Dake <sdake@redhat.com>
+
+ defect 965 Fix synchronization service lockup if the new_message_queue is full
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@842 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 956 fix assertion where new_message_queue is overflowed when a message is pending in the fragmentation queue.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@839 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-11-18 Mark Haverkamp <markh@osdl.org>
+
+ Fix for BUG 955. The base event ID needed to be set to one. event zero was being detected as already delivered and thrown away.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@837 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-11-18 Steven Dake <sdake@redhat.com>
+
+ defect 968 Improve worst-case failure detection time using active healthchecking
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@836 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-10-27 Steven Dake <sdake@redhat.com>
+
+ defect 914 fix gcc 4 specific compile warnings and compile errors
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@834 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-10-04 Steven Dake <sdake@redhat.com>
+
+ defect 909 c++ keywords are used in the internal implementation of list.h
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@832 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-09-29 Mark Haverkamp <markh@osdl.org>
+
+ Fix compiler warnings when HZ is defined to be a long. Bugzilla #904
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@830 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-09-29 Steven Dake <sdake@redhat.com>
+
+ defect 903 First cut at a distributed locking service.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@829 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-09-26 Steven Dake <sdake@redhat.com>
+
+ defect 898 don't need to copy message to fragmentation data buffer if message can be multicasted as is.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@827 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 897 fix new_message_queue can be overwritten
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@825 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-09-22 Steven Dake <sdake@redhat.com>
+
+ defect 896 Ruppert reported there was a missing typecast
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@822 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 895 Ruppert reported that there is code that doesn't do anything but should.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@821 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-09-21 Steven Dake <sdake@redhat.com>
+
+ reduce maximum message size since 253000 is beyond the max.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@818 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ remove extraneous debug printf
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@816 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-09-20 Steven Dake <sdake@redhat.com>
+
+ defect 892 Fix performance degradation when sending 10-15 messages per second because of a large seqno_unchanged_const. Also, seqno_unchanged_const does not have a configurable option and this patch adds that support.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@814 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-09-06 Steven Dake <sdake@redhat.com>
+
+ defect 856 - CHANGES and CHANGES_ONLY have identical effect with saClmClusterTrack()
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@812 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 855 - implement view numbers and report them correctly as per specs
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@811 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 854 - invalid return value displayed in test program
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@810 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-08-30 Steven Dake <sdake@redhat.com>
+
+ defect 841 Rabbe reported that cluster track callback operations dont work properly. This patch fixes that problem.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@809 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-08-29 Steven Dake <sdake@redhat.com>
+
+ defect 839 The timer interval can be set to less then the platform timing interval. This could result in negative timer values configured by the user which confuse the totem protocol.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@808 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 828 assert in totemsrp_avail occurs with certain test cases. The code was rounding down to zero when calculating the number of messages required. This patch adds one in all cases so no roundoff occurs.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@807 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 840 J Seltzer reported that closed checkpoints in the TRY_AGAIN state are not closed in the executive but are closed in the library. This patch fixes that problem.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@806 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-08-26 Steven Dake <sdake@redhat.com>
+
+ defect 837 Muni reported the token retransmission timer doesn't need to be reset when receiving a retransmission
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@805 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 833 Rabbe reported that the encoding of the ipv4 address in SaClmNodeAddressT is incorrect
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@804 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 824: replace network directive with totem directive in default configuration file
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@803 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 823 Typo in openias conf manpage reported by Rabbe
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@802 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-08-19 Mark Haverkamp <markh@osdl.org>
+
+ Fix for bug 825. SaEvtChannelClose needed to handle SA_AIS_ERR_TRY_AGAIN so that the eci_closing would be cleared before returning.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@800 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-08-18 Steven Dake <sdake@redhat.com>
+
+ This sets the receive and send transmission buffers to a larger size to avoid overruns of the multicast buffer.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@799 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ This fixes an off by one in queue_avail which resulted in an assertion during testing.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@798 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-08-17 Steven Dake <sdake@redhat.com>
+
+ defect 501 this patch fixes short reads and writes between the library and executive
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@797 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ enhancement 813 Rename ais_types.h header file to be more compliant with sa forum
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@796 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 822 checkpoint synchronization has serious bug after saftest fixups
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@795 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ enhancmement 821 Global reorganization of totem code and also many feature enhancments These include: need to specify whether authentication is enabled or dislabed in config file need to specify frame size in config file need redundant ring placeholder need to specify version field of totem need to support large frame sizes need to break out threading code from totemsrp need to break out network code from totemsrp need to break out parser code from parse.c and some others
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@794 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-08-13 Steven Dake <sdake@redhat.com>
+
+ Patch from Russell Bryant to fix up gcc 4 warnings
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@793 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-08-11 Mark Haverkamp <markh@osdl.org>
+
+ The current event service code will start rejecting received events after 4gig because it thinks that they are duplicates. This update fixes that problem. Now I am keeping a full 64 bit id for checking for duplicate/re-sends, etc. separate from the event ID. I also check that a new event ID is not in use by a retained event.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@792 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-08-05 Mark Haverkamp <markh@osdl.org>
+
+ Add a check field to the handle structure to make it less likely to get a random valid handle. Fix a couple bugs in the event service that this change exposed.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@791 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-08-02 Mark Haverkamp <markh@osdl.org>
+
+ Fix for BUG 803. We need to complete a library call even if the channel requested for unlink has been deleted previous to processing an unlink request.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@790 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-07-30 Steven Dake <sdake@redhat.com>
+
+ fixes segfault when ctrl-c pressed with new totemmrp code
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@789 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-07-29 Steven Dake <sdake@redhat.com>
+
+ fixes a missed merge in the totemmrp mergeup
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@788 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix a few compile warnings.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@787 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 796 fix saClmClusterTrack to operate according to specs.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@786 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 793 dont return SA_AIS_ERR_NOT_EXIST when tracking started with SA_TRACK_CURRENT only
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@785 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 792 saClmTrackStop not returning SA_AIS_ERR_NOT_EXIST
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@784 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 790 if sectionDescriptor is null in iteration next call, segfault occurs
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@783 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add infrastructure support for multiring to totem library Make totemsrp support multiple instances of a running protocol within one app. Rename libtotem to libtotem_pg because of a name conflict with some movie player
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@782 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-07-27 Mark Haverkamp <markh@osdl.org>
+
+ Move the check of subscription ID in lib_evt_event_subscribe before processing the filters.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@781 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix for bug 776. Don't require retained events to expire before deleting the channel on unlink.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@780 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-07-27 Steven Dake <sdake@redhat.com>
+
+ defect 784 readSize is not properly set after return from checkpoint read operation.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@779 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 785 ckptbenchth is completely broken. This patch fixes it to operate properly.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@778 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 788 ckptbench returns error 7 at 20000 byte size writes. The benchmark program improperly creates the checkpoint parameters.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@777 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-07-27 Mark Haverkamp <markh@osdl.org>
+
+ Fix for bug 773. Not quite the full fix, but the best we can do for now.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@776 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix for bug 774. Check malloc return before accessing pointer.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@775 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix for bug 782. Receved events may not be modified.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@774 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-07-26 Steven Dake <sdake@redhat.com>
+
+ defect 777 fix reference counting bugs in aispoll
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@773 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-07-25 Mark Haverkamp <markh@osdl.org>
+
+ Update saEvtEventPublist to return the correct error code when the event data size in too big. Bug 768.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@772 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-07-15 Steven Dake <sdake@redhat.com>
+
+ defect 754 tests dont build because makefile damaged
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@771 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 752 fix reference counting in checkpoint library
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@770 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 751 when ckptSectionIterationNext iterates all sections, SA_AIS_ERR_NO_SECTIONS not being returned.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@769 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 750 in saCkptIterationFinalize if no active replica set, return error
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@768 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 749 Make handle put work properly for IterationFinalize
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@767 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 748 rename sectioniterator to sectioniteration in executive and library
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@766 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defecct 747 in saCkptSectionIterationInitialize if sectionsChosen invalid, return INVALID_PARAM
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@765 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 746 return INVALID_PARAM in saCkptSectionIterationInitialize if address is NULL
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@764 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 745 in saCkptSectionCreate if initialData == NULL return INVALID_PARAM
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@763 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 744 return SA_AIS_ERR_EXIST in saCkptSectionCreate if maxSections == 1
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@762 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 743 in saCkptCheckpointSectionCreate return SA_AIS_ERR_NO_SPACE if current sections == maxSections
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@761 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 742 error not returned in saCkptSectionCreate if sectionCreationAttributes == NULL
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@760 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 741 saCkptCheckpointOpenAsync doesn't return error when checkpointSize > maxSections * maxSectionsSize
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@759 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 740 if open callback isn't set on saCkptCheckpointOpenAsync, return SA_AIS_ERR_INIT
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@758 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 739 saCkptCheckpointOpenAsync callback doesn't return error as per spec
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@757 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-07-13 Steven Dake <sdake@redhat.com>
+
+ defect 718 if no active replica is not set do not set expiration time and return error.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@756 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 717 if checkpoint is not writeable in durationset, return error
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@755 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 716 in durationtimeset if sectionId is null, return error
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@754 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 715 synchronize open missing break in dispatch causing checkpointsyncasync callback not to be called.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@753 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 714 if checkpoint doesn't have write permissions in section delete, return error
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@752 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 713 if active replica not set in section delete, return error
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@751 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 712 if sectionId is null in sectiondelete, return INVALID_PARAM
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@750 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 711 if no active replica set in checkpoint write, error not returned
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@749 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 710 if ioVector == NULL in checkpoint read error should be returned
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@748 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 709 if synchronize async called, but no callback set, error not returned
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@747 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 708 checkpoint synchronize async call not implemented
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@746 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 707 if checkpoint synchronize executedd with timeout=0, TIMEOUT error not returned
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@745 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 706 replica is not set based upon open flags as per specification
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@744 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 705 if synchronize executed on a checkpoint that was created WR_ALL_REPLICAS return error.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@743 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 704 if checkpoint is opened without read permissions, checkpoint synchronize should return SA_AIS_ERR_ACCESS.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@742 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 703 checkpoint synchronize calls do not check if active replica set
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@741 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 702 checkpoint synchronize missing executive handler
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@740 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 684 return INVALID_PARAM in checkpoint read if dataSize greater then maxSections * maxsectionsSize.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@739 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 683 if active replica not set, checkpointread should return SA_AIS_ERR_NOT_EXIST
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@738 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 682 null iovector caues checkpointRead to segfault
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@737 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 681 if null paramter passed to checkpoint service as iovector element, allocate the io vector element
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@736 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 680 ckptsectionoverwrite should return INVALID if dataSize greater then maxSections * maxSectionsSize
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@735 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 677 SectionOverwrite with null sectionId segfaults
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@734 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 676 sectionoverwrite doesn't return correct error when checkpoint section doesn't exist
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@733 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 675 section overwrite with null dataBuffer parameter locks up
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@732 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 734 cleanup include files and exports from libraries
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@731 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 732 req_amf_componentregister used instead of req_lib_amf_componentregister. There is no definition for req_amf_componentregister.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@730 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 731 error - saSendReceiveReply instead of error = function
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@729 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-07-07 Mark Haverkamp <markh@osdl.org>
+
+ Check for reserved event ID and return SA_AIS_ERR_INVALID_PARAM. Bug 694
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@728 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-07-01 Mark Haverkamp <markh@osdl.org>
+
+ Wait to return status to the library until the clear request was received over the network so that the publish and receipt of the event is in sync with the time clear request.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@727 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-06-30 Steven Dake <sdake@redhat.com>
+
+ defect 673 fix checkpoint unlink not cleaning up checkpoints.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@726 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 502 fix assert when packet added in multicast message handler.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@725 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Remove some warnings from the compile.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@724 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-06-30 Mark Haverkamp <markh@osdl.org>
+
+ Error comparing unsigned to less than zero.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@723 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-06-29 Steven Dake <sdake@redhat.com>
+
+ Enables test caes in saftest to pass by returning failure return codes in both callback and return function. This may have to change later if a later errata changes this functionality.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@722 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 669 token retransmits dont work under heavy load.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@721 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 656 libraries not built with position independent code. This causes x86_64 not to build.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@720 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 655 invalid checkpoint open flags should return ERR_BAD_FLAGS
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@719 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 654 wrong error code returned when checkpointSize > maxSections * maxSectionsSize in checkpoint open.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@718 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 653 saCkptCheckpointOpen segfaults if null parameter passed in checkpointName
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@717 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 652 saCkptCheckpointOpen segfaults if null parameter passed to checkpointHandle
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@716 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 651 - saCkptCheckpointUnlink segfaults if checkpointName attribute is null
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@715 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 646 - wrong return code in checkpoint open
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@714 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-06-28 Steven Dake <sdake@redhat.com>
+
+ Patch from Muni Bajpai to improve synchronization after a merge.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@713 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-06-27 Mark Haverkamp <markh@osdl.org>
+
+ saEvtEventAttributesSet needs to check that the priority value passed in is valid.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@712 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-06-27 Steven Dake <sdake@redhat.com>
+
+ Patch from Szakacsits Szabolcs to improve error detection in parsing configuration files.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@711 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-06-24 Mark Haverkamp <markh@osdl.org>
+
+ The channel open functions need to check for bad flags.
+ I set the newly created event elements to the default
+ values in the B spec.
+
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@710 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ I discovered that our SaAisErrorT is incorrect. I have included a patch to fix that. The SA_AIS_ERR_BAD_CHECKPOINT code doesn't exist. I replaced it with SA_AIS_ERR_BAD_OPERATION.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@709 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-06-23 Mark Haverkamp <markh@osdl.org>
+
+ The A spec required patterns to be set but the B spec doesn't. Fix lib/evt.c and test/testevt.c
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@708 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-06-22 Mark Haverkamp <markh@osdl.org>
+
+ This fixes some B spec related parameter checks
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@707 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Some fixes to the event service based on the saftest event tests results.
+ The changes may affect applications currently using the event service.
+
+ 1. Timeout value to the saEvtChannelOpen call was updated to use
+ SA_TIME_MAX instead of 0 for infinite timeout.
+
+ 2. added cleanup in the library to remove associated events when a
+ channel is closed, and remove associated channels when finalize is
+ called.
+
+ 3. Added some new checking args for NULL and returning the correct error
+ code.
+
+ 4. fixed dispatch to return correct status with SA_DISPATCH_ONE and no
+ available poll data.
+
+ 5. Makefile had bad dependency for evt library build.
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@706 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-06-17 Steven Dake <sdake@mvista.com>
+
+ defect 643 saClmNodeGet timeout parameter of 0 should return SA_AIS_ERR_TIMEOUT
+ (Logical change 1.224)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@705 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ clm.c: defect 643 saClmNodeGet timeout parameter of 0 should return SA_AIS_ERR_TIMEOUT
+ BKrev: 42b31c07wymW-ntnqdOvHrTrCDEEhA
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@704 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 642 fix segfault when null clusterNode parameter passed to saClusterNodeGet
+ (Logical change 1.223)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@703 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ clm.c: defect 642 fix segfault when null clusterNode parameter passed to saClusterNodeGet
+ BKrev: 42b31bd8J6eYpNHnpFWwHWc3waURXw
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@702 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ clm.c: defect 641 NodeGetAsync called with no nodeget callback should return SA_AIS_ERR_INIT
+ BKrev: 42b31ba3yncxyr2C6XoRwB_9yMdvRA
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@701 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 641 NodeGetAsync called with no nodeget callback should return SA_AIS_ERR_INIT
+ (Logical change 1.222)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@700 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 640 fix wrong error code when null version parameter passed to saClmInitialize
+ (Logical change 1.221)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@699 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ clm.c: defect 640 fix wrong error code when null version parameter passed to saClmInitialize
+ BKrev: 42b31b73Cok4gPBc42AbPIksg9Rw2w
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@698 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ clm.c: defect 639 fix segfault if null callback parameter passed to saClmInitialize
+ BKrev: 42b31b3dnxjnqS8cEzAPHPJmbMdVEw
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@697 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 639 fix segfault if null callback parameter passed to saClmInitialize
+ (Logical change 1.220)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@696 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 638 fix segfault if clmHandle is null to saClmInitialize
+ (Logical change 1.219)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@695 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ clm.c: defect 638 fix segfault if clmHandle is null to saClmInitialize
+ BKrev: 42b31b12gslEYBvbGYQJgGi6uFw8hg
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@694 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ clm.c: defect 637 Fix saClmFinalize will block with threads
+ BKrev: 42b31ad2mqut41t3GjnF-5BmQYDkOA
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@693 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 637 Fix saClmFinalize will block with threads
+ (Logical change 1.218)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@692 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 636 fix saClmDispatch blocks on invalid dispatch flags
+ (Logical change 1.217)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@691 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ clm.c: defect 636 fix saClmDispatch blocks on invalid dispatch flags
+ BKrev: 42b31aa7DNo7fwD1STjEtZQflKEaCw
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@690 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ clm.c: defect 635 saClmSelectionObjectGet crashes if selection object pointer is null
+ BKrev: 42b31a7e1tftUaCVpz36dDVxSI0wBA
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@689 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 635 saClmSelectionObjectGet crashes if selection object pointer is null
+ (Logical change 1.216)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@688 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 634 saCkptDispatch blocks if invalid dispatch flag is set
+ (Logical change 1.215)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@687 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ ckpt.c: defect 634 saCkptDispatch blocks if invalid dispatch flag is set
+ BKrev: 42b31a459dDwB00enI3nSeayQwFODA
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@686 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 633 saCkptInitialize crashes if callbacks parameter is null
+ (Logical change 1.214)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@685 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ ckpt.c: defect 633 saCkptInitialize crashes if callbacks parameter is null
+ BKrev: 42b31a19Ti58H5PxsI2NaDivhyz-fQ
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@684 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ ckpt.c: Fix segfault when address of checkpoint handle is null to the initialize function
+ BKrev: 42b319e8cJKg9zY0XT9um2oqVst5Ug
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@683 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix segfault when address of checkpoint handle is null to the initialize function
+ (Logical change 1.213)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@682 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ ckpt.c: defect 631 Fix segfault if null pointer passed to selection object address of saCkptSelectionObjectGet
+ BKrev: 42b319acUTulJHw99ALuUlMGTcgL1g
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@681 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 631 Fix segfault if null pointer passed to selection object address of saCkptSelectionObjectGet
+ (Logical change 1.212)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@680 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ ckpt.c: defect 630 if a checkpoint is unlinked then opened it should return SA_AIS_ERR_NOT_EXIST
+ BKrev: 42b31972GC0d7zd0Xw4yt4RcQrxcCg
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@679 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 630 if a checkpoint is unlinked then opened it should return SA_AIS_ERR_NOT_EXIST
+ (Logical change 1.211)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@678 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ ckpt.c: defect 629 Return error if checkpoint has been unlinked on retentation duration set
+ BKrev: 42b3192dcHnUOXNAKirryjp4WHDl9g
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@677 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 629 Return error if checkpoint has been unlinked on retentation duration set
+ (Logical change 1.210)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@676 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 628 saCkptCheckpointStatusGet test case 13 from saftest fails
+ (Logical change 1.209)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@675 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ ckpt.c, ckpt.h: defect 628 saCkptCheckpointStatusGet test case 13 from saftest fails
+ BKrev: 42b318f7gBulPAY6sscL0tMMMi9jMw
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@674 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Makefile, ckpt.c: defect 627 Fix API crash when second parameter of saCkptCheckpointStatusGet is null
+ BKrev: 42b318bd2NjZ6GGEcjf0mUQr9yL1EA
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@673 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 627 Fix API crash when second parameter of saCkptCheckpointStatusGet is null
+ (Logical change 1.208)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@672 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 611 add some manual pages to openais
+ (Logical change 1.207)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@671 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 577 Implement token holding mode
+ (Logical change 1.207)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@670 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Makefile, index.html: defect 611 add some manual pages to openais openais_overview.8, openais.conf.5: new file Many files: defect 577 Implement token holding mode
+ BKrev: 42b31834M2cICKgskYf4EnywBr9Fiw
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@669 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ (Logical change 1.207)
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@668 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Initial revision
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@667 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-06-15 Mark Haverkamp <markh@osdl.org>
+
+ Merge markh@bk.osdl.org:/var/bk/openais into markh1.pdx.osdl.net:/home/localmarkh/views/BK/openais_work
+ 2005/06/15 14:09:09-07:00 osdl.net!markh
+ Fix version handling code to be B spec compliant.
+ BUG 623.
+
+ BKrev: 42b09916lexB-dFgQMudnN6k_mmmkw
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@666 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix version handling code to be B spec compliant. BUG 623.
+ (Logical change 1.206)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@665 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Auto merged
+ 2005/06/15 14:09:08-07:00 osdl.net!markh
+ Fix version handling code to be B spec compliant.
+ BUG 623.
+
+ (Logical change 1.206)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@664 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Move the closing of file descriptors from the destructor to the finalize function. This allows threads waiting on poll to wake up and release handle references.
+ BKrev: 42b097dceYknwQw6iUHoWmtoiZRCAQ
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@663 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Move the closing of file descriptors from the destructor to the finalize function. This allows threads waiting on poll to wake up and release handle references.
+ (Logical change 1.205)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@662 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-06-13 Mark Haverkamp <markh@osdl.org>
+
+ Fixes to patterns and filters for B API spec support.
+ (Logical change 1.204)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@661 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fixes to patterns and filters for B API spec support.
+ BKrev: 42ade79b0MPjVuydg8XjvOCQs9MTkw
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@660 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-06-07 Steven Dake <sdake@mvista.com>
+
+ totempg.c: defect 604 report fragmentation messages missing.
+ BKrev: 42a61064-RatmX2Oh0W-yAQkVrhuLA
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@659 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 604 report fragmentation messages missing.
+ (Logical change 1.203)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@658 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-06-06 Steven Dake <sdake@mvista.com>
+
+ defect 600 Qian Zhang reported defect 599 which was a missing pthread_mutex_unlock. Patch attached to fix it.
+ (Logical change 1.202)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@657 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ (Logical change 1.202)
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@656 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ clm.c: defect 600 Qian Zhang reported defect 599 which was a missing pthread_mutex_unlock. Patch attached to fix it.
+ BKrev: 42a4b379jtJP5rnRmyVL92o1PyIDDw
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@655 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ clm.c: defect 599 Qian Zhang reported defect 599 which was a missing pthread_mutex_unlock. Patch attached to fix it.
+ BKrev: 42a4b337flt6FdzG6hqwbxOqSyl59w
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@654 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 599 Qian Zhang reported defect 599 which was a missing pthread_mutex_unlock. Patch attached to fix it.
+ (Logical change 1.201)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@653 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ ipc_ckpt.h, testckpt.c, ckptbench.c, util.c, ckpt.c: defect 595 There are various bugs with saCkptCheckpointOpenAsync that result in it crashing the executive, library, or just failing the saftest conformance suite.
+ BKrev: 42a4afd8Fg5CFXDzyZ_v5qo_ad-Guw
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@652 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 595 There are various bugs with saCkptCheckpointOpenAsync that result in it crashing the executive, library, or just failing the saftest conformance suite..
+ (Logical change 1.200)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@651 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 595 There are various bugs with saCkptCheckpointOpenAsync that result in it crashing the executive, library, or just failing the saftest conformance suite.
+ (Logical change 1.200)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@650 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ ckpt.c: The selection object get in sync with openAsync doesn't work.
+ BKrev: 42a4ae24bww-nX_J3YlTL9lMO3KZvQ
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@649 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ The selection object get in sync with openAsync doesn't work.
+ (Logical change 1.199)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@648 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ ckpt.c, ipc_ckpt.h: defect 592 If ActiveReplicaSet is called, the correct return values are not returned, causing failures in the saf test suite.
+ BKrev: 42a4ade8M7A9p_GJDKQGsWWbJxc41w
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@647 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 592 If ActiveReplicaSet is called, the correct return values are not returned, causing failures in the saf test suite.
+ (Logical change 1.198)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@646 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 591 If checkpoint open is called, but checkpoint close isn't called before saCkptFinalize is called, the reference count of the checkpoints gets out of kilter.
+ (Logical change 1.197)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@645 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ ckpt.c: defect 591 If checkpoint open is called, but checkpoint close isn't called before saCkptFinalize is called, the reference count of the checkpoints gets out of kilter.
+ BKrev: 42a4ada5nUMOYQy74W2MQ1eTlNNC0g
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@644 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-05-27 Steven Dake <sdake@mvista.com>
+
+ (Logical change 1.196)
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@643 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ adds evs_membership_get api
+ (Logical change 1.196)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@642 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Many files: adds evs_membership_get api evs_membership_get.3: new file
+ BKrev: 42964fab28riN6pUGbG3uqbjbAjKcA
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@641 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Initial revision
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@640 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-05-27 Mark Haverkamp <markh@osdl.org>
+
+ Allow services to use the openais.conf file for setting custom options. Evt now allows the maximum delivery queue size and the resume size to be set in openais.conf
+ (Logical change 1.195)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@639 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Allow services to use the openais.conf file for setting custom options. Evt now allows the maximum delivery queue size and the resume size to be set in openais.conf
+ BKrev: 42964b6eDjhuwHSUD_2OVfOPwqZf3w
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@638 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Allow services to use the openais.conf file for setting custom options.
+ (Logical change 1.195)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@637 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-05-25 Miyotaka Sakai <sakai@unknown.org>
+
+ Failover doesn't happen when CTL-Z and process kill
+ (Logical change 1.194)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@636 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-05-25 Mark Haverkamp <markh@osdl.org>
+
+ Merge markh@bk.osdl.org:/var/bk/openais into markh1.pdx.osdl.net:/home/localmarkh/views/BK/openais_work
+ 2005/05/18 01:03:02+09:00 sakai!sakai
+ amf.c:
+ Failover doesn't happen when CTL-Z and process kill
+
+ BKrev: 4294e4525GqfTV54xRLGWs-383Stsg
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@635 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ More updates to make event conform to B spec.
+ BKrev: 4294e431odUeu4s7HWbqMRrsByv4rQ
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@634 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ More updates to make event conform to B spec.
+ (Logical change 1.193)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@633 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix memory leak.
+ BKrev: 4294e345EM8L82mcgFGtNXNOOrANVg
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@632 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix memory leak.
+ (Logical change 1.192)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@631 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-05-04 Mark Haverkamp <markh@osdl.org>
+
+ Added a description of the timeout section of openais.conf
+ (Logical change 1.191)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@630 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add support for user specified timeouts from openais.conf
+ BKrev: 427901a7TTHofqEBWm_tyZgxLVSn8g
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@629 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add support for user specified timeouts from openais.conf
+ (Logical change 1.191)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@628 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-04-29 Steven Dake <sdake@mvista.com>
+
+ defect 529 dont ignore commit token which was causing strange semantics.
+ (Logical change 1.190)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@627 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ totemsrp.c: defect 529 dont ignore commit token which was causing strange semantics.
+ BKrev: 4272a2cfQng6C3XBRPdeo8GZx7KIlQ
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@626 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-04-22 Steven Dake <sdake@mvista.com>
+
+ Many files: defect 512 - some ais header file defines are wrong.
+ BKrev: 4269467fUqljxZ1cZm7rYtXJgozkZQ
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@625 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 512 - some ais header file defines are wrong.
+ (Logical change 1.189)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@624 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ totemsrp.c: defect 498 - reduce network traffic from merge detection
+ BKrev: 42694604csBxR35HgvFh1cX-WdsjPw
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@623 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 498 - reduce network traffic from merge detection
+ (Logical change 1.188)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@622 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-04-21 Steven Dake <sdake@mvista.com>
+
+ testckpt.c, ckpt.c, ipc_ckpt.h: defect 323 - defect 410 - CheckpointOpenAsync and Dispatch not working
+ BKrev: 4267f1b1iKpaZFwASGi0Hpg6NPVlvA
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@621 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 323 - defect 410 - CheckpointOpenAsync and Dispatch not working
+ (Logical change 1.187)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@620 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 505 - fix uncompilable with gcc 2.95
+ (Logical change 1.186)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@619 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ ckpt-wr.c, evt.c, ckpt.c, amf.c: defect 505 - fix uncompilable with gcc 2.95
+ BKrev: 4266fa7e2AAxpdYH2FJH4NEZ75Hc9w
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@618 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-04-21 Mark Haverkamp <markh@osdl.org>
+
+ Defect 501.
+ Fix some mutex and error return problems.
+
+ (Logical change 1.185)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@617 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Defect 501.
+ Fix some mutex and error return problems.
+
+ BKrev: 4266d40eIENsfJQEvDM6MjMDhFcqLA
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@616 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-04-20 Mark Haverkamp <markh@osdl.org>
+
+ For defect 501. Fix possible stale pointers in async lists if an application disconnects before its command has been fully processed.
+ (Logical change 1.184)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@615 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Merge markh@bk.osdl.org:/var/bk/openais into markh1.pdx.osdl.net:/home/localmarkh/views/BK/openais_work
+ 2005/04/20 14:43:05-07:00 osdl.net!markh
+ For defect 501.
+ Fix possible stale pointers in async lists if an application
+ disconnects before its command has been fully processed.
+
+ BKrev: 4266cda65e-fXv0kW4Qe-4Fr4Sbrww
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@614 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-04-18 Steven Dake <sdake@mvista.com>
+
+ evs.c: defect 42 - evs service doesn't send config change on evs_initialize
+ BKrev: 4264263fzzgV2yL8rAEqgs69wjGnZA
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@613 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 42 - evs service doesn't send config change on evs_initialize
+ (Logical change 1.183)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@612 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ totemsrp.c: Fix assert when recovery fails and messages are accepted in the gather state.
+ BKrev: 42641035MxBKYwCZ1zOkFr_h-WES3Q
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@611 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix assert when recovery fails and messages are accepted in the gather state.
+ (Logical change 1.182)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@610 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-04-16 Steven Dake <sdake@mvista.com>
+
+ totemsrp.c: Fixes a condition which would result in a proc set and failed set being equal which would force the algorithm to never reach consensus in the membership algorithm.
+ BKrev: 42604e9fCBYactncuQuguPZ_IEfQsQ
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@609 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fixes a condition which would result in a proc set and failed set being equal which would force the algorithm to never reach consensus in the membership algorithm.
+ (Logical change 1.181)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@608 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ totem packet size changed from 1408 to 1404 because a field was added to the mcast header.
+ (Logical change 1.180)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@607 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ add some sort queue functions.
+ (Logical change 1.180)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@606 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ turn off random dropping of packets by default.
+ 2005/04/15 16:27:14-07:00 mvista.com!sdake
+ Major fixes to the recovery phase of the totem protocol. The
+ remainder of the protocol remains unchanged.
+ The protocol now properly adds the right messages to the right
+ queues during recovery. The protocol properly handles failures
+ in the recovery state.
+
+ (Logical change 1.180)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@605 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ totemsrp.c: turn off random dropping of packets by default. totemsrp.h: totem packet size changed from 1408 to 1404 because a field was added to the mcast header. sq.h: add some sort queue functions. totemsrp.c: Major fixes to the recovery phase of the totem protocol. The remainder of the protocol remains unchanged. The protocol now properly adds the right messages to the right queues during recovery. The protocol properly handles failures in the recovery state. totempg.c: add an assert to catch a weird case.
+ BKrev: 42604e5bSfwCdUnySrgU1nlV7yDYNQ
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@604 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ add an assert to catch a weird case.
+ (Logical change 1.180)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@603 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-04-15 Steven Dake <sdake@mvista.com>
+
+ crypto.c: autodetect endian and wordsize with gnuisms
+ BKrev: 42602efdZ8LfQwIHBFrdtsjrK3BtCg
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@602 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ autodetect endian and wordsize with gnuisms
+ (Logical change 1.179)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@601 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ evs.c: fix defect 477 - header size calculated incorrectly results in assert
+ BKrev: 42602cf5j6Zi2RZtyz9xB83lZW9R6g
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@600 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ fix defect 477 - header size calculated incorrectly results in assert
+ (Logical change 1.178)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@599 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Merge sdake@bk.osdl.org:/var/bk/openais into persist.az.mvista.com:/home/sdake/openais
+ 2005/04/15 13:48:35-07:00 mvista.com!sdake
+ Makefile, util.h, util.c, evt.c, evs.c, clm.c, ckpt.c, amf.c:
+ defect 188 missed initial checkin
+
+ BKrev: 426028b9DQDC6BgUEBBsQmVJmhyxOg
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@598 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 188 missed initial checkin
+ (Logical change 1.177)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@597 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-04-15 Mark Haverkamp <markh@osdl.org>
+
+ Test updates to handle SA_AIS_ERR_TRY_AGAIN return codes.
+ (Logical change 1.176)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@596 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Merge markh@bk.osdl.org:/var/bk/openais into markh1.pdx.osdl.net:/home/localmarkh/views/BK/openais_work
+ 2005/04/15 13:01:00-07:00 osdl.net!markh
+ Test updates to handle SA_AIS_ERR_TRY_AGAIN return codes.
+
+ BKrev: 42601e9aBWGIREypBcTjO5NC8bK8uA
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@595 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-04-15 Steven Dake <sdake@mvista.com>
+
+ defect 188 - use two fds instead of one fd for I/Os to executive
+ (Logical change 1.175)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@594 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Many files: defect 188 - use two fds instead of one fd for I/Os to executive testevsth.c: test evs threading
+ BKrev: 42601124xiPxCobiccGpS7CZ62Ol7w
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@593 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ (Logical change 1.175)
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@592 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Initial revision
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@591 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 478 - remove extra parameter to config change.
+ (Logical change 1.174)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@590 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Many files: defect 478 - remove extra parameter to config change.
+ BKrev: 42600ff6Tg7hfUjwYnckeK8uBxBGrg
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@589 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-04-11 Steven Dake <sdake@mvista.com>
+
+ Fix defect 456 when checkpoint expirse, the executive crashes if no bind address was specified
+ (Logical change 1.173)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@588 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ main.c: Fix defect 456 when checkpoint expirse, the executive crashes if no bind address was specified
+ BKrev: 425aed2d6P3dBt_7UO1Cv6d5kt4haQ
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@587 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ add default section to testcase
+ (Logical change 1.172)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@586 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ add default section to testcase.
+ (Logical change 1.172)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@585 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add default section support to checkpoints.
+ (Logical change 1.172)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@584 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ (Logical change 1.172)
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@583 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ testckpt.c, ckpt-rd.c, ckpt-wr: add default section to testcase. ckpt.c: Add default section support to checkpoints.
+ BKrev: 425aeb47Mb_N8HKGtX_BdmRGaLP-Jg
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@582 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-04-08 Steven Dake <sdake@mvista.com>
+
+ ckpt.c: Patch from Muni and Mark to properly calculate the header size field so that the totem delivery assertion doesn't assert when using ckpt services.
+ BKrev: 4256f3d0FFsh6CwpsXs-w4_225C4Wg
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@581 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Patch from Muni and Mark to properly calculate the header size field so that the totem delivery assertion doesn't assert when using ckpt services.
+ (Logical change 1.171)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@580 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-04-06 Mark Haverkamp <markh@osdl.org>
+
+ Make sure that the message count in the message matches the actual length of the message.
+ BKrev: 42543a7aj_fChUtiZ_ZWH0wdZ6JN3Q
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@579 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Make sure that the message count in the message matches the actual length of the message.
+ (Logical change 1.170)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@578 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-04-05 Mark Haverkamp <markh@osdl.org>
+
+ Merge markh@bk.osdl.org:/var/bk/openais into markh1.pdx.osdl.net:/home/localmarkh/views/BK/openais_work
+ 2005/04/05 08:56:39-07:00 osdl.net!markh
+ Replace assert with a return. This will allow the custer to continue
+ to run. This happens when a joining node receives a message from a node
+ that it doesn't know about yet. This is a temporary fix for now.
+
+ BKrev: 4252b541e1CWSNFoD816nTIzzKKPDg
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@577 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Replace assert with a return. This will allow the custer to continue to run. This happens when a joining node receives a message from a node that it doesn't know about yet. This is a temporary fix for now.
+ (Logical change 1.169)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@576 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-04-05 Steven Dake <sdake@mvista.com>
+
+ Patch from Miyotaka Sakai to fix access to free area defect 426.
+ (Logical change 1.168)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@575 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ totemsrp.c: Patch from Miyotaka Sakai to fix access to free area defect 426.
+ BKrev: 4251ef0dubnPmmnqD-elKTQ_vgpq9Q
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@574 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-04-01 Steven Dake <sdake@mvista.com>
+
+ change around this_ip to better support ifup/ifdown
+ (Logical change 1.167)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@573 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ add some support functions relating to this_ip
+ (Logical change 1.167)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@572 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ add ifup/ifdown binding to totem single ring protocol
+ (Logical change 1.167)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@571 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ minor improvements to the ckpt tests
+ (Logical change 1.167)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@570 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ testckpt.c: minor improvements to the ckpt tests totemsrp.h, totemsrp.c: add ifup/ifdown binding to totem single ring protocol main.h, main.c: add some support functions relating to this_ip clm.c, ckpt.c, amf.c: change around this_ip to better support ifup/ifdown
+ BKrev: 424dbb0bUeDXpnbGn8TxJlPYWRvT6A
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@569 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-03-31 Miyotaka Sakai <sakai@unknown.org>
+
+ fix not to transit state when process terminate
+ (Logical change 1.166)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@568 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ amf.c: fix not to transit state when process terminate
+ BKrev: 424b286648uPUwF_B-hMgKOF5Mgwzw
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@567 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-03-30 Steven Dake <sdake@mvista.com>
+
+ Updated with comments from Michael Howard added evt and evs service tests to quickstart information added text about running as root removed default route setup instructions since they are no longer needed.
+ (Logical change 1.165)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@566 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ QUICKSTART: Updated with comments from Michael Howard added evt and evs service tests to quickstart information added text about running as root removed default route setup instructions since they are no longer needed.
+ BKrev: 424b198bYLqB2blTRdYtgLgjFmHjIA
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@565 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Merge sdake@bk.osdl.org:/var/bk/openais into persist.az.mvista.com:/home/sdake/openais
+ 2005/03/29 15:03:30-07:00 mvista.com!sdake
+ testckpt.c:
+ Create section after section is unlinked in test code.
+ ckpt.c:
+ Patch from Muni Bajpai to not setup a cleanup handler for a
+ checkpoint when a checkpoint open fails. Patch also fixes up
+ checkpoint iterators so they do not crash on process exit.
+
+ BKrev: 4249da03fKPlzZG0QP8eZriaAtoM-w
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@564 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Patch from Muni Bajpai to not setup a cleanup handler for a checkpoint when a checkpoint open fails. Patch also fixes up checkpoint iterators so they do not crash on process exit.
+ (Logical change 1.164)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@563 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Create section after section is unlinked in test code.
+ (Logical change 1.164)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@562 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-03-29 Miyotaka Sakai <sakai@unknown.org>
+
+ fix configuration change
+ (Logical change 1.163)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@561 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ amf.c: fix configuration change
+ BKrev: 424889eehbHC-A5YNtbXzaEzVMhcVQ
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@560 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-03-28 Steven Dake <sdake@mvista.com>
+
+ Remove extra debug printf.
+ (Logical change 1.162)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@559 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ totemsrp.c: Remove extra debug printf.
+ BKrev: 42485391qM7HG2et7RcmNIHInqXxTA
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@558 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 368 A report of totemsrp not merging configurations led to this enhancement.
+ totemsrp.c:
+ The totem protocol would not previously merge a configuration
+ until a multicast message was sent. This change sends a special
+ "merge detect" message if no message has been multicast in some
+ time from the representative. This merge detect message will
+ trigger other processors to enter the gather state and form
+ a new configuration if they were not previously part of the
+ current configuration.
+ Makefile:
+ Build aisexec when libtotem.a changes.
+
+ BKrev: 42484f5453Wf6HN2Gbyg9dznFaQGtw
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@557 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ The totem protocol would not previously merge a configuration until a multicast message was sent. This change sends a special "merge detect" message if no message has been multicast in some time from the representative. This merge detect message will trigger other processors to enter the gather state and form a new configuration if they were not previously part of the current configuration.
+ (Logical change 1.161)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@556 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Build aisexec when libtotem.a changes.
+ (Logical change 1.161)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@555 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-03-28 Mark Haverkamp <markh@osdl.org>
+
+ This update allows retained events from a merging partition to be delivered to applications with the associated channels already open at the time of the merge.
+ BKrev: 42484b6f0IXKK1Bql-GCaHwTbXg0dQ
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@554 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ This update allows retained events from a merging partition to be delivered to applications with the associated channels already open at the time of the merge.
+ (Logical change 1.160)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@553 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Async open and subscribe needed to check for registered call back functions and retrun an error if there were no assocated callbacks.
+ BKrev: 42483e43sOS_W8zCqoAZNHTy43FhkA
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@552 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Async open and subscribe needed to check for registered call back functions and retrun an error if there were no assocated callbacks.
+ (Logical change 1.159)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@551 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-03-23 Mark Haverkamp <markh@osdl.org>
+
+ Only dispatch a callback if it is non-null.
+ (Logical change 1.158)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@550 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Only dispatch a callback if it is non-null.
+ BKrev: 4241cdbcbgCCwsZLJEXicZZTvGpuGQ
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@549 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-03-23 Steven Dake <sdake@mvista.com>
+
+ defect325 - rename saCkptActiveCheckpointSet to saCkptActiveReplicaSet
+ (Logical change 1.157)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@548 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ ckpt.c: defect325 - rename saCkptActiveCheckpointSet to saCkptActiveReplicaSet
+ BKrev: 4240ac49svEd0Uoaf0zn8-6YXK5akw
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@547 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Makefile: Link to seperate libraries. Provide seperate libraries per service as well as the consolidated libais library.
+ BKrev: 4240ac15wtabDEmO2ooaShdbFZP-wg
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@546 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Link to seperate libraries.
+ (Logical change 1.156)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@545 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Provide seperate libraries per service as well as the consolidated libais library.
+ (Logical change 1.156)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@544 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-03-23 Mark Haverkamp <markh@osdl.org>
+
+ Fix an off by one error causing a bad event ID to be sent after a recovery in some cases.
+ BKrev: 4240a8ba6cGIAgqLoTZNAUZJJOgyrg
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@543 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix an off by one error causing a bad event ID to be sent after a recovery in some cases.
+ (Logical change 1.155)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@542 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-03-17 Mark Haverkamp <markh@osdl.org>
+
+ Event service now reconciles open channels and retained events between active merging partitions.
+ (Logical change 1.154)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@541 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Merge markh@bk.osdl.org:/var/bk/openais into markh1.pdx.osdl.net:/home/localmarkh/views/BK/openais_work
+ 2005/03/17 14:44:09-08:00 osdl.net!markh
+ Event service now reconciles open channels and retained events between active
+ merging partitions.
+
+ BKrev: 423a084c-3ULQ_tcgSf5isGBiqzUWA
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@540 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-03-17 Steven Dake <sdake@mvista.com>
+
+ Merge sdake@bk.osdl.org:/var/bk/openais into persist.az.mvista.com:/home/sdake/openais
+ 2005/03/17 14:25:22-07:00 mvista.com!sdake
+ ckpt.c:
+ Change few ERROR loggings to DEBUG loggings from Muni Bajpai.
+
+ BKrev: 4239f5cbSrwx6_k9jxG2_GjW1OoVHQ
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@539 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Change few ERROR loggings to DEBUG loggings from Muni Bajpai.
+ (Logical change 1.153)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@538 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-03-17 Mark Haverkamp <markh@osdl.org>
+
+ Handle possible SA_AIS_ERR_TRY_AGAIN status.
+ BKrev: 4239c886n6J6MzMfIVjaN1QvFnsfzg
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@537 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Handle possible SA_AIS_ERR_TRY_AGAIN status.
+ (Logical change 1.152)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@536 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-03-17 Steven Dake <sdake@mvista.com>
+
+ Block multicast messages during synchronization.
+ (Logical change 1.151)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@535 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ ckptbench.c: retry writes when it appears the system is blocked, perhaps during a resynchronization. Many files: Block multicast messages during synchronization.
+ BKrev: 4238c435y6ZGwBr-M4xFHDUJ7HhLaQ
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@534 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ retry writes when it appears the system is blocked, perhaps during a resynchronization.
+ (Logical change 1.151)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@533 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-03-16 Steven Dake <sdake@mvista.com>
+
+ cleanup some shared datatypes.
+ (Logical change 1.150)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@532 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ cleanup some shared datatypes
+ (Logical change 1.150)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@531 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ (Logical change 1.150)
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@530 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Mark Haverkamp reported some compile warnings with his compiler. Cleanup those warnings by unifying the datatypes used in totempg and totemsrp into one set of datatypes.
+ Many files:
+ cleanup some shared datatypes for the totem protocol.
+ totem.h:
+ new file
+
+ BKrev: 423879baJvLZpm8nNaRfQHRfWB2fOA
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@529 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Initial revision
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@528 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Improved synchronization test code from Muni Bajpai.
+ (Logical change 1.149)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@527 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ ckpt-wr.c, ckpt-rd.c: Improved synchronization test code from Muni Bajpai.
+ BKrev: 4238784c5RBxBXc3aHA68KOVGhAEWw
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@526 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-03-15 Steven Dake <sdake@mvista.com>
+
+ Fix bug in sync which caused segfault.
+ (Logical change 1.148)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@525 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ totemsrp.h, totemsrp.c: Allow totemsrp to remove the reference information for a token callback. sync.c: Fix bug in sync which caused segfault.
+ BKrev: 42371b753plEvd2J96qRpg6mRxki1Q
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@524 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Allow totemsrp to remove the reference information for a token callback.
+ (Logical change 1.148)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@523 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add checkpoint reader and writer to test synchronization
+ (Logical change 1.147)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@522 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Makefile: Add checkpoint reader and writer to test synchronization ckpt-wr.c, ckpt-rd.c: new file
+ BKrev: 42363081enPpMuQpdvw2e1uqFAqD0A
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@521 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ (Logical change 1.147)
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@520 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Initial revision
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@519 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-03-14 Steven Dake <sdake@mvista.com>
+
+ Merge sdake@bk.osdl.org:/var/bk/openais into persist.az.mvista.com:/home/sdake/openais
+ 2005/03/14 15:39:42-07:00 mvista.com!sdake
+ ipc_gen.h, ipc_ckpt.h, ckpt.c:
+ Checkpoint synchronization patch from Muni Bajpai.
+
+ BKrev: 423612bc5lRZOqj0qi_o6zXGw1bAwg
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@518 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Checkpoint synchronization patch from Muni Bajpai.
+ (Logical change 1.146)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@517 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-03-11 Mark Haverkamp <markh@osdl.org>
+
+ Update the publish API to return SA_AIS_ERR_TRY_AGAIN to the application instead of handling it in the library.
+ (Logical change 1.145)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@516 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Update the publish API to return SA_AIS_ERR_TRY_AGAIN to the application instead of handling it in the library.
+ BKrev: 4231eb69MvlifP_ykH0Nfj693tUWMA
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@515 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-03-09 Mark Haverkamp <markh@osdl.org>
+
+ New event service recovery code implementation for totem and the new sync services.
+ (Logical change 1.144)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@514 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ New event service recovery code implementation for totem and the new sync services.
+ BKrev: 422f73c7NkihQaud_tc4WYQOjavwhg
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@513 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-03-09 Steven Dake <sdake@mvista.com>
+
+ Cluster membership synchronization support
+ (Logical change 1.143)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@512 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ clm.c: Cluster membership synchronization support
+ BKrev: 422f5283JgT5AkInLBoHrZMu0wx2rQ
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@511 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-03-02 Steven Dake <sdake@mvista.com>
+
+ Added synchronization base code. Four new APIs are required for a service to support synchronization. sync_init, sync_process, sync_activate, and sync_abort provide the calls into the recovery mechanism.
+ sync.h, sync.c:
+ new file
+ totemsrp.h, totemsrp.c, print.h, print.c, Makefile, main.c, handlers.h:
+ Synchronization base code added.
+ ipc_gen.h:
+ Synchronization base code.
+
+ BKrev: 422639e5L_FEDTWgRgI-w8vKm8zhMQ
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@510 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Synchronization base code.
+ (Logical change 1.142)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@509 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Synchronization base code added.
+ (Logical change 1.142)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@508 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ (Logical change 1.142)
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@507 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Initial revision
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@506 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-02-27 Steven Dake <sdake@broked.org>
+
+ em64t support
+ (Logical change 1.141)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@505 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Many files: em64t support
+ BKrev: 42216853DGp9Hwgh8mvnixFj_QMRUQ
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@504 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-02-18 Steven Dake <sdake@mvista.com>
+
+ Many files: Pass handle by value instead of address.
+ BKrev: 4216488aoAf2Eu5qvs7qGxx8rO9zXw
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@503 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Pass handle by value instead of address.
+ (Logical change 1.140)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@502 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-02-17 Steven Dake <sdake@mvista.com>
+
+ Auto merged
+ 2005/02/16 17:24:12-07:00 mvista.com!sdake
+ send ring_id through configuration changes patch from Muni Bajpai.
+
+ (Logical change 1.139)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@501 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Merge sdake@bk.osdl.org:/var/bk/openais into persist.az.mvista.com:/home/sdake/openais
+ 2005/02/16 17:24:48-07:00 mvista.com!sdake
+ Many files:
+ send ring_id through configuration changes patch from Muni Bajpai.
+ clm.c:
+ mutex bug fixes as reported by Kristen Smith.
+
+ BKrev: 4213e45dnMl87bYQKSfi4_98X352Lg
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@500 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ send ring_id through configuration changes patch from Muni Bajpai.
+ (Logical change 1.139)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@499 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ mutex bug fixes as reported by Kristen Smith.
+ (Logical change 1.139)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@498 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-02-16 Mark Haverkamp <markh@osdl.org>
+
+ Look for SA_EVT_EVENTID_LOST when receiving an event.
+ (Logical change 1.138)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@497 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Set default event ID.
+ (Logical change 1.138)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@496 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Set lost event ID on dropped events.
+ (Logical change 1.138)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@495 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Use special event ID for setting the default in a new event and to indicate a lost event. Update subscription test to look for the "lost" event ID.
+ BKrev: 42128170Q5DcNymwbx8NushEykXwmg
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@494 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-02-15 Mark Haverkamp <markh@osdl.org>
+
+ Add unlink function.
+ (Logical change 1.137)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@493 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Merge markh@bk.osdl.org:/var/bk/openais into markh1.pdx.osdl.net:/home/localmarkh/views/BK/openais_work
+ 2005/02/15 08:54:34-08:00 osdl.net!markh
+ Add unlink function.
+
+ BKrev: 42122956O-InvJqb6K70vMTy4gl8yQ
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@492 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-02-09 Steven Dake <sdake@mvista.com>
+
+ Increase code coverage by calling more API functions.
+ (Logical change 1.136)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@491 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ testevs.c, testckpt.c: Increase code coverage by calling more API functions. testamf.c: Fix bug in test script which was causing test not to run. Increase code coverage by allowing few more apis to be called. totemsrp.c: Increase code coverage by removing some debug code
+ BKrev: 42095a88Q0lU2eqEirC1FAZ05pxlmg
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@490 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix bug in test script which was causing test not to run. Increase code coverage by allowing few more apis to be called.
+ (Logical change 1.136)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@489 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Increase code coverage by removing some debug code
+ (Logical change 1.136)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@488 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-02-08 Steven Dake <sdake@mvista.com>
+
+ (Logical change 1.135)
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@487 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Many files: defect 245 - revise checkpoint service to B.01.01. saCkpt.h, ipc_ckpt.h, sa_error.h: new file .del-ais_clm.h~ed02cd4c7506e43: Delete: include/ais_clm.h .del-ais_ckpt.h~b3c15abf536a6fbc: Delete: include/ais_ckpt.h
+ BKrev: 42092786pSJQ8uC11PWAhWTC1Hwjqw
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@486 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ defect 245 - revise checkpoint service to B.01.01.
+ (Logical change 1.135)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@485 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Delete: include/ais_ckpt.h
+ }(Logical change 1.135)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@484 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Delete: include/ais_clm.h
+ }(Logical change 1.135)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@483 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Initial revision
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@482 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ totemsrp.c: Add more text output to display what occurs during recovery. Fix recovery bug which results in segfault. fix defect 228 - ring id file deleted causes assert. Fix recovery bug where recovery doesn't complete. Fix assert on commit phase.
+ BKrev: 42092662LEVSqJlhbISw-Hweb4Cbfg
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@481 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add more text output to display what occurs during recovery. Fix recovery bug which results in segfault. fix defect 228 - ring id file deleted causes assert. Fix recovery bug where recovery doesn't complete. Fix assert on commit phase.
+ (Logical change 1.134)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@480 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-02-08 Mark Haverkamp <markh@osdl.org>
+
+ Add test for channel open async
+ (Logical change 1.133)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@479 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add handler for channel open async
+ (Logical change 1.133)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@478 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add handler for channel open async and add a test to testevt for the async channel open function. Bug fix for event retention time clear exec code and added comments when converting nanoseconds to milliseconds.
+ BKrev: 4208f4048DxJP7FLwfqHo7TfAoEJlA
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@477 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-02-04 Mark Haverkamp <markh@osdl.org>
+
+ This fixes a potential problem where, because of a config change, a joining node may not have a previous fragment of a message. It now discards continuations of that message until it is complete and a new message arrives.
+ (Logical change 1.132)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@476 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ This fixes a potential problem where, because of a config change, a joining node may not have a previous fragment of a message. It now discards continuations of that message until it is complete and a new message arrives.
+ BKrev: 4203ea20pYSrD8ZyY3pxIHSXFSooeg
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@475 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Remove ais_evt.h since its content has been moved.
+ BKrev: 4203e785HE6cQ-KCAgc-CHHOiZ0tEg
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@474 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Delete: include/ais_evt.h
+ }(Logical change 1.131)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@473 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Update to B spec API
+ (Logical change 1.130)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@472 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Update event service to B spec API.
+ BKrev: 4203e6d8nLXD7EMTNFZNfFwMnzt8mA
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@471 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Conver to B spec API.
+ (Logical change 1.130)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@470 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ update dependencies.
+ (Logical change 1.130)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@469 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ (Logical change 1.130)
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@468 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Update evt to B spec remove event related code and move to ipc_evt.h and saEvt.h
+ (Logical change 1.130)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@467 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Use B spec include files
+ (Logical change 1.130)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@466 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Convert to B spec. Add in endian conversion functions.
+ (Logical change 1.130)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@465 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Moved from ais_msg.h so ais_msg.h doesn't need to be included by evt.
+ (Logical change 1.130)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@464 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ update evt to B spec. remove evt related code and move to ipc_evt.h and saEvt.h
+ (Logical change 1.130)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@463 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ update dependencies
+ (Logical change 1.130)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@462 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Initial revision
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@461 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-02-04 Steven Dake <sdake@mvista.com>
+
+ util.c: Fix merge error in util.c file
+ BKrev: 4203d35fqEwtXJ4ZtIAnGz5HWpHsEQ
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@460 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix merge error in util.c file
+ (Logical change 1.129)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@459 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Small fix for data types.
+ (Logical change 1.128)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@458 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ util.c: Small fix for data types.
+ BKrev: 4203d2d97z9HmoblaHq8etKUqRGF0w
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@457 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Update to use 64 bit data types for handles.
+ (Logical change 1.127)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@456 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ testamf1.c, testamf2.c: 64 bit handles. testevs.c, testclm.c, testamfth.c, testamf6.c, testamf4.c, testamf3.c: 64 bit handles evs.h: change data type of handle to 64 bits for evs_handle_t. ais_types.h: remove cluster membership types and put in saClm.h file. ais_msg.h: remove cluster membership code and put in ipc file. util.h, util.c: Update to use 64 bit data types for handles. clm.c: Update cluster membership to B.01.01. print.h: Update print data to new node structure. clm.h, clm.c: Update cluster membership service to B.01.01. saClm.h, ipc_gen.h, ipc_clm.h: new file
+ BKrev: 4203ce72I415G1q4yQQNjFfAxSJVOA
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@455 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ 64 bit handles
+ (Logical change 1.127)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@454 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ remove cluster membership code and put in ipc file.
+ (Logical change 1.127)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@453 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Update cluster membership service to B.01.01.
+ (Logical change 1.127)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@452 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ (Logical change 1.127)
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@451 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ 64 bit handles.
+ (Logical change 1.127)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@450 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Update print data to new node structure.
+ (Logical change 1.127)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@449 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ remove cluster membership types and put in saClm.h file.
+ (Logical change 1.127)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@448 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ change data type of handle to 64 bits for evs_handle_t.
+ (Logical change 1.127)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@447 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Update cluster membership to B.01.01.
+ (Logical change 1.127)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@446 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Initial revision
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@445 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-02-01 Steven Dake <sdake@mvista.com>
+
+ fix defect 131 - member element not set in cluster membership service
+ (Logical change 1.126)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@444 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ More fixes for defect 204. From Mark Haverkamp: |Looking at the totempg config change function, I think that leaving |members should have their assembly area reset. I assume that any data |that is there is now invalid, and we wouldn't want it hanging around if |they return. Also, I think that the wrong index was being used to |initialize the assembly area index.
+ (Logical change 1.126)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@443 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ totempg.c: More fixes for defect 204. From Mark Haverkamp: |Looking at the totempg config change function, I think that leaving |members should have their assembly area reset. I assume that any data |that is there is now invalid, and we wouldn't want it hanging around if |they return. Also, I think that the wrong index was being used to |initialize the assembly area index. clm.c: fix defect 131 - member element not set in cluster membership service
+ BKrev: 41ffe9278sM8ZyWmj_3tmUK0YiqgSQ
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@442 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-01-31 Steven Dake <sdake@mvista.com>
+
+ Fix from mark and daniel for small packet sizes in totempg resulting in segfault.
+ (Logical change 1.125)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@441 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ random drop defined to on.. turning off.
+ (Logical change 1.125)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@440 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ totemsrp.c: random drop defined to on.. turning off. totempg.c: Fix from mark and daniel for small packet sizes in totempg resulting in segfault.
+ BKrev: 41feac34ILMg8MsBZNAXgHefIA22zw
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@439 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ totempg.c: Fixes defect 204 : messages not delivered correctly Patch from Mark Haverkamp.
+ BKrev: 41fe8cbaM4eR7_3dP91qFSahtT23dA
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@438 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fixes defect 204 : messages not delivered correctly Patch from Mark Haverkamp.
+ (Logical change 1.124)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@437 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix bug in implementation that deviates from specification.
+ (Logical change 1.123)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@436 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ totemsrp.c: Fix bug in implementation that deviates from specification.
+ BKrev: 41fe8c84mIHGgf3brH_kZTiOR_ACvQ
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@435 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-01-29 Steven Dake <sdake@mvista.com>
+
+ bug 214 Fix pthread mutex not unlocked in error path
+ (Logical change 1.122)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@434 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ remove priority fields from evs service. ..
+ (Logical change 1.122)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@433 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ remove priority fields from evs service.
+ (Logical change 1.122)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@432 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ evs_mcast_joined.3: remove priority fields from evs service. .. evs_mcast_groups.3, evs.h, ais_msg.h: remove priority fields from evs service. util.c: bug 214 Fix pthread mutex not unlocked in error path
+ BKrev: 41fbd660W-BROulgsZt4S6LYD_pcvw
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@431 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-01-27 Steven Dake <sdake@mvista.com>
+
+ testevs.c, evsbench.c: Remove priorities from interfaces. evs.c: Remove priorities from evs interfaces. totempg.h, totempg.c, main.c, handlers.h, evt.c, evs.c, clm.c, ckpt.c, amf.c: Remove priorities from all interfaces.
+ BKrev: 41f943030jN3Y5g5v10371Hgb2007A
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@430 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Remove priorities from evs interfaces.
+ (Logical change 1.121)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@429 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Remove priorities from interfaces.
+ (Logical change 1.121)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@428 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Remove priorities from all interfaces.
+ (Logical change 1.121)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@427 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-01-24 Steven Dake <sdake@mvista.com>
+
+ Fix defect 203 commit token asserts
+ (Logical change 1.120)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@426 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ totemsrp.c: Fix defect 203 commit token asserts
+ BKrev: 41f55007suViMhWrhOICprHxyacUwg
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@425 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-01-24 Mark Haverkamp <markh@osdl.org>
+
+ Small fixes. evt: fix member count until recovery code is done. totempg: remove dbug print.
+ BKrev: 41f546cd0Fq27HJzalqHeE69x99WKg
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@424 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Temp config change code
+ (Logical change 1.119)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@423 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ remove debug print
+ (Logical change 1.119)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@422 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-01-22 Steven Dake <sdake@broked.org>
+
+ Remove random dropping of packets in released version.
+ (Logical change 1.118)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@421 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ totemsrp.c: Remove random dropping of packets in released version.
+ BKrev: 41f2c58dbLMQ6YcKCJxEwIKRUk7lxw
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@420 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-01-22 Steven Dake <sdake@mvista.com>
+
+ update to new totem code
+ (Logical change 1.117)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@419 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ enable some testing code.
+ (Logical change 1.117)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@418 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add test.cpp to makefile
+ (Logical change 1.117)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@417 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Delete: exec/gmi.c
+ }(Logical change 1.117)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@416 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ new benchmark runs for 10 seconds.
+ (Logical change 1.117)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@415 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ update to new crypto code
+ (Logical change 1.117)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@414 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ update to new crypto code.
+ (Logical change 1.117)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@413 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ (Logical change 1.117)
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@412 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Makefile: Add test.cpp to makefile testckpt.c: enable some testing code. evsbench.c, ckptbench.c: new benchmark runs for 10 seconds. test.cpp, rmd.h, totemsrp.h, totemsrp.c, totempg.h, totempg.c, swab.h: new file sq.h, Makefile, evt.c, evs.c, clm.c, amf.c, crypto.c, ckpt.c, aispoll.c: update to new totem code. queue.h, ais_msg.h: update to new totem code parse.h, parse.c, Makefile, main.h: update to new crypto code main.c, handlers.h: update to new crypto code. .del-gmi.h~7d81bcdb10af22b3: Delete: exec/gmi.h .del-gmi.c~df0f77a7b91ff206: Delete: exec/gmi.c
+ BKrev: 41f2bdd3a_mEhs2wkBZHsD4_aft9vA
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@411 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ update to new totem code.
+ (Logical change 1.117)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@410 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Delete: exec/gmi.h
+ }(Logical change 1.117)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@409 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Initial revision
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@408 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-01-11 Mark Haverkamp <markh@osdl.org>
+
+ add in missing mutex unlock
+ BKrev: 41e405deOyfzWPCaxv7_aIpgxL5C5g
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@407 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ add in missing mutex unlock
+ (Logical change 1.116)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@406 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Need to specify create because the channel probably doesn't exist anymore.
+ BKrev: 41e40050NKYAEN3N5kB1-R-klUXqUQ
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@405 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Need to specify create because the channel probably doesn't exist anymore.
+ (Logical change 1.115)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@404 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-01-10 Miyotaka Sakai <sakai@unknown.org>
+
+ amf.c: For Protection Group Tracking Bug
+ BKrev: 41e29f00Yz2GqTwTyBhpW_zo6WjI1Q
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@403 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ For Protection Group Tracking Bug
+ (Logical change 1.114)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@402 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-01-08 Steven Dake <sdake@mvista.com>
+
+ tlist.h: Fix required for previous tlist.c commit.
+ BKrev: 41e01e1cFsurlTBuApZjiZ3l9RFdBw
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@401 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix required for previous tlist.c commit.
+ (Logical change 1.113)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@400 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Merge sdake@bk.osdl.org:/var/bk/openais into persist.az.mvista.com:/home/sdake/openais
+ 2005/01/08 02:16:10-07:00 mvista.com!sdake
+ tlist.c:
+ Fix use of memory area after free when timer_fn deletes a timer.
+ The 3 cases are:
+ 1. timer_fn deletes its own timer
+ 2. timer_fn deletes next timer after its own timer
+ 3. timer_fn deletes any other timer
+
+ BKrev: 41dfa4faNWgA_s0fcyzlj-jhOFNKAA
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@399 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix use of memory area after free when timer_fn deletes a timer. The 3 cases are: 1. timer_fn deletes its own timer 2. timer_fn deletes next timer after its own timer 3. timer_fn deletes any other timer
+ (Logical change 1.112)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@398 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-01-07 Steven Dake <sdake@broked.org>
+
+ evs.c, clm.c, amf.c: Fix missing unlock in error conditions reported by Kristen Smith
+ BKrev: 41deef37lfq4PXPbgolOpenG8xUJYg
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@397 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix missing unlock in error conditions reported by Kristen Smith
+ (Logical change 1.111)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@396 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2005-01-07 Kristen Smith <kjsmith@nortelnetworks.com>
+
+ Add missing mutex unlocks in evt dispatch function.
+ BKrev: 41dec6bdm_JzS8aFCPMDziJhBZprSw
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@395 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ I was running into a problem where the evt api appeared to be getting into a deadlock situtation. The problem would occur when I would kill aisexec while my program was running (using EVT and CLM apis). My program is multi-threaded where 1 thread is calling evtDispatch and other threads can be calling evtPublish at various times. The problem I ran into is when I killed aisexec, the evtDispatch would take a lock, but never give it back. At the same time, my sending thread would call evtPublish which would take the lock and hang since evtDispatch never gave up the lock it took.
+ The fix was to add a few unlocks in evt.c where they appeared to be missing.
+ Here is the info:
+
+ 1) line 504 in evt.c (lib dir) calls
+
+ pthread_mutex_unlock(&evti->ei_mutex);
+ goto error_unlock;
+
+ 2) There are subsequent calls to goto error_unlock in later error statements
+ that do not unlock the mutex before the goto call - the lines are 534 and 541
+
+ Adding the unlock right before the goto @ 534 and @ 541 fixes the deadlock
+ for my scenario.
+
+ Kristen Smith
+ Nortel Networks
+
+ (Logical change 1.110)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@394 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2004-11-29 Steven Dake <sdake@mvista.com>
+
+ Improve code coverage by testing a few more APIs in the AMF.
+ (Logical change 1.109)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@393 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ testamf.c: Improve code coverage by testing a few more APIs in the AMF.
+ BKrev: 41ab821fPmG01mXBZYuPJWKuOLHj5A
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@392 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2004-11-25 Steven Dake <sdake@mvista.com>
+
+ code coverage work cleanup
+ (Logical change 1.108)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@391 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ fix double ;; which causes gcc 2.95 to fail to compile
+ (Logical change 1.108)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@390 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ testparse.c: code coverage work cleanup evt.c: fix double ;; which causes gcc 2.95 to fail to compile
+ BKrev: 41a51dc9RLGeGsr9z5GLjSGzFovoKQ
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@389 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ correct stack corruption when logging data.
+ (Logical change 1.107)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@388 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ remove extra printf from gmi.
+ (Logical change 1.107)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@387 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ parse.c: correct stack corruption when logging data. gmi.c: remove extra printf from gmi.
+ BKrev: 41a51930u36bUFf2s34EDiXBXWb-1Q
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@386 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2004-11-24 Steven Dake <sdake@mvista.com>
+
+ Fix compile with gcc 2.95.
+ (Logical change 1.106)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@385 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ gmi.c, amf.c: Fix compile with gcc 2.95.
+ BKrev: 41a50bf5bDdOboBSLlLamrDIChW6LQ
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@384 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2004-11-12 Steven Dake <sdake@mvista.com>
+
+ evs.c: Kristen Smith reported a bug where evs would return 0.0.0.0 in the source address. This patch fixes that defect 182.
+ BKrev: 41950c4eWm2WAOmtw1VmnIPUzCirKw
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@383 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Kristen Smith reported a bug where evs would return 0.0.0.0 in the source address. This patch fixes that defect 182.
+ (Logical change 1.105)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@382 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2004-11-08 somacoma <somacoma@unknown.org>
+
+ Merge
+ 2004/10/29 00:13:35+02:00 somacoma.net!dns
+ evt.c:
+ Fix type-punning warnings with gcc-3.3 and later.
+
+ BKrev: 418eb0e5AwiqPJ0GA8LlrTmNOv1pVQ
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@381 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix type-punning warnings with gcc-3.3 and later.
+ (Logical change 1.104)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@380 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2004-11-06 Steven Dake <sdake@mvista.com>
+
+ Commit timeout wasn't stopped when entering gather state. This patch stops the commit timeout when the gather state is entered.
+ (Logical change 1.103)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@379 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Merge sdake@bk.osdl.org:/var/bk/openais into persist.az.mvista.com:/home/sdake/openais
+ 2004/11/06 10:42:19-07:00 mvista.com!sdake
+ gmi.c:
+ Commit timeout wasn't stopped when entering gather state. This patch stops
+ the commit timeout when the gather state is entered.
+
+ BKrev: 418d0d02UJqL-86F2zLxnkruJk2Z7Q
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@378 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2004-11-05 Miyotaka Sakai <sakai@unknown.org>
+
+ Makefile: append keygen.o to clean target amf.c: match function name to coding style
+ BKrev: 418baa69pjW8OB2yd60kweHMtHG5Fg
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@377 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ match function name to coding style
+ (Logical change 1.102)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@376 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ append keygen.o to clean target
+ (Logical change 1.102)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@375 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2004-11-04 Miyotaka Sakai <sakai@unknown.org>
+
+ implement gmi_token_callback in amf.c
+ (Logical change 1.101)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@374 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Makefile: get rid of make error amf.c: implement gmi_token_callback in amf.c
+ BKrev: 418aaf0fKs_99rjhstkG78ZR02mT9g
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@373 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ get rid of make error
+ (Logical change 1.101)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@372 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2004-11-02 Miyotaka Sakai <sakai@unknown.org>
+
+ fix wrong Hastat after node join
+ (Logical change 1.100)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@371 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ fix wrong HaStat after node join
+ (Logical change 1.100)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@370 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2004-11-02 Steven Dake <sdake@mvista.com>
+
+ Merge persist.az.mvista.com:/home/sdake/openais into persist.az.mvista.com:/export/hadev/openais/defect-174
+ 2004/10/31 00:48:17+09:00 sakai!sakai
+ ais_msg.h:
+ fix wrong Hastat after node join
+ amf.c:
+ fix wrong HaStat after node join
+
+ BKrev: 4187f5f99iXw5l-V34v_kR2YTLDpgg
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@369 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2004-10-30 Steven Dake <sdake@mvista.com>
+
+ Add rlimit code to allow openais to work with linux kernel 2.6.9 or later
+ (Logical change 1.99)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@368 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add rlimit code to allow openais to work with linux kernel 2.6.9 or later
+ BKrev: 4182db2fMpOhxCxRnyhHxC5YOCUhvg
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@367 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2004-10-28 Steven Dake <sdake@mvista.com>
+
+ 64bit safe ais types
+ (Logical change 1.98)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@366 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Remove specific o files instead of all objects.
+ (Logical change 1.98)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@365 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Type checking changes for printf's
+ (Logical change 1.98)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@364 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix off by one which oculd cause invalid handle to be used.
+ (Logical change 1.98)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@363 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix off by one which could cause invalid handle to be used.
+ (Logical change 1.98)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@362 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ type safeness printing.
+ (Logical change 1.98)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@361 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Several fixes by Daniel Stodden. Possible crash on invalid handle fixed in library and executive. Also parser could crash when out of memory occurs.
+ util.c:
+ Fix off by one which oculd cause invalid handle to be used.
+ testevt.c, testckpt.c, subscription.c, evtbench.c:
+ type safeness printing.
+ publish.c:
+ type safeness prnting.
+ ais_types.h:
+ 64bit safe ais types
+ Makefile:
+ Remove specific o files instead of all objects.
+ parse.c:
+ Fix crash in parser.
+ hdb.c:
+ Fix off by one which could cause invalid handle to be used.
+ gmi.c:
+ remove type-punned pointer warning
+ ckpt.c, amf.c:
+ Type checking changes for printf's
+
+ BKrev: 4180200fVk1m035hXoENX87UgLUrKg
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@360 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ type safeness prnting.
+ (Logical change 1.98)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@359 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ remove type-punned pointer warning
+ (Logical change 1.98)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@358 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix crash in parser.
+ (Logical change 1.98)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@357 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2004-10-22 Mark Haverkamp <markh@osdl.org>
+
+ I added some cases to test multiple channel and subscriptions as well as some retained event tests.
+ (Logical change 1.97)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@356 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Here some updates to the event code. The first are changes to exec/evt.c: 1. manage the base event ID a little better. 2. I also added some private log levels to allow me to selectively turn on debug output in some sections of the code without turning on everything. 3. Remove (EVT) from all the printf calls.
+ The next is an update to the testevt program. I added some cases to test
+ multiple channel and subscriptions as well as some retained event tests.
+
+ BKrev: 417978c5I2I15AFzIQ0zITa5_ESuZQ
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@355 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ 1. manage the base event ID a little better. 2. I also added some private log levels to allow me to selectively turn on debug output in some sections of the code without turning on everything. 3. Remove (EVT) from all the printf calls.
+ (Logical change 1.97)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@354 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2004-10-18 Steven Dake <sdake@mvista.com>
+
+ Change logging to include service and description.
+ (Logical change 1.96)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@353 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Change loggint o include service and description.
+ (Logical change 1.96)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@352 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add log print service.
+ (Logical change 1.96)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@351 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Delete: exec/log/print.c
+ }(Logical change 1.96)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@350 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add log service level.
+ (Logical change 1.96)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@349 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Big update for better logging to file, syslog, or stderr.
+ print.h:
+ Change loggint o include service and description.
+ print.c:
+ Change logging to include service and description.
+ parse.h, parse.c:
+ Change parser to read new configuration file format.
+ main.c:
+ Some changes for log services.
+ gmi.c, evt.c, evs.c, clm.c, ckpt.c:
+ Add log service level.
+ amf.c:
+ Add log print service.
+ openais.conf:
+ new file
+ .del-network.conf~b38a0f011c4341a7:
+ Delete: conf/network.conf
+ QUICKSTART:
+ Updates that explains new configuration file options.
+ .del-print.h~e83281cecec7f02d:
+ Delete: exec/log/print.h
+ .del-print.c~53000a4a22b4cd:
+ Delete: exec/log/print.c
+
+ BKrev: 41740e46Y1NJgmUMM6WceFwxBVXOVg
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@348 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ (Logical change 1.96)
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@347 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Updates that explains new configuration file options.
+ (Logical change 1.96)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@346 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Change parser to read new configuration file format.
+ (Logical change 1.96)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@345 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Delete: conf/network.conf
+ }(Logical change 1.96)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@344 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Delete: exec/log/print.h
+ }(Logical change 1.96)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@343 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Some changes for log services.
+ (Logical change 1.96)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@342 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Initial revision
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@341 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2004-10-15 Mark Haverkamp <markh@osdl.org>
+
+ Merge markh@bk.osdl.org:/var/bk/openais into markh1.pdx.osdl.net:/home/localmarkh/views/BK/openais_event
+ 2004/10/15 07:34:46-07:00 osdl.net!markh
+ Fix some problems in the open channel recovery code that could cause
+ remaining nodes to have an incorrect count when a node left the
+ membership.
+
+ BKrev: 416fe0393RmyVFqRVwmPFENov-OyGw
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@340 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix some problems in the open channel recovery code that could cause remaining nodes to have an incorrect count when a node left the membership.
+ (Logical change 1.95)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@339 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2004-10-15 Steven Dake <sdake@mvista.com>
+
+ Make testevs exit on evs_initialize if the return code is not EVS_OK.
+ (Logical change 1.94)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@338 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add handle instance destructor code. Previously it was set to null and was being called which caused a null jump.
+ (Logical change 1.94)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@337 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ testevs.c: Make testevs exit on evs_initialize if the return code is not EVS_OK. evs.c: Add handle instance destructor code. Previously it was set to null and was being called which caused a null jump.
+ BKrev: 416f1bdbIKOv0YEK2JzYcGImsLWrsA
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@336 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2004-10-12 Mark Haverkamp <markh@osdl.org>
+
+ Fix some compiler warnings with gcc 3.4
+ (Logical change 1.93)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@335 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Auto merged
+ 2004/10/12 14:57:45-07:00 osdl.net!markh
+ Message type support for tracking open channels
+
+ (Logical change 1.93)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@334 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Auto merged
+ 2004/10/12 14:57:45-07:00 osdl.net!markh
+ This takes care of tracking open channels through configuration
+ changes. The channel structures and data are maintained until the last
+ instance is closed and there are no unexpired retained events. Then the
+ data is freed up.
+
+ (Logical change 1.93)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@333 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Merge markh@bk.osdl.org:/var/bk/openais into markh1.pdx.osdl.net:/home/localmarkh/views/BK/openais_event
+ 2004/10/12 14:57:46-07:00 osdl.net!markh
+ Handle open channels cluster wide and track opens. Free up channel
+ data when there are no more references.
+
+ Also, fix some compiler warnings in lib/evt.c
+
+ BKrev: 416c53d279cT2JNVM_jQ5qBjLGe6EQ
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@332 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2004-10-11 Miyotaka Sakai <sakai@unknown.org>
+
+ correct defalut component name
+ (Logical change 1.92)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@331 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ testamf5.c, testamf3.c: correct defalut component name testamf4.c: correct defalut component name
+ BKrev: 416a4e740QCv2KoVOb0lbFRJYINodA
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@330 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ correct defalut component name
+ (Logical change 1.92)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@329 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ main.c, handlers.h, evt.c, evs.c, clm.c, ckpt.c, amf.c: exec_dump_fn support as SIGUSR2 handler to easy to debug
+ BKrev: 416a3b42053878SDRpbH_G7EUB4rAQ
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@328 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ exec_dump_fn support as SIGUSR2 handler to easy to debug
+ (Logical change 1.91)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@327 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2004-10-05 Steven Dake <sdake@mvista.com>
+
+ Auto merged
+ 2004/10/04 16:08:46-07:00 mvista.com!sdake
+ Remove unneeded debug printf
+
+ (Logical change 1.90)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@326 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Change req_header to res_header to match rest of library, especially for out of order queued messages.
+ (Logical change 1.90)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@325 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Merge sdake@bk.osdl.org:/var/bk/openais into persist.az.mvista.com:/home/sdake/openais
+ 2004/10/04 16:10:02-07:00 mvista.com!sdake
+ testamf.c:
+ Change testamf to just test protection group tracking
+ and componentcapabilitymodelget.
+ amf.c:
+ Change req_header to res_header to match rest of
+ library, especially for out of order queued messages.
+ Remove unneeded debug printf
+
+ BKrev: 416301fc-l-UbKOcLV0FMuNqzCEQIw
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@324 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Auto merged
+ 2004/10/04 16:09:33-07:00 mvista.com!sdake
+ Change testamf to just test protection group tracking
+ and componentcapabilitymodelget.
+
+ (Logical change 1.90)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@323 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2004-10-05 Miyotaka Sakai <sakai@unknown.org>
+
+ amf.h, main.c, amf.c: add Amfcomponent state dump mechanism
+ BKrev: 4162c542Q_AtRTLkaWtprRi7H3ew7w
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@322 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ add Amfcomponent state dump mechanism
+ (Logical change 1.89)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@321 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2004-10-02 Miyotaka Sakai <sakai@unknown.org>
+
+ add surpressing health check printf message
+ (Logical change 1.88)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@320 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ testamf.c: add to reduce health check printf message testamf6.c, testamf5.c, testamf4.c, testamf3.c, testamf2.c, testamf1.c: add to reduce health check printf message
+ BKrev: 415e7532j5RNbHSwQl4tF2HzMJjayQ
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@319 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ add suppressing healthcheck pritf message
+ (Logical change 1.88)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@318 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2004-10-02 Steven Dake <sdake@mvista.com>
+
+ Fix a bunch of errors in node get and async node get.
+ (Logical change 1.87)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@317 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Increase code coverage of clm code.
+ (Logical change 1.87)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@316 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ testclm.c: Increase code coverage of clm code. clm.c, ais_msg.h: Fix a bunch of errors in node get and async node get.
+ BKrev: 415e032aF1mVsl5HqRqEZTGL5S90VA
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@315 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2004-09-29 Miyotaka Sakai <sakai@unknown.org>
+
+ get rid of compile warning
+ (Logical change 1.86)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@314 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ testckpt.c: get rid of compile warning
+ BKrev: 415a0e3b7pcmfNPh8_SQDhuaxhArpQ
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@313 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2004-09-28 Mark Haverkamp <markh@osdl.org>
+
+ Auto merged
+ 2004/09/28 11:29:35-07:00 mvista.com!sdake
+ Configuration change support from Miyotaka Sakai.
+
+ (Logical change 1.85)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@312 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Merge markh@bk.osdl.org:/var/bk/openais into markh1.pdx.osdl.net:/home/localmarkh/views/BK/openais_event
+ 2004/09/28 11:29:45-07:00 mvista.com!sdake
+ parse.h, amf.c:
+ Configuration change support from Miyotaka Sakai.
+
+ BKrev: 4159bb79gTMIV1ezWSXqMb61zwoXkg
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@311 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Auto merged
+ 2004/09/28 11:29:17-07:00 mvista.com!sdake
+ Configuration change support from Miyotaka Sakai.
+
+ (Logical change 1.85)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@310 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Moved the SaNameTisNNameT function to util.c and called it name_match.
+ (Logical change 1.84)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@309 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Replace SaNameTisNameT with name_match from util.[ch]
+ (Logical change 1.84)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@308 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ evt code updated to handle cluster config changes better. Now, when a node joins, it is sent any retained events that have time left on them. Also, if the joining node had been a part of the cluster in the past, it is sent the next event ID that it should use so as to not generate duplicate event IDs. Channel open requests are now completed in the exec handler, with channel close code to follow later.
+ (Logical change 1.84)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@307 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Mostly event service updates to handle recovery after a configuration change. (Selecting next event ID and sending retained events to the joiner).
+ BKrev: 4159ad7atHUdo0CF1QjlYHOM-fjAvQ
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@306 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ testparse.c needs util.o now.
+ (Logical change 1.84)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@305 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ (Logical change 1.84)
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@304 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Remove some old TODO comments.
+ (Logical change 1.84)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@303 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Added util.[ch] for time and SaNameT match functions. Also updated dependencies.
+ (Logical change 1.84)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@302 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Updates for evt to handle recovery after a config change.
+ (Logical change 1.84)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@301 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ added a semi-quiet mode.
+ (Logical change 1.84)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@300 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Initial revision
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@299 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2004-09-28 Steven Dake <sdake@mvista.com>
+
+ Add token callback for recovery routines.
+ (Logical change 1.83)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@298 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add token callback for recovery.
+ gmi.h:
+ Add token callback functions to header.
+ gmi.c:
+ Add token callback for recovery routines.
+
+ BKrev: 4159aa0ejs1nwJhT7hT1XL-gr9wv2Q
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@297 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add token callback functions to header.
+ (Logical change 1.83)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@296 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2004-09-24 Mark Haverkamp <markh@osdl.org>
+
+ Check to see that the message can be sent before proceeding.
+ (Logical change 1.82)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@295 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ add assert around clmNodeJoinSend since the call to gmi_mcast can return a failure now.
+ (Logical change 1.82)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@294 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ add assert around gmi_mcast calls since it can return a failure now.
+ BKrev: 4154791ch3ag3FHVGxaUfrVFsvN3sQ
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@293 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ add assert around gmi_mcast since it can return a failure now.
+ (Logical change 1.82)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@292 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2004-09-24 Steven Dake <sdake@mvista.com>
+
+ testparse.c: Fix commit error in changeset 1.77.
+ BKrev: 41534ab0cY4dYHQw-qoPHLMpXQTAAQ
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@291 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix commit error in changeset 1.77.
+ (Logical change 1.81)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@290 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Allow getSaNameT to be compiled in for application reporting.
+ (Logical change 1.80)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@289 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add sectione xpiration and get checkpoint durations working properly.
+ (Logical change 1.80)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@288 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Clean up duration and expiration functions.
+ (Logical change 1.80)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@287 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Finalize expiration of sections and checkpoints.
+ (Logical change 1.80)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@286 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Test expiration timer.
+ (Logical change 1.80)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@285 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix build error with -DDEBUG set.
+ (Logical change 1.80)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@284 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add final support for duration timers on checkpoints and expiration timers. This cleans up memory leaks that could occur because checkpoints are expected to cleanup with the expiration and duration timers.
+ testckpt.c:
+ Test expiration timer.
+ ckptbenchth.c:
+ Reduce number of threads so runs with valgrind operate faster.
+ ckpt.c:
+ Clean up duration and expiration functions.
+ ais_types.h:
+ Add sectione xpiration and get checkpoint durations working properly.
+ ais_msg.h:
+ Add section expiration and get checkpoint durations working properly.
+ ckpt.h, ckpt.c:
+ Finalize expiration of sections and checkpoints.
+ print.c:
+ Allow getSaNameT to be compiled in for application reporting.
+ evs.c:
+ Fix build error with -DDEBUG set.
+
+ BKrev: 41534a3dcm_0gpB32jNbsek3bGYwXQ
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@283 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Reduce number of threads so runs with valgrind operate faster.
+ (Logical change 1.80)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@282 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add section expiration and get checkpoint durations working properly.
+ (Logical change 1.80)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@281 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2004-09-23 Steven Dake <sdake@mvista.com>
+
+ Store handle address in timer structure. When timer expires, wipe out the handle address's value, since the timer is no longer valid. This allows double frees, or frees on handles that haven't been added. One note of caution: a handle cannot be moved into another variable and be expected to work properly for double frees.
+ (Logical change 1.79)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@280 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Change define for timer handle.
+ (Logical change 1.79)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@279 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ tlist.h: Change interface to allow storing of handle address in timer structure. aispoll.h, aispoll.c: Change define for timer handle. tlist.c: Store handle address in timer structure. When timer expires, wipe out the handle address's value, since the timer is no longer valid. This allows double frees, or frees on handles that haven't been added. One note of caution: a handle cannot be moved into another variable and be expected to work properly for double frees.
+ BKrev: 4152267afe09VjiyO_78GrWKiND_oQ
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@278 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Change interface to allow storing of handle address in timer structure.
+ (Logical change 1.79)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@277 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2004-09-22 Steven Dake <sdake@mvista.com>
+
+ Fix annoying build failure because of code coverage increases.
+ (Logical change 1.78)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@276 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ testparse.c: Fix annoying build failure because of code coverage increases.
+ BKrev: 4151d91edCQRlmhK78LajPaUV35NyQ
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@275 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2004-09-21 Steven Dake <sdake@mvista.com>
+
+ Add retainined events while also cleaning up memory leakage that occurs because of a lack of retained events.
+ (Logical change 1.77)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@274 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add duration timer support. ckpt.h: Add retained checkpoints timer to checkpoint structure. ckpt.c: Add retained checkpoints while also cleaning up memory leakage that occurs because of a lack of retained events.
+ BKrev: 414f7d20vmWMyWW9eWJST5Ew5sw_yw
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@273 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add retained events timer to checkpoint structure.
+ (Logical change 1.77)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@272 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Get rid of valgrind warning and possible segfault.
+ (Logical change 1.76)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@271 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ gmi.c: Get rid of valgrind warning and possible segfault.
+ BKrev: 414f7c5cf4HwWODMiTAI2PCkLX1fnw
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@270 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Missed merge of these two files from last changeset.
+ (Logical change 1.75)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@269 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ handlers.h, gmi.h: Missed merge of these two files from last changeset.
+ BKrev: 414f573d4f7iW8ZMEKLNAImK24Vn3g
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@268 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2004-09-18 Steven Dake <sdake@mvista.com>
+
+ Add recovery plug support to evs. l
+ (Logical change 1.74)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@267 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add recovery plug support to amf.
+ (Logical change 1.74)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@266 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add recovery plug support to openais. This allows messages that are recovery messages to be blocked until recovery completes. All low/medium/high messages cannot be transmitted until all processors have unplugged themselves. If a configuration change occurs, the plugs are invalidated and the recovery starts again.
+ Makefile:
+ Remove two build errors with extra object file included that is not needed.
+ main.c:
+ Add recovery plug support.
+ gmi.c:
+ Add recovery plug support to group messaging.
+ evt.c:
+ Add recovery plug support to evt.
+ evs.c:
+ Add recovery plug support to evs.
+ l
+ clm.c:
+ Add recovery plug support to clm.
+ ckpt.c:
+ Add recovery plug support to ckpt.
+ amf.c:
+ Add recovery plug support to amf.
+
+ BKrev: 414bddd7HCsNs1rz-sJV92mB6fupCw
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@265 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add recovery plug support to clm.
+ (Logical change 1.74)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@264 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add recovery plug support to group messaging.
+ (Logical change 1.74)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@263 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add recovery plug support to evt.
+ (Logical change 1.74)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@262 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add recovery plug support.
+ (Logical change 1.74)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@261 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Remove two build errors with extra object file included that is not needed.
+ (Logical change 1.74)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@260 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add recovery plug support to ckpt.
+ (Logical change 1.74)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@259 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2004-09-16 Steven Dake <sdake@mvista.com>
+
+ gmi.c: Bug 44. Fixes assertion in executive when running ckptbenchth.
+ BKrev: 4148dc42NSqyi9F4s6exhsVarsF10Q
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@258 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Bug 44. Fixes assertion in executive when running ckptbenchth.
+ (Logical change 1.73)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@257 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2004-09-15 Steven Dake <sdake@mvista.com>
+
+ main.c: Call poll_destroy when executing ais_done. This increases code coverage from 66.9% to 82.3%.
+ BKrev: 4148ac12oFAraidHBF8lhdpMgBXc1w
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@256 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Call poll_destroy when executing ais_done. This increases code coverage from 66.9% to 82.3%.
+ (Logical change 1.72)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@255 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Increase code coverage from 19.4% to 100% by adding defines to remove debug print code in production builds. Also removed function by ifdef that is never used in the project.
+ (Logical change 1.71)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@254 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ print.c: Increase code coverage from 19.4% to 100% by adding defines to remove debug print code in production builds. Also removed function by ifdef that is never used in the project.
+ BKrev: 4148a813APgP44Mw4XR-P--e0qYzTw
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@253 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Increased code coverage of tlist.c from 74.5% to 95.9%.
+ (Logical change 1.70)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@252 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ tlist.c: Increased code coverage of tlist.c from 74.5% to 95.9%.
+ BKrev: 4148a64akC3-Hr8RMOSHHChVWBYM5Q
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@251 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Remove unused code.
+ (Logical change 1.69)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@250 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ crypto.h: Remove unused code. crypto.c: Remove unused code and change some error detection to assertions. This increases code covergae from 80.2% to 92.7% with no change in functionality.
+ BKrev: 4148a3f73A3zw2reb3HkDh6RWIrcag
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@249 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Remove unused code and change some error detection to assertions. This increases code covergae from 80.2% to 92.7% with no change in functionality.
+ (Logical change 1.69)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@248 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2004-09-10 Steven Dake <sdake@mvista.com>
+
+ BUG 37. Fix several leaks during configuration changes. Also fixes a possible assert with many large messages being sent from multiple processors at the same time.
+ (Logical change 1.68)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@247 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ gmi.c: BUG 37. Fix several leaks during configuration changes. Also fixes a possible assert with many large messages being sent from multiple processors at the same time.
+ BKrev: 4140fd9dwjk3xOLpFw3Ivhp0_f_oYw
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@246 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2004-09-08 Steven Dake <sdake@mvista.com>
+
+ Merge sdake@bk.osdl.org:/var/bk/openais into persist.az.mvista.com:/home/sdake/openais
+ 2004/09/08 01:11:43-07:00 mvista.com!sdake
+ Code coverage support in build environment and test programs.
+
+ Many files:
+ Add signal handler so code coverage records coverage
+ Makefile:
+ Add code coverage build options and make clean target
+
+ BKrev: 413ebecc_2LPT2fuaQZhw9BymLz6bQ
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@245 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add signal handler so code coverage records coverage
+ (Logical change 1.67)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@244 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add code coverage build options and make clean target
+ (Logical change 1.67)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@243 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2004-09-08 Steven Dake <sdake@broked.org>
+
+ Get rid of magic number 1500 and replace with PACKET_SIZE_MAX. Also fix a glaring memory overwrite bug in gmi_init which would init 256k of memory instead of PACKET_SIZE_MAX memory.
+ (Logical change 1.66)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@242 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ gmi.c: Get rid of magic number 1500 and replace with PACKET_SIZE_MAX. Also fix a glaring memory overwrite bug in gmi_init which would init 256k of memory instead of PACKET_SIZE_MAX memory.
+ BKrev: 413e7bc48wgkqG1E4wSbG9KQkBJMkg
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@241 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2004-09-07 Steven Dake <sdake@broked.org>
+
+ EVS library makes compiler warning on some compilers. Found and fixed by Sakai Miyotaka.
+ (Logical change 1.65)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@240 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2004-09-07 Mark Haverkamp <markh@osdl.org>
+
+ Merge
+ 2004/09/04 16:52:55-07:00 broked.org!sdake
+ Makefile missing clean target for evs bench. Found and fixed by Sakai Miyotaka.
+
+ (Logical change 1.65)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@239 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2004-09-07 Steven Dake <sdake@broked.org>
+
+ (Logical change 1.65)
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@238 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2004-09-07 Mark Haverkamp <markh@osdl.org>
+
+ Merge
+ 2004/09/06 13:30:28-07:00 broked.org!sdake
+ Added man pages and html generation for the EVS interface.
+
+ 2004/09/04 16:54:20-07:00 broked.org!sdake
+ One serious bug in AMF and a few minor nits fixed from patch
+ from Sakai Miyotaka.
+ Makefile:
+ Makefile missing clean target for evs bench. Found and fixed by Sakai Miyotaka.
+ evs.c:
+ EVS library makes compiler warning on some compilers. Found and fixed by
+ Sakai Miyotaka.
+ amf.c:
+ State change from standby-active to outofservice could
+ result in invalid number of active units. Found and fixed by
+ Sakai Miyotaka.
+
+ BKrev: 413dd134zK97xpVttMuRVm6GdcbQlg
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@237 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2004-09-07 Steven Dake <sdake@broked.org>
+
+ State change from standby-active to outofservice could result in invalid number of active units. Found and fixed by Sakai Miyotaka.
+ (Logical change 1.65)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@236 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Initial revision
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@235 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2004-09-07 Mark Haverkamp <markh@osdl.org>
+
+ Clean up some comments code. (comments, old macro).
+ (Logical change 1.64)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@234 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add return value to main.
+ (Logical change 1.64)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@233 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Some code cleanup.
+ BKrev: 413dd073MFU2gjJ72eQd8SOvDfpBwQ
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@232 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2004-09-02 Mark Haverkamp <markh@osdl.org>
+
+ Development, updates, and bug fixes to event service lib.
+ (Logical change 1.63)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@231 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Added special SA_CLM_LOCAL_NODE_ID case to receive your own cluster node data.
+ (Logical change 1.63)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@230 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ (Logical change 1.63)
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@229 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Added event testing programs: evtbench, subscription, publish
+ (Logical change 1.63)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@228 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add in list_add_tail and list_empty functions
+ (Logical change 1.63)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@227 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Check to make sure that sequence ID passed into sq_item_inuse is valid.
+ (Logical change 1.63)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@226 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Event Service Implementation and fixes.
+ BKrev: 41375569R3AaZBcK1LtaD9gt36SuLQ
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@225 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add event service message types.
+ (Logical change 1.63)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@224 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Completed most of the event service functionality.
+ (Logical change 1.63)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@223 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Initial revision
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@222 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2004-08-31 Steven Dake <sdake@broked.org>
+
+ Mark a bug for later resolution
+ (Logical change 1.62)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@221 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Added the EVS service and changed the library queue to 256 entries.
+ (Logical change 1.62)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@220 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Major rewrite of saRecvQueue. Fixed is: activate poll messages are not sent over and over The message header is read into the return buffer if the message doesn't match, a new message is allocated This allows the message buffer for saRecvQueue to be small, but allows receiving very large messages.
+ (Logical change 1.62)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@219 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add the evs library
+ (Logical change 1.62)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@218 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Added the evs target.
+ (Logical change 1.62)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@217 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ This changeset includes major fixes to the IPC from the executive to the library. Also included is an entirely new API called the EVS api (Extended Virtual Synchrony). This API provides EVS semantics for those developers that require this model of programming. The API is defined in include/evs.h and is very simple.
+ The API provides:
+ group semantics with 32 byte group keys.
+ delivery callback
+ configuration change callback
+ join one or more groups
+ leave one or more groups
+ multicast a message to the instance's joined groups
+ multicast a message to any other group
+
+ Makefile:
+ Add the testevs and evsbench targets.
+ evs.c, testevs.c, evsbench.c, evs.h:
+ new file
+ Makefile:
+ Add the evs library
+ util.c:
+ Major rewrite of saRecvQueue. Fixed is:
+ activate poll messages are not sent over and over
+ The message header is read into the return buffer
+ if the message doesn't match, a new message is allocated
+ This allows the message buffer for saRecvQueue to be
+ small, but allows receiving very large messages.
+ amf.c:
+ Mark a bug for later resolution
+ ais_msg.h:
+ Add the evs messages and descriptors.
+ Makefile:
+ Added the evs target.
+ main.h:
+ Added the EVS service and changed the library queue
+ to 256 entries.
+ main.c:
+ major rewrite of the IPC code for sending messages
+ to the library. What was there previously was very
+ broken.
+ gmi.c:
+ Fix bug where transition from multiple members to
+ single members would cause messages not to be sent.
+ Also fixed an assertion in transition from multiple
+ processors to one processor.
+
+ BKrev: 41343518pVUD6aQu4urTw6ClPiOl3w
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@216 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add the testevs and evsbench targets.
+ (Logical change 1.62)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@215 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ major rewrite of the IPC code for sending messages to the library. What was there previously was very broken.
+ (Logical change 1.62)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@214 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add the evs messages and descriptors.
+ (Logical change 1.62)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@213 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ (Logical change 1.62)
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@212 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix bug where transition from multiple members to single members would cause messages not to be sent. Also fixed an assertion in transition from multiple processors to one processor.
+ (Logical change 1.62)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@211 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Initial revision
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@210 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2004-08-28 Steven Dake <sdake@mvista.com>
+
+ gmi.c: Flush all multicast messages by delivering them before processing the token. This ensures that the mcast fd doesn't buffer too many old messages and avoids an assert.
+ BKrev: 412fd3cesE7M-pXl9OZs1X2CyK7Y4A
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@209 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Flush all multicast messages by delivering them before processing the token. This ensures that the mcast fd doesn't buffer too many old messages and avoids an assert.
+ (Logical change 1.61)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@208 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2004-08-24 Steven Dake <sdake@mvista.com>
+
+ Add initial support for multipathing to group messaging.
+ (Logical change 1.60)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@207 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Change gmi interface to support multipathing.
+ (Logical change 1.60)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@206 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Change network configuration parser interface to support multipathing.
+ (Logical change 1.60)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@205 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ parse.h: Change network configuration parser interface to support multipathing. gmi.h, main.c: Change gmi interface to support multipathing. parse.c: Change network configuration parser to read multiple interfaces. gmi.c: Add initial support for multipathing to group messaging.
+ BKrev: 412a981dC8TjKSqUYOtAx6jKoO-UlA
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@204 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Change network configuration parser to read multiple interfaces.
+ (Logical change 1.60)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@203 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2004-08-24 Mark Haverkamp <markh@osdl.org>
+
+ Need to check the size of the response header here.
+ (Logical change 1.59)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@202 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Need to check the size of the response header instead of the request header in saRecvQueue.
+ BKrev: 412a6f3b4NlVb-n94TuM1jqiD4KUgA
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@201 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2004-08-23 Steven Dake <sdake@mvista.com>
+
+ Clean up usage of ais_done. This includes passing a value for each done type. Also, libais_disconnect cleaned up so it doesn't ais_done when its queues are full. Instead it disconnects the library connection. A new connection state variable added to the conn_info structure in place of active.
+ (Logical change 1.58)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@200 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Changed number of queueable messages to the library from 8192 to 128 messages.
+ (Logical change 1.58)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@199 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Use new connection enumeration with AMF code.
+ (Logical change 1.58)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@198 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ main.h: Changed number of queueable messages to the library from 8192 to 128 messages. main.c: Clean up usage of ais_done. This includes passing a value for each done type. Also, libais_disconnect cleaned up so it doesn't ais_done when its queues are full. Instead it disconnects the library connection. A new connection state variable added to the conn_info structure in place of active. amf.c: Use new connection enumeration with AMF code.
+ BKrev: 41297f85ZsPdr8oHUfjQ6v_A6b6ybw
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@197 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Missed commit to changes for queue.h.
+ (Logical change 1.57)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@196 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ queue.h: Missed commit to changes for queue.h. ais_msg.h: Missed commit of changes to ais_msg.h.
+ BKrev: 41292695YG_qjNyfkNoFlMFaeiR7zg
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@195 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Missed commit of changes to ais_msg.h.
+ (Logical change 1.57)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@194 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add flow control documentation to devmap. .l
+ 2004/08/22 15:24:25-07:00 mvista.com!sdake
+ Add event service to devmap.
+
+ (Logical change 1.56)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@193 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ README.devmap: Add flow control documentation to devmap. Add event service to devmap.
+ BKrev: 412922454HMPjB41f5bgMaos4soalg
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@192 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2004-08-21 Steven Dake <sdake@mvista.com>
+
+ Cleanup errors in Makefile.
+ (Logical change 1.55)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@191 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Change interface so there is a new libais_handler structure.
+ (Logical change 1.55)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@190 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add support for flow control to amf library.
+ (Logical change 1.55)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@189 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add support to group messaging to get flow control information.
+ (Logical change 1.55)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@188 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add flow control support to the checkpoint benchmark program.
+ (Logical change 1.55)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@187 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Flow control changes.
+ (Logical change 1.55)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@186 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ testamf3.c: misc flow control changes. ckptbenchth.c: Retry checkpoint writes on threaded writes if SA_ERR_TRY_AGAIn received. ckptbench.c: Add flow control support to the checkpoint benchmark program. util.c: Add flow control to saRecvQueue function. evt.c: Add flow control to eventing. clm.c: Add flow control to cluster membership. ckpt.c: Add flow control to checkpointing. amf.c: Add flow control to amf. Makefile: Cleanup errors in Makefile. main.h: Flow control changes. handlers.h: Change interface so there is a new libais_handler structure. gmi.h: Add support to group messaging for another priority level. main.c: Add support to disconnect and dispatch to utilize flow control. gmi.c: Add support to group messaging to get flow control information. evt.c: Add support to eventing for flow control. clm.c: Add support to clm for flow control. ckpt.c: Add support for flow control to ckpt library. amf.c: Add support for flow control to amf library.
+ BKrev: 412678baBKkyszbWcphf0Vg85SpLXg
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@185 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Retry checkpoint writes on threaded writes if SA_ERR_TRY_AGAIn received.
+ (Logical change 1.55)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@184 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add support to group messaging for another priority level.
+ (Logical change 1.55)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@183 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add flow control to eventing.
+ (Logical change 1.55)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@182 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add flow control to cluster membership.
+ (Logical change 1.55)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@181 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add support to eventing for flow control.
+ (Logical change 1.55)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@180 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add support to disconnect and dispatch to utilize flow control.
+ (Logical change 1.55)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@179 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add flow control to amf.
+ (Logical change 1.55)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@178 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add support for flow control to ckpt library.
+ (Logical change 1.55)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@177 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ misc flow control changes.
+ (Logical change 1.55)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@176 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add flow control to saRecvQueue function.
+ (Logical change 1.55)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@175 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add flow control to checkpointing.
+ (Logical change 1.55)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@174 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add support to clm for flow control.
+ (Logical change 1.55)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@173 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2004-08-14 Steven Dake <sdake@broked.org>
+
+ Add priority to poll abstraction Higher priority items will be serviced first
+ (Logical change 1.54)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@172 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Priorites added to dispatch function. This is in prep for flow control to allow dispatch functions that haven't been serviced in awhile to be bumped up in priority when they are not serviced.
+ The priority of the dispatch handler is passed to the dispatch
+ function which can modify it in place. The new priority will be
+ used the next time the poll system call is executed.
+
+ main.c:
+ Add library accept handler at lowest priority
+ gmi.c:
+ Make gmi highest priority when adding dispatch functions
+ aispoll.h, aispoll.c:
+ Add priority to poll abstraction
+ Higher priority items will be serviced first
+
+ BKrev: 411dda8dXGsq4glmjj36km40YZhjCA
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@171 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Make gmi highest priority when adding dispatch functions
+ (Logical change 1.54)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@170 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add library accept handler at lowest priority
+ (Logical change 1.54)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@169 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2004-08-10 Steven Dake <sdake@broked.org>
+
+ gmi.c: When 2 processors are part of the configuration, then one of the members leaves, then a new configuration occurs with 2 or more members, the "joined" list was not being properly passed to the rest of the executive services. This bug fixed.
+ BKrev: 41185349SwUWKZU-QQ_K91jAnvqYpA
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@168 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ When 2 processors are part of the configuration, then one of the members leaves, then a new configuration occurs with 2 or more members, the "joined" list was not being properly passed to the rest of the executive services. This bug fixed.
+ (Logical change 1.53)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@167 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2004-08-09 Steven Dake <sdake@mvista.com>
+
+ Add encryption and authentication to GMI.
+ (Logical change 1.52)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@166 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add encryption and authentication to all messages so that messages are secret and are always known to come from a source that knows the private key.
+ SECURITY:
+ Describe latest security system using SOBER, SHA1, and HMAC.
+ QUICKSTART:
+ Add details to creating security key to quickstart guide.
+ LICENSE:
+ Add libtomcrypt's license text for crypto.c and crypto.h
+ Makefile:
+ Add crytpo features to makefile
+ gmi.h:
+ Add ability to pass key and keylen to gmi_init.
+ Add ability to set security logging value.
+ gmi.c:
+ Add encryption and authentication to GMI.
+
+ BKrev: 4117ed75MEkDZv2CoCUYGolBNHy17Q
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@165 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add details to creating security key to quickstart guide.
+ (Logical change 1.52)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@164 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add ability to pass key and keylen to gmi_init. Add ability to set security logging value.
+ (Logical change 1.52)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@163 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add libtomcrypt's license text for crypto.c and crypto.h
+ (Logical change 1.52)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@162 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add crytpo features to makefile
+ (Logical change 1.52)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@161 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ (Logical change 1.52)
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@160 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Describe latest security system using SOBER, SHA1, and HMAC.
+ (Logical change 1.52)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@159 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ keygen.c, crypto.h, crypto.c: New files for cryptography support.
+ BKrev: 4117ecc6HWTXJ7DG7UZ3E01aKajTBA
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@158 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ (Logical change 1.51)
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@157 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Initial revision
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@156 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2004-07-30 Mark Haverkamp <markh@osdl.org>
+
+ Fix compiler warning
+ (Logical change 1.50)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@155 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix compiler warning
+ BKrev: 410a8aa45tOLcJaeS6TU0H7l55hYiQ
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@154 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix queue items memory leak.
+ (Logical change 1.49)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@153 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix queue items memory leak.
+ BKrev: 410a8a1arpYlwWZY9PRvbEkRYy7zkQ
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@152 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2004-07-30 Steven Dake <sdake@mvista.com>
+
+ Change RecvQueue to use a stack structure for receiving the response instead of passing in the maximum sized value for a response message.
+ (Logical change 1.48)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@151 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Clean up RecvQueue users and pass in actual buffer instead of "overly large" buffer which has changed because of changes to util.c Also cleaned up memory leak in the dispatch function.
+ (Logical change 1.48)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@150 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ util.c: Change RecvQueue to use a stack structure for receiving the response instead of passing in the maximum sized value for a response message. ckpt.c: Change all RecvQueue users to use RecvRetry since there is no reason to queue out of order messages. amf.c: Clean up RecvQueue users and pass in actual buffer instead of "overly large" buffer which has changed because of changes to util.c Also cleaned up memory leak in the dispatch function.
+ BKrev: 4109819b_adTTm4cCZmfLJcsYb9hyA
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@149 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Change all RecvQueue users to use RecvRetry since there is no reason to queue out of order messages.
+ (Logical change 1.48)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@148 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2004-07-29 Steven Dake <sdake@mvista.com>
+
+ (Logical change 1.47)
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@147 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add function in exec/clm to get the full cluster node information for any node in the cluster membership
+ (Logical change 1.47)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@146 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2004-07-29 Mark Haverkamp <markh@osdl.org>
+
+ Merge bk://bk.osdl.org/openais into markh1.pdx.osdl.net:/home/localmarkh/views/BK/openais_stage
+ 2004/07/29 12:26:46-07:00 mvista.com!sdake
+ clm.c:
+ Add function in exec/clm to get the full cluster node information
+ for any node in the cluster membership
+
+ BKrev: 410955capPzVdVwzpMJetS80seWS7g
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@145 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Added event code and dependencies.
+ (Logical change 1.46)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@144 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ added event message types and associated data structures.
+ (Logical change 1.46)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@143 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Event service data types.
+ (Logical change 1.46)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@142 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ This adds the start of the AIS event service code. The library code is mostly complete. The aisexec part just has placeholders for now and will be filled in later.
+ BKrev: 410944e7-oXL5OZSJvizPPH9dGS2GA
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@141 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Added event library and depend target.
+ (Logical change 1.46)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@140 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ added event service handler.
+ (Logical change 1.46)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@139 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ added event service.
+ (Logical change 1.46)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@138 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Added clustTimeNow to get current time in nanoseconds.
+ (Logical change 1.46)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@137 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Added event test program and depend target.
+ (Logical change 1.46)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@136 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ (Logical change 1.46)
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@135 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Initial revision
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@134 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2004-07-29 Steven Dake <sdake@mvista.com>
+
+ README.devmap: Document new changes to exec handler function prototype and recommend using the source_addr for deferring requests instead of recording the ip address in the message itself. main.c, handlers.h, clm.c, ckpt.c, amf.c: Add source_addr to exec message handler for event service.
+ BKrev: 41082a5cY6cLQK7NG_rxZrkb7lERfw
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@133 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Document new changes to exec handler function prototype and recommend using the source_addr for deferring requests instead of recording the ip address in the message itself.
+ (Logical change 1.45)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@132 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add source_addr to exec message handler for event service.
+ (Logical change 1.45)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@131 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2004-07-28 Steven Dake <sdake@mvista.com>
+
+ Major cleanup and use hdb.c abstracted out functions now instead of internal hacked together stuff that was there previously.
+ (Logical change 1.44)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@130 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Remove "old-style" handle database code from aispoll.c and include instead hdb.c/hdb.h. These files are copies of the handle database code used for the library without mutexes.
+ This work for Mark Haverkamp to use the handle database functionality
+ as part of the event service.
+
+ BKrev: 4106e5a7ANCdXqe3zoIfO1tcYyrQhQ
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@129 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Major cleanup to use hdb.c handle database functions.
+ (Logical change 1.44)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@128 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add hdb.c to the build.
+ (Logical change 1.44)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@127 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ (Logical change 1.44)
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@126 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Initial revision
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@125 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Remove handle state and handle instance information. Also cleanup saHandleCreate to return unsigned int handle instead of int handle.
+ (Logical change 1.43)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@124 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Hide handle state and handle instance information in this file instead of in global header file.
+ (Logical change 1.43)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@123 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ util.h: Remove handle state and handle instance information. Also cleanup saHandleCreate to return unsigned int handle instead of int handle. util.c: Hide handle state and handle instance information in this file instead of in global header file.
+ BKrev: 4106e4d1-Ntb973S5ymyNwgL6e0PDw
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@122 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2004-07-27 Steven Dake <sdake@mvista.com>
+
+ Remove BINDTODEVICE socket option and replace with MULTICAST_IF to be more portable and require less root privs.
+ (Logical change 1.42)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@121 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ gmi.c: Remove BINDTODEVICE socket option and replace with MULTICAST_IF to be more portable and require less root privs.
+ BKrev: 410583008afZgkQ66_jDep-8pFf_nw
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@120 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2004-07-24 Steven Dake <sdake@mvista.com>
+
+ Additional information for using the saRecvQueue call in a library.
+ (Logical change 1.41)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@119 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ README.devmap: Additional information for using the saRecvQueue call in a library.
+ BKrev: 41018de8tOmRhu_QtrtzbSGzWHSMKA
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@118 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2004-07-21 Steven Dake <sdake@mvista.com>
+
+ (Logical change 1.40)
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@117 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ SECURITY: Description of the security policy of the openais project. Includes a description of the techniques used in openais.
+ BKrev: 40fdaf10zR42cuBrfB9UB-Bc-edNsQ
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@116 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Initial revision
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@115 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2004-07-15 Steven Dake <sdake@mvista.com>
+
+ Major improvements to fragmentation. It works alot better now.
+ (Logical change 1.39)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@114 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Major improvements to quality in the GMI. Previously with 12 processors and running ckptstress from two nodes, one node would fail to make forward progress. Sometimes the nodes would assert or crash. All the fragmentation code has been rewritten to be more stable and of better design (at the cost of a little more memory).
+ BKrev: 40f5c9b6KnXRw3_UyUgLV-cIvI7YpA
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@113 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2004-07-13 Steven Dake <sdake@mvista.com>
+
+ Allow NULL delivery_fn in gmi_join. This basically has no effect but allows the processor to participate in multicasting and membership.
+ (Logical change 1.38)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@112 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ gmi.c: Allow NULL delivery_fn in gmi_join. This basically has no effect but allows the processor to participate in multicasting and membership.
+ BKrev: 40f419f8lTr8W134C7CXrtXRnzoMzw
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@111 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Extraneous tokens were not being rejected on token retransmits that occurred during configuration changes. The result was bad behavior, especially with larger rings. Also cleaned up the token retransmit timer to be deleted if necessary.
+ (Logical change 1.37)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@110 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ gmi.c: Extraneous tokens were not being rejected on token retransmits that occurred during configuration changes. The result was bad behavior, especially with larger rings. Also cleaned up the token retransmit timer to be deleted if necessary.
+ BKrev: 40f419afbeZlmKywfUpsrDkU5kMnHg
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@109 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add ip to deliver_fn callback
+ (Logical change 1.36)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@108 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add ip to deliver_fn callback
+ BKrev: 40f35c58ypi89e5Nq53F73OF8QGakA
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@107 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add ip to deliver_fn callback Add ip to deliver_fn callback Add ip to deliver_fn callback
+ (Logical change 1.36)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@106 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Removed something that was necessary in last changeset.
+ (Logical change 1.35)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@105 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ gmi.c: Removed something that was necessary in last changeset.
+ BKrev: 40f35ba0CGzAzJZVAZx-QxSIYzQlNQ
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@104 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2004-07-12 Steven Dake <sdake@mvista.com>
+
+ gmi.c: Fix debug exit.
+ BKrev: 40f3069ao4cKWSuICZHrMdMIqJDlMw
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@103 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix debug exit.
+ (Logical change 1.34)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@102 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Merge sdake@bk.osdl.org:/var/bk/openais into persist.az.mvista.com:/home/sdake/openais
+ 2004/07/12 14:40:19-07:00 mvista.com!sdake
+ gmi.c:
+ When a processor left the membership, the next configuration would sometimes
+ cause a form token timeout. While not particularly harmful, it was wasteful
+ and not part of the original design of the group messaging protocol.
+ There was some extra junk code that was added to workaround some other bug
+ that has since been fixed.
+ This junk code removed and now the form token never times out (woohoo).
+ Also removed some extra code that calculates the next ORF processor twice.
+ We only really need to do it once.
+
+ BKrev: 40f3054fipDDp-KdB8CJpzw0vS3PfA
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@101 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Auto merged
+ 2004/07/12 14:37:13-07:00 mvista.com!sdake
+ When a processor left the membership, the next configuration would sometimes
+ cause a form token timeout. While not particularly harmful, it was wasteful
+ and not part of the original design of the group messaging protocol.
+ There was some extra junk code that was added to workaround some other bug
+ that has since been fixed.
+ This junk code removed and now the form token never times out (woohoo).
+ Also removed some extra code that calculates the next ORF processor twice.
+ We only really need to do it once.
+
+ (Logical change 1.33)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@100 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2004-07-12 Steven Dake <sdake@broked.org>
+
+ Retransmit orf token if no multicast or token received within a timeout period. This could mean that the token was lost, but no configuration change has really occured. Rather then execute the heavyweight membership protocol, just retry the token and if it fails after the token timeout, execute a configuration change sequence.
+ BKrev: 40f21082dvUxH0aOPvKmpqoqlkEgEA
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@99 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add retransmit of token if no multicast or token received within a timeout period (100 msec). This helps avoid a reconfiguration when only the token is lost, but no real configuration changes have occured.
+ (Logical change 1.32)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@98 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Changeset 1.22 introduced problem with managing messages in the sort queue. The result was memory leakage.
+ (Logical change 1.31)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@97 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix memory leak introduced in changeset 1.22.
+ BKrev: 40f20a301E28mF_1r27z43zk2MqHeA
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@96 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2004-07-11 Steven Dake <sdake@mvista.com>
+
+ Clean up warnings found with -pedantic.
+ BKrev: 40f0eaa4fMlsgdXtJH-HQEl5nRh78Q
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@95 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Clean up warnings found with -pedantic.
+ (Logical change 1.30)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@94 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Changed references to C99 initializers after pedantic cleanup
+ (Logical change 1.30)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@93 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2004-07-10 Steven Dake <sdake@mvista.com>
+
+ Removes the external dependency from the gmi to the global variable this_ip. This is still passed in for gmi_init users to be notified of which IP was selected, but copied for local use.
+ BKrev: 40ef692cfv-e5JCQ8T9iC-_i3AaBcg
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@92 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fixes build problem with rename of aispoll.c.
+ (Logical change 1.29)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@91 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Removes this_ip external dependency and instead copies the bound to address to storage local to the group messaging interface.
+ (Logical change 1.29)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@90 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2004-07-09 Steven Dake <sdake@mvista.com>
+
+ Rename: exec/poll.h -> exec/aispoll.h
+ }(Logical change 1.28)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@89 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Rename aispoll.h so that people using the aispoll header file do not collide with sys/poll.h.
+ BKrev: 40ef0fadvg4jQb-J9VhBM25mh_mdMQ
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@88 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Rename: exec/poll.h -> exec/aispoll.h
+ (Logical change 1.28)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@87 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Rename: exec/poll.c -> exec/aispoll.c
+ (Logical change 1.28)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@86 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Rename: exec/poll.c -> exec/aispoll.c
+ }(Logical change 1.28)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@85 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Rename poll.h to aispoll.h
+ (Logical change 1.28)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@84 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Initial revision
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@83 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2004-07-08 Steven Dake <sdake@mvista.com>
+
+ Fix a merge problem with the previous update to the amf with the conn_info structure. the track list was not being initialized at start.
+ (Logical change 1.27)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@82 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix merge bugs from changeset 1.23.
+ BKrev: 40edb2ddF4jV4bxQYmbXj7nCSPCe2w
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@81 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix a couple merge problems with the previous update to clm with the conn_info structure. the track list was not being initialized. When track start was called the tracking wasn't added to a list. When track stop was called the tracking was not deleted. The result of all this is that cluster membership tracking was broken previously.
+ (Logical change 1.27)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@80 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Development documentation update. After reading these docs, it should be possible to add a service to the AIS.
+ (Logical change 1.26)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@79 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Learn how to develop an AIS service with README.devmap.
+ BKrev: 40eda440k9_Mia7kFQvGzgthaN_bWQ
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@78 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix build errors after previous commit.
+ (Logical change 1.25)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@77 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Cleanup last commit so build occurs properly.
+ BKrev: 40ec739f-StbBZFtCXNnVcEbdIqOYg
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@76 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ pass conn_info to all messages instead of file descriptor. This requires changing the initialization phase of the socket and all calls made.
+ (Logical change 1.24)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@75 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Big cleanup of executive to pass connection info by reference instead of having connection info as an array seperate from the poll interface. This makes the code alot cleaner and easier to read, plus removes duplicated code in the connection array management.
+ BKrev: 40ec72dd7wKGeQDubAA6lmUMc7JjOQ
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@74 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ update todo by removing completed items.
+ (Logical change 1.24)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@73 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ store conn_info field is component structure.
+ (Logical change 1.24)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@72 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ pass conn_info to all messages instead of file descriptor.
+ (Logical change 1.24)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@71 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ pass conn_info to all messages instead of file descriptor. this requires removing the connection structure and replacing with the conn_info structure.
+ (Logical change 1.24)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@70 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ when gmi.c changed, full project would not always be rebuilt fixed this issue.
+ (Logical change 1.24)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@69 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Run full tests instead of writing a bunch of checkpoints.
+ (Logical change 1.24)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@68 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add track active variable to keep track of active connections.
+ (Logical change 1.24)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@67 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ cleanup valgrind warnings.
+ (Logical change 1.24)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@66 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ change message source to use conn_info field instead of fd. Also removed a few unneeded calls which were moved to the amf.c file.
+ (Logical change 1.24)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@65 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2004-07-07 Steven Dake <sdake@mvista.com>
+
+ Change memcpy to memmove to quiet down valgrind.
+ (Logical change 1.23)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@64 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ valgrind found an off-by-one error in message frees that could lead to corruption. l
+ (Logical change 1.23)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@63 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Clean up some errors found with valgrind 2.1.1.
+ BKrev: 40ec6721IO7rAWx1t4cNnFNTugIZ1A
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@62 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Get rid of some errors from valgrind by initializing variables.
+ (Logical change 1.23)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@61 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2004-07-06 Steven Dake <sdake@mvista.com>
+
+ Remove extra unused parameter to exec messages.
+ (Logical change 1.22)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@60 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Remove extra parameter to exec messages.
+ (Logical change 1.22)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@59 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Every exec message was of the prototype int func (int fd, void *msg). The "int fd" was not used by an executive message and was dead code from a previous implementation. This dead parameter removed from the tree.
+ BKrev: 40eb05fa_UbGyISyMyNciMoGXAXDeg
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@58 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add activate poll message.
+ (Logical change 1.21)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@57 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Use new APIs for handle reference counting
+ (Logical change 1.21)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@56 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Change clunky locking used in library APIs to use reference counting instead. A BIG thanks to Chris Friesen who provided the initial ideas, additional comments and more ideas leading up to the commit.
+ BKrev: 40eafcb50VMDbK4i9ZEiu0_90gFlPQ
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@55 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix example to use component names in example service group.
+ (Logical change 1.21)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@54 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Change activate poll definitions to be generic instead of AMF specific.
+ (Logical change 1.21)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@53 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Use new APIs for handle reference counting.
+ (Logical change 1.21)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@52 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ add activate poll message
+ (Logical change 1.21)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@51 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix segfault during membership changes with multiple leaves at the same time.
+ BKrev: 40eaeec3CJrXaOzED0qddXmUUurQdg
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@50 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Wrong value being used to determine leave list, resulting in a memcpy with a -1 value in some cases, and the incorrect memcpy in other cases.
+ (Logical change 1.20)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@49 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2004-07-01 Steven Dake <sdake@mvista.com>
+
+ With a two node cluster and one node killed, the remaining node didn't sent the appropriate configuration changes to the clm API or to the rest of the services.
+ (Logical change 1.19)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@48 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix two node cluster membership event not appearing on leave problem reported by Chris Friesen.
+ BKrev: 40e477d75L2YauKHr18UGUlPGfAEoA
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@47 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ remove dead code.
+ BKrev: 40e451f2-IOwwPNaNm65NetyBme-nw
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@46 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ remove dead code.
+ (Logical change 1.18)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@45 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2004-06-30 Steven Dake <sdake@mvista.com>
+
+ The group messaging interface has been exported as a library for use in other programs. The key interfaces are exec/gmi.h and exec/poll.h. gmi.h describes the interface for group messaging, while poll.h describes the interface for abstracting poll system call with timers and integrated with gmi. By including these headers in programs and linking with libgmi, it is possible to use the virtual synchrony layer (group messaging interface) used in AIS for other applications.
+ BKrev: 40e30f7bM1KpRbp3-Bf2qVPRH1EsFA
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@44 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Initialize logging function in group messaging interface.
+ (Logical change 1.17)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@43 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Build gmi static and shared library for use in other programs.
+ (Logical change 1.17)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@42 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add logging function init interface.
+ (Logical change 1.17)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@41 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add ability to pass in logging function for people that want to use their own logging functions in their own programs.
+ (Logical change 1.17)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@40 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ add debug checking version of logging function.
+ (Logical change 1.17)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@39 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ make clean didn't remove ckptbench and ckptbenchth binaries
+ (Logical change 1.17)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@38 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Chris Friesen reported the testamf programs don't work correctly. Error in description of quickstart guide about how they should work which has been corrected. Also added information about using the ckptbench and ckptbenchth programs to benchmark checkpoint writes.
+ (Logical change 1.16)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@37 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ (Logical change 1.16)
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@36 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Modify QUICKSTART to clarify how testamf{1-6} work and added some text about using the ckptbench and ckptbenchth test programs. Also added the ckptbench and ckptbenchth programs to the build environment.
+ BKrev: 40e26a810DYCs3LU79Ne-q51pO2TgA
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@35 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add ckptbench and ckptbenchth targets
+ (Logical change 1.16)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@34 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Initial revision
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@33 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2004-06-29 Steven Dake <sdake@mvista.com>
+
+ Cluster membership API not being authenticated by openais executive. This results in testclm locking on start in saClmInitialize.
+ BKrev: 40e095e4VUojyuQYOBeAUqjZnbBTCA
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@32 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix cluster membership API not being authenticated bug.
+ (Logical change 1.15)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@31 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2004-06-27 Steven Dake <sdake@mvista.com>
+
+ Make bind to a device really work properly. Now it is possible to specify the bind network and the networking will take place over that interface.
+ (Logical change 1.14)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@30 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add priv drop so process doesn't have to run as root in order to lock, set RR 99, and bind to a specific ethernet interface for multicast.
+ (Logical change 1.14)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@29 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Make binding to a specific network really work. Also added priv dropping so process doesn't have to run as root for process lifetime.
+ BKrev: 40df35a4eUCTfC660C7oBwg-P9YE2g
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@28 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2004-06-23 Steven Dake <sdake@mvista.com>
+
+ Yixiong Zou reported a problem where on some OSes the aisexec couldn't join the multicast group. This problem fixed. Also changed binding rules for sockets relating to the group messaging. see detailed changlogs for more details.
+ BKrev: 40d9efacQooUDhv3APjn55QVVjMueg
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@27 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix binding rules so that instead of binding to INADDR_ANY for UDP sockets, bind to specific interface defined in network.conf. This is done by creating two fds. gmi_fd_token is used for all token communication. gmi_fd_mcast is used for all mcast communication. I'm not sure if gmi_fd_mcast binding rules is correct. Once work begins on multipathing, this will have to be figured out :)
+ 2004/06/23 13:55:52-07:00 mvista.com!sdake
+ Use portable mreq instead of mreqn when joining the multicast
+ group.
+
+ (Logical change 1.13)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@26 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ QUICKSTART: Modified quickstart guide thanks to comments from Yixiong Zou Information about adding groups added Information about testclm blocking until cluster membership event occurs added.
+ BKrev: 40d920ffgjnZO35fZ2d947AV5TWGWQ
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@25 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Modified quickstart guide thanks to comments from Yixiong Zou Information about adding groups added Information about testclm blocking until cluster membership event occurs added.
+ (Logical change 1.12)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@24 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2004-06-21 Steven Dake <sdake@mvista.com>
+
+ Buffer with message data used outside lock. This creates a possible race where data from another response could be used to execute a dispatch.
+ 2004/06/21 00:59:54-07:00 mvista.com!sdake
+ Remove double pthread_mutex_unlock on saAmfDispatch routine. Unlock could
+ unlock another thread's unlock midthread.
+
+ (Logical change 1.11)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@23 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix race with saClmDispatch where two threads could race for access to the response data from the AIS Executive.
+ (Logical change 1.11)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@22 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix race relating to threads and saClmDispatch/saAmfDispatch.
+ BKrev: 40d6977ewZ8VFYD8mJyEaPWxg0tI7w
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@21 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2004-06-20 Steven Dake <sdake@mvista.com>
+
+ Add support for C++ linkage to cluster membership API. Without this change, C++ programs will not link to the library.
+ BKrev: 40d53e4bzcKNiPnfX523_065NBw4gg
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@20 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Add support for C++ linkage to cluster membership APIs.
+ (Logical change 1.10)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@19 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Port not actually set to correct port as found with tcpdump.
+ BKrev: 40d53d26QDtzR8msp2zMvJ-9Mq6-Tw
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@18 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ x86 was not setting port to network byte order, which resulted in port being byte swapped. This of course, doesn't work well with xscale boards.
+ (Logical change 1.9)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@17 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2004-06-18 Steven Dake <sdake@mvista.com>
+
+ quickstart gives incorrect info about multicast addresses, now corrected.
+ BKrev: 40d35b80BGcr_8TvtSlrbEZBn14zZA
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@16 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ fix error in quickstart
+ (Logical change 1.8)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@15 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix single-node AMF assertion failure (cause runaway recursion).
+ BKrev: 40d22e42IsByk3WqoRIGSlETLqdUgw
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@14 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ single node AMF would fail because of a recursion bug. Removed the recursion by queueing single node message delivery as a timer with 0 timeout. This was happening before, but the logic was wrong.
+ (Logical change 1.7)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@13 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2004-06-17 Steven Dake <sdake@mvista.com>
+
+ Crash when no network.conf file present (missing error checking).
+ (Logical change 1.6)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@12 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix crash when error reading network.conf file.
+ BKrev: 40d21314UfLNnjjrMSt_4U9rJZSVHA
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@11 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Fix bug in membership protocol where form token sometimes times out because the initial send of the token is sent to the wrong address.
+ 2004/06/16 15:42:49-07:00 mvista.com!sdake
+ Performance enhancements: Allow more messages to be multicast per
+ token possession to reach 8.8MB/sec checkpoint performance without
+ remcasts. Trim gather/commit timeouts to 100 msec to speed up the
+ membership gathering process.
+
+ (Logical change 1.5)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@10 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Bug fix and performance enhancements to the group messaging protocol.
+ BKrev: 40d0cebf3iPVrudikdxGEhhTs-CQMw
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@9 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2004-06-16 Steven Dake <sdake@mvista.com>
+
+ QUICKSTART: Test change
+ BKrev: 40cfe45fPOa0mbN6jPO9bRiSG_tZWA
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@8 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Test change
+ (Logical change 1.4)
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@7 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2004-06-16 John Cherry <cherry@osdl.net>
+
+ Import changeset
+ BKrev: 40cf759cAkpvgQbZ43nWNRClHYqlXQ
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@6 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ (Logical change 1.3)
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@5 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Initial revision
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@4 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2004-06-16 cem <cem@osdl.net>
+
+ Initial repository create
+ BKrev: 40cf7521T7yNtYdteqiCUMgD7RdOCA
+
+
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@3 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+ Initial revision
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2 fd59a12c-fef9-0310-b244-a6a79926bd2f
+
+2004-06-16 Steven Dake <sdake@broked.org>
+
+ New repository initialized by cvs2svn.
+ git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1 fd59a12c-fef9-0310-b244-a6a79926bd2f
diff --git a/Doxyfile.in b/Doxyfile.in
new file mode 100644
index 0000000..c3340e0
--- /dev/null
+++ b/Doxyfile.in
@@ -0,0 +1,1644 @@
+# Doxyfile 1.7.3
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project.
+#
+# All text after a hash (#) is considered a comment and will be ignored.
+# The format is:
+# TAG = value [value, ...]
+# For lists items can also be appended using:
+# TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (" ").
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# This tag specifies the encoding used for all characters in the config file
+# that follow. The default is UTF-8 which is also the encoding used for all
+# text before the first occurrence of this tag. Doxygen uses libiconv (or the
+# iconv built into libc) for the transcoding. See
+# http://www.gnu.org/software/libiconv for the list of possible encodings.
+
+DOXYFILE_ENCODING = UTF-8
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded
+# by quotes) that should identify the project.
+
+PROJECT_NAME = corosync
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number.
+# This could be handy for archiving the generated documentation or
+# if some version control system is used.
+
+PROJECT_NUMBER = @VERSION@
+
+# Using the PROJECT_BRIEF tag one can provide an optional one line description for a project that appears at the top of each page and should give viewer a quick idea about the purpose of the project. Keep the description short.
+
+PROJECT_BRIEF =
+
+# With the PROJECT_LOGO tag one can specify an logo or icon that is
+# included in the documentation. The maximum height of the logo should not
+# exceed 55 pixels and the maximum width should not exceed 200 pixels.
+# Doxygen will copy the logo to the output directory.
+
+PROJECT_LOGO =
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
+# base path where the generated documentation will be put.
+# If a relative path is entered, it will be relative to the location
+# where doxygen was started. If left blank the current directory will be used.
+
+OUTPUT_DIRECTORY = doc/api
+
+# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create
+# 4096 sub-directories (in 2 levels) under the output directory of each output
+# format and will distribute the generated files over these directories.
+# Enabling this option can be useful when feeding doxygen a huge amount of
+# source files, where putting all generated files in the same directory would
+# otherwise cause performance problems for the file system.
+
+CREATE_SUBDIRS = NO
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all
+# documentation generated by doxygen is written. Doxygen will use this
+# information to generate all constant output in the proper language.
+# The default language is English, other supported languages are:
+# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional,
+# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German,
+# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English
+# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian,
+# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak,
+# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese.
+
+OUTPUT_LANGUAGE = English
+
+# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will
+# include brief member descriptions after the members that are listed in
+# the file and class documentation (similar to JavaDoc).
+# Set to NO to disable this.
+
+BRIEF_MEMBER_DESC = YES
+
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend
+# the brief description of a member or function before the detailed description.
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
+# brief descriptions will be completely suppressed.
+
+REPEAT_BRIEF = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator
+# that is used to form the text in various listings. Each string
+# in this list, if found as the leading text of the brief description, will be
+# stripped from the text and the result after processing the whole list, is
+# used as the annotated text. Otherwise, the brief description is used as-is.
+# If left blank, the following values are used ("$name" is automatically
+# replaced with the name of the entity): "The $name class" "The $name widget"
+# "The $name file" "is" "provides" "specifies" "contains"
+# "represents" "a" "an" "the"
+
+ABBREVIATE_BRIEF =
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
+# Doxygen will generate a detailed section even if there is only a brief
+# description.
+
+ALWAYS_DETAILED_SEC = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
+# inherited members of a class in the documentation of that class as if those
+# members were ordinary class members. Constructors, destructors and assignment
+# operators of the base classes will not be shown.
+
+INLINE_INHERITED_MEMB = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full
+# path before files name in the file list and in the header files. If set
+# to NO the shortest path that makes the file name unique will be used.
+
+FULL_PATH_NAMES = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag
+# can be used to strip a user-defined part of the path. Stripping is
+# only done if one of the specified strings matches the left-hand part of
+# the path. The tag can be used to show relative paths in the file list.
+# If left blank the directory from which doxygen is run is used as the
+# path to strip.
+
+STRIP_FROM_PATH =
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of
+# the path mentioned in the documentation of a class, which tells
+# the reader which header file to include in order to use a class.
+# If left blank only the name of the header file containing the class
+# definition is used. Otherwise one should specify the include paths that
+# are normally passed to the compiler using the -I flag.
+
+STRIP_FROM_INC_PATH =
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter
+# (but less readable) file names. This can be useful if your file system
+# doesn't support long names like on DOS, Mac, or CD-ROM.
+
+SHORT_NAMES = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
+# will interpret the first line (until the first dot) of a JavaDoc-style
+# comment as the brief description. If set to NO, the JavaDoc
+# comments will behave just like regular Qt-style comments
+# (thus requiring an explicit @brief command for a brief description.)
+
+JAVADOC_AUTOBRIEF = YES
+
+# If the QT_AUTOBRIEF tag is set to YES then Doxygen will
+# interpret the first line (until the first dot) of a Qt-style
+# comment as the brief description. If set to NO, the comments
+# will behave just like regular Qt-style comments (thus requiring
+# an explicit \brief command for a brief description.)
+
+QT_AUTOBRIEF = NO
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen
+# treat a multi-line C++ special comment block (i.e. a block of //! or ///
+# comments) as a brief description. This used to be the default behaviour.
+# The new default is to treat a multi-line C++ comment block as a detailed
+# description. Set this tag to YES if you prefer the old behaviour instead.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
+# member inherits the documentation from any documented member that it
+# re-implements.
+
+INHERIT_DOCS = YES
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce
+# a new page for each member. If set to NO, the documentation of a member will
+# be part of the file/class/namespace that contains it.
+
+SEPARATE_MEMBER_PAGES = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab.
+# Doxygen uses this value to replace tabs by spaces in code fragments.
+
+TAB_SIZE = 8
+
+# This tag can be used to specify a number of aliases that acts
+# as commands in the documentation. An alias has the form "name=value".
+# For example adding "sideeffect=\par Side Effects:\n" will allow you to
+# put the command \sideeffect (or @sideeffect) in the documentation, which
+# will result in a user-defined paragraph with heading "Side Effects:".
+# You can put \n's in the value part of an alias to insert newlines.
+
+ALIASES =
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C
+# sources only. Doxygen will then generate output that is more tailored for C.
+# For instance, some of the names that are used will be different. The list
+# of all members will be omitted, etc.
+
+OPTIMIZE_OUTPUT_FOR_C = YES
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java
+# sources only. Doxygen will then generate output that is more tailored for
+# Java. For instance, namespaces will be presented as packages, qualified
+# scopes will look different, etc.
+
+OPTIMIZE_OUTPUT_JAVA = NO
+
+# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran
+# sources only. Doxygen will then generate output that is more tailored for
+# Fortran.
+
+OPTIMIZE_FOR_FORTRAN = NO
+
+# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL
+# sources. Doxygen will then generate output that is tailored for
+# VHDL.
+
+OPTIMIZE_OUTPUT_VHDL = NO
+
+# Doxygen selects the parser to use depending on the extension of the files it
+# parses. With this tag you can assign which parser to use for a given extension.
+# Doxygen has a built-in mapping, but you can override or extend it using this
+# tag. The format is ext=language, where ext is a file extension, and language
+# is one of the parsers supported by doxygen: IDL, Java, Javascript, CSharp, C,
+# C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, C++. For instance to make
+# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C
+# (default is Fortran), use: inc=Fortran f=C. Note that for custom extensions
+# you also need to set FILE_PATTERNS otherwise the files are not read by doxygen.
+
+EXTENSION_MAPPING =
+
+# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want
+# to include (a tag file for) the STL sources as input, then you should
+# set this tag to YES in order to let doxygen match functions declarations and
+# definitions whose arguments contain STL classes (e.g. func(std::string); v.s.
+# func(std::string) {}). This also makes the inheritance and collaboration
+# diagrams that involve STL classes more complete and accurate.
+
+BUILTIN_STL_SUPPORT = NO
+
+# If you use Microsoft's C++/CLI language, you should set this option to YES to
+# enable parsing support.
+
+CPP_CLI_SUPPORT = NO
+
+# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only.
+# Doxygen will parse them like normal C++ but will assume all classes use public
+# instead of private inheritance when no explicit protection keyword is present.
+
+SIP_SUPPORT = NO
+
+# For Microsoft's IDL there are propget and propput attributes to indicate getter
+# and setter methods for a property. Setting this option to YES (the default)
+# will make doxygen replace the get and set methods by a property in the
+# documentation. This will only work if the methods are indeed getting or
+# setting a simple type. If this is not the case, or you want to show the
+# methods anyway, you should set this option to NO.
+
+IDL_PROPERTY_SUPPORT = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
+# tag is set to YES, then doxygen will reuse the documentation of the first
+# member in the group (if any) for the other members of the group. By default
+# all members of a group must be documented explicitly.
+
+DISTRIBUTE_GROUP_DOC = NO
+
+# Set the SUBGROUPING tag to YES (the default) to allow class member groups of
+# the same type (for instance a group of public functions) to be put as a
+# subgroup of that type (e.g. under the Public Functions section). Set it to
+# NO to prevent subgrouping. Alternatively, this can be done per class using
+# the \nosubgrouping command.
+
+SUBGROUPING = YES
+
+# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum
+# is documented as struct, union, or enum with the name of the typedef. So
+# typedef struct TypeS {} TypeT, will appear in the documentation as a struct
+# with name TypeT. When disabled the typedef will appear as a member of a file,
+# namespace, or class. And the struct will be named TypeS. This can typically
+# be useful for C code in case the coding convention dictates that all compound
+# types are typedef'ed and only the typedef is referenced, never the tag name.
+
+TYPEDEF_HIDES_STRUCT = NO
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
+# documentation are documented, even if no documentation was available.
+# Private class members and static file members will be hidden unless
+# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
+
+EXTRACT_ALL = YES
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
+# will be included in the documentation.
+
+EXTRACT_PRIVATE = NO
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file
+# will be included in the documentation.
+
+EXTRACT_STATIC = NO
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs)
+# defined locally in source files will be included in the documentation.
+# If set to NO only classes defined in header files are included.
+
+EXTRACT_LOCAL_CLASSES = YES
+
+# This flag is only useful for Objective-C code. When set to YES local
+# methods, which are defined in the implementation section but not in
+# the interface are included in the documentation.
+# If set to NO (the default) only methods in the interface are included.
+
+EXTRACT_LOCAL_METHODS = NO
+
+# If this flag is set to YES, the members of anonymous namespaces will be
+# extracted and appear in the documentation as a namespace called
+# 'anonymous_namespace{file}', where file will be replaced with the base
+# name of the file that contains the anonymous namespace. By default
+# anonymous namespaces are hidden.
+
+EXTRACT_ANON_NSPACES = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
+# undocumented members of documented classes, files or namespaces.
+# If set to NO (the default) these members will be included in the
+# various overviews, but no documentation section is generated.
+# This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_MEMBERS = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all
+# undocumented classes that are normally visible in the class hierarchy.
+# If set to NO (the default) these classes will be included in the various
+# overviews. This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_CLASSES = NO
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all
+# friend (class|struct|union) declarations.
+# If set to NO (the default) these declarations will be included in the
+# documentation.
+
+HIDE_FRIEND_COMPOUNDS = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any
+# documentation blocks found inside the body of a function.
+# If set to NO (the default) these blocks will be appended to the
+# function's detailed documentation block.
+
+HIDE_IN_BODY_DOCS = NO
+
+# The INTERNAL_DOCS tag determines if documentation
+# that is typed after a \internal command is included. If the tag is set
+# to NO (the default) then the documentation will be excluded.
+# Set it to YES to include the internal documentation.
+
+INTERNAL_DOCS = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate
+# file names in lower-case letters. If set to YES upper-case letters are also
+# allowed. This is useful if you have classes or files whose names only differ
+# in case and if your file system supports case sensitive file names. Windows
+# and Mac users are advised to set this option to NO.
+
+CASE_SENSE_NAMES = YES
+
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen
+# will show members with their full class and namespace scopes in the
+# documentation. If set to YES the scope will be hidden.
+
+HIDE_SCOPE_NAMES = NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen
+# will put a list of the files that are included by a file in the documentation
+# of that file.
+
+SHOW_INCLUDE_FILES = YES
+
+# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen
+# will list include files with double quotes in the documentation
+# rather than with sharp brackets.
+
+FORCE_LOCAL_INCLUDES = NO
+
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline]
+# is inserted in the documentation for inline members.
+
+INLINE_INFO = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen
+# will sort the (detailed) documentation of file and class members
+# alphabetically by member name. If set to NO the members will appear in
+# declaration order.
+
+SORT_MEMBER_DOCS = YES
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the
+# brief documentation of file, namespace and class members alphabetically
+# by member name. If set to NO (the default) the members will appear in
+# declaration order.
+
+SORT_BRIEF_DOCS = NO
+
+# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen
+# will sort the (brief and detailed) documentation of class members so that
+# constructors and destructors are listed first. If set to NO (the default)
+# the constructors will appear in the respective orders defined by
+# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS.
+# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO
+# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO.
+
+SORT_MEMBERS_CTORS_1ST = NO
+
+# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the
+# hierarchy of group names into alphabetical order. If set to NO (the default)
+# the group names will appear in their defined order.
+
+SORT_GROUP_NAMES = NO
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be
+# sorted by fully-qualified names, including namespaces. If set to
+# NO (the default), the class list will be sorted only by class name,
+# not including the namespace part.
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
+# Note: This option applies only to the class list, not to the
+# alphabetical list.
+
+SORT_BY_SCOPE_NAME = NO
+
+# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper type resolution of all parameters of a function it will reject a
+# match between the prototype and the implementation of a member function even if there is only one candidate or it is obvious which candidate to choose by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen
+# will still accept a match between prototype and implementation in such cases.
+
+STRICT_PROTO_MATCHING = NO
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or
+# disable (NO) the todo list. This list is created by putting \todo
+# commands in the documentation.
+
+GENERATE_TODOLIST = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or
+# disable (NO) the test list. This list is created by putting \test
+# commands in the documentation.
+
+GENERATE_TESTLIST = YES
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or
+# disable (NO) the bug list. This list is created by putting \bug
+# commands in the documentation.
+
+GENERATE_BUGLIST = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or
+# disable (NO) the deprecated list. This list is created by putting
+# \deprecated commands in the documentation.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional
+# documentation sections, marked by \if sectionname ... \endif.
+
+ENABLED_SECTIONS =
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines
+# the initial value of a variable or macro consists of for it to appear in
+# the documentation. If the initializer consists of more lines than specified
+# here it will be hidden. Use a value of 0 to hide initializers completely.
+# The appearance of the initializer of individual variables and macros in the
+# documentation can be controlled using \showinitializer or \hideinitializer
+# command in the documentation regardless of this setting.
+
+MAX_INITIALIZER_LINES = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated
+# at the bottom of the documentation of classes and structs. If set to YES the
+# list will mention the files that were used to generate the documentation.
+
+SHOW_USED_FILES = YES
+
+# Set the SHOW_FILES tag to NO to disable the generation of the Files page.
+# This will remove the Files entry from the Quick Index and from the
+# Folder Tree View (if specified). The default is YES.
+
+SHOW_FILES = YES
+
+# Set the SHOW_NAMESPACES tag to NO to disable the generation of the
+# Namespaces page.
+# This will remove the Namespaces entry from the Quick Index
+# and from the Folder Tree View (if specified). The default is YES.
+
+SHOW_NAMESPACES = YES
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that
+# doxygen should invoke to get the current version for each file (typically from
+# the version control system). Doxygen will invoke the program by executing (via
+# popen()) the command <command> <input-file>, where <command> is the value of
+# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file
+# provided by doxygen. Whatever the program writes to standard output
+# is used as the file version. See the manual for examples.
+
+FILE_VERSION_FILTER =
+
+# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed
+# by doxygen. The layout file controls the global structure of the generated
+# output files in an output format independent way. The create the layout file
+# that represents doxygen's defaults, run doxygen with the -l option.
+# You can optionally specify a file name after the option, if omitted
+# DoxygenLayout.xml will be used as the name of the layout file.
+
+LAYOUT_FILE =
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated
+# by doxygen. Possible values are YES and NO. If left blank NO is used.
+
+QUIET = YES
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are
+# generated by doxygen. Possible values are YES and NO. If left blank
+# NO is used.
+
+WARNINGS = YES
+
+# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings
+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will
+# automatically be disabled.
+
+WARN_IF_UNDOCUMENTED = NO
+
+# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for
+# potential errors in the documentation, such as not documenting some
+# parameters in a documented function, or documenting parameters that
+# don't exist or using markup commands wrongly.
+
+WARN_IF_DOC_ERROR = YES
+
+# The WARN_NO_PARAMDOC option can be enabled to get warnings for
+# functions that are documented, but have no documentation for their parameters
+# or return value. If set to NO (the default) doxygen will only warn about
+# wrong or incomplete parameter documentation, but not about the absence of
+# documentation.
+
+WARN_NO_PARAMDOC = NO
+
+# The WARN_FORMAT tag determines the format of the warning messages that
+# doxygen can produce. The string should contain the $file, $line, and $text
+# tags, which will be replaced by the file and line number from which the
+# warning originated and the warning text. Optionally the format may contain
+# $version, which will be replaced by the version of the file (if it could
+# be obtained via FILE_VERSION_FILTER)
+
+WARN_FORMAT =
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning
+# and error messages should be written. If left blank the output is written
+# to stderr.
+
+WARN_LOGFILE =
+
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag can be used to specify the files and/or directories that contain
+# documented source files. You may enter file names like "myfile.cpp" or
+# directories like "/usr/src/myproject". Separate the files or directories
+# with spaces.
+
+INPUT = lib \
+ include \
+ exec
+
+# This tag can be used to specify the character encoding of the source files
+# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
+# also the default input encoding. Doxygen uses libiconv (or the iconv built
+# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for
+# the list of possible encodings.
+
+INPUT_ENCODING = UTF-8
+
+# If the value of the INPUT tag contains directories, you can use the
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank the following patterns are tested:
+# *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh
+# *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py
+# *.f90 *.f *.for *.vhd *.vhdl
+
+FILE_PATTERNS = *.c \
+ *.h
+
+# The RECURSIVE tag can be used to turn specify whether or not subdirectories
+# should be searched for input files as well. Possible values are YES and NO.
+# If left blank NO is used.
+
+RECURSIVE = YES
+
+# The EXCLUDE tag can be used to specify files and/or directories that should
+# excluded from the INPUT source files. This way you can easily exclude a
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+
+EXCLUDE =
+
+# The EXCLUDE_SYMLINKS tag can be used select whether or not files or
+# directories that are symbolic links (a Unix file system feature) are excluded
+# from the input.
+
+EXCLUDE_SYMLINKS = NO
+
+# If the value of the INPUT tag contains directories, you can use the
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
+# certain files from those directories. Note that the wildcards are matched
+# against the file with absolute path, so to exclude all test directories
+# for example use the pattern */test/*
+
+EXCLUDE_PATTERNS =
+
+# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
+# (namespaces, classes, functions, etc.) that should be excluded from the
+# output. The symbol name can be a fully qualified name, a word, or if the
+# wildcard * is used, a substring. Examples: ANamespace, AClass,
+# AClass::ANamespace, ANamespace::*Test
+
+EXCLUDE_SYMBOLS =
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or
+# directories that contain example code fragments that are included (see
+# the \include command).
+
+EXAMPLE_PATH =
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank all files are included.
+
+EXAMPLE_PATTERNS =
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
+# searched for input files to be used with the \include or \dontinclude
+# commands irrespective of the value of the RECURSIVE tag.
+# Possible values are YES and NO. If left blank NO is used.
+
+EXAMPLE_RECURSIVE = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or
+# directories that contain image that are included in the documentation (see
+# the \image command).
+
+IMAGE_PATH =
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should
+# invoke to filter for each input file. Doxygen will invoke the filter program
+# by executing (via popen()) the command <filter> <input-file>, where <filter>
+# is the value of the INPUT_FILTER tag, and <input-file> is the name of an
+# input file. Doxygen will then use the output that the filter program writes
+# to standard output.
+# If FILTER_PATTERNS is specified, this tag will be
+# ignored.
+
+INPUT_FILTER =
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
+# basis.
+# Doxygen will compare the file name with each pattern and apply the
+# filter if there is a match.
+# The filters are a list of the form:
+# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further
+# info on how filters are used. If FILTER_PATTERNS is empty or if
+# non of the patterns match the file name, INPUT_FILTER is applied.
+
+FILTER_PATTERNS =
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
+# INPUT_FILTER) will be used to filter the input files when producing source
+# files to browse (i.e. when SOURCE_BROWSER is set to YES).
+
+FILTER_SOURCE_FILES = NO
+
+# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file
+# pattern. A pattern will override the setting for FILTER_PATTERN (if any)
+# and it is also possible to disable source filtering for a specific pattern
+# using *.ext= (so without naming a filter). This option only has effect when
+# FILTER_SOURCE_FILES is enabled.
+
+FILTER_SOURCE_PATTERNS =
+
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will
+# be generated. Documented entities will be cross-referenced with these sources.
+# Note: To get rid of all source code in the generated output, make sure also
+# VERBATIM_HEADERS is set to NO.
+
+SOURCE_BROWSER = YES
+
+# Setting the INLINE_SOURCES tag to YES will include the body
+# of functions and classes directly in the documentation.
+
+INLINE_SOURCES = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct
+# doxygen to hide any special comment blocks from generated source code
+# fragments. Normal C and C++ comments will always remain visible.
+
+STRIP_CODE_COMMENTS = YES
+
+# If the REFERENCED_BY_RELATION tag is set to YES
+# then for each documented function all documented
+# functions referencing it will be listed.
+
+REFERENCED_BY_RELATION = YES
+
+# If the REFERENCES_RELATION tag is set to YES
+# then for each documented function all documented entities
+# called/used by that function will be listed.
+
+REFERENCES_RELATION = YES
+
+# If the REFERENCES_LINK_SOURCE tag is set to YES (the default)
+# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from
+# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will
+# link to the source code.
+# Otherwise they will link to the documentation.
+
+REFERENCES_LINK_SOURCE = YES
+
+# If the USE_HTAGS tag is set to YES then the references to source code
+# will point to the HTML generated by the htags(1) tool instead of doxygen
+# built-in source browser. The htags tool is part of GNU's global source
+# tagging system (see http://www.gnu.org/software/global/global.html). You
+# will need version 4.8.6 or higher.
+
+USE_HTAGS = NO
+
+# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen
+# will generate a verbatim copy of the header file for each class for
+# which an include is specified. Set to NO to disable this.
+
+VERBATIM_HEADERS = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index
+# of all compounds will be generated. Enable this if the project
+# contains a lot of classes, structs, unions or interfaces.
+
+ALPHABETICAL_INDEX = NO
+
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns
+# in which this list will be split (can be a number in the range [1..20])
+
+COLS_IN_ALPHA_INDEX = 5
+
+# In case all classes in a project start with a common prefix, all
+# classes will be put under the same header in the alphabetical index.
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that
+# should be ignored while generating the index headers.
+
+IGNORE_PREFIX =
+
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will
+# generate HTML output.
+
+GENERATE_HTML = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `html' will be used as the default path.
+
+HTML_OUTPUT =
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for
+# each generated HTML page (for example: .htm,.php,.asp). If it is left blank
+# doxygen will generate files with .html extension.
+
+HTML_FILE_EXTENSION = .html
+
+# The HTML_HEADER tag can be used to specify a personal HTML header for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard header.
+
+HTML_HEADER =
+
+# The HTML_FOOTER tag can be used to specify a personal HTML footer for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard footer.
+
+HTML_FOOTER =
+
+# If the HTML_TIMESTAMP tag is set to YES then the generated HTML
+# documentation will contain the timesstamp.
+
+HTML_TIMESTAMP = NO
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading
+# style sheet that is used by each HTML page. It can be used to
+# fine-tune the look of the HTML output. If the tag is left blank doxygen
+# will generate a default style sheet. Note that doxygen will try to copy
+# the style sheet file to the HTML output directory, so don't put your own
+# stylesheet in the HTML output directory as well, or it will be erased!
+
+HTML_STYLESHEET =
+
+# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output.
+# Doxygen will adjust the colors in the stylesheet and background images
+# according to this color. Hue is specified as an angle on a colorwheel,
+# see http://en.wikipedia.org/wiki/Hue for more information.
+# For instance the value 0 represents red, 60 is yellow, 120 is green,
+# 180 is cyan, 240 is blue, 300 purple, and 360 is red again.
+# The allowed range is 0 to 359.
+
+HTML_COLORSTYLE_HUE = 220
+
+# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of
+# the colors in the HTML output. For a value of 0 the output will use
+# grayscales only. A value of 255 will produce the most vivid colors.
+
+HTML_COLORSTYLE_SAT = 100
+
+# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to
+# the luminance component of the colors in the HTML output. Values below
+# 100 gradually make the output lighter, whereas values above 100 make
+# the output darker. The value divided by 100 is the actual gamma applied,
+# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2,
+# and 100 does not change the gamma.
+
+HTML_COLORSTYLE_GAMMA = 80
+
+# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML
+# page will contain the date and time when the page was generated. Setting
+# this to NO can help when comparing the output of multiple runs.
+
+HTML_TIMESTAMP = YES
+
+# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
+# documentation will contain sections that can be hidden and shown after the
+# page has loaded. For this to work a browser that supports
+# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox
+# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari).
+
+HTML_DYNAMIC_SECTIONS = NO
+
+# If the GENERATE_DOCSET tag is set to YES, additional index files
+# will be generated that can be used as input for Apple's Xcode 3
+# integrated development environment, introduced with OSX 10.5 (Leopard).
+# To create a documentation set, doxygen will generate a Makefile in the
+# HTML output directory. Running make will produce the docset in that
+# directory and running "make install" will install the docset in
+# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find
+# it at startup.
+# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html
+# for more information.
+
+GENERATE_DOCSET = NO
+
+# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the
+# feed. A documentation feed provides an umbrella under which multiple
+# documentation sets from a single provider (such as a company or product suite)
+# can be grouped.
+
+DOCSET_FEEDNAME = "Doxygen generated docs"
+
+# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that
+# should uniquely identify the documentation set bundle. This should be a
+# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen
+# will append .docset to the name.
+
+DOCSET_BUNDLE_ID = org.doxygen.Project
+
+# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely identify
+# the documentation publisher. This should be a reverse domain-name style
+# string, e.g. com.mycompany.MyDocSet.documentation.
+
+DOCSET_PUBLISHER_ID = org.doxygen.Publisher
+
+# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher.
+
+DOCSET_PUBLISHER_NAME = Publisher
+
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files
+# will be generated that can be used as input for tools like the
+# Microsoft HTML help workshop to generate a compiled HTML help file (.chm)
+# of the generated HTML documentation.
+
+GENERATE_HTMLHELP = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can
+# be used to specify the file name of the resulting .chm file. You
+# can add a path in front of the file if the result should not be
+# written to the html output directory.
+
+CHM_FILE =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can
+# be used to specify the location (absolute path including file name) of
+# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run
+# the HTML help compiler on the generated index.hhp.
+
+HHC_LOCATION =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag
+# controls if a separate .chi index file is generated (YES) or that
+# it should be included in the master .chm file (NO).
+
+GENERATE_CHI = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING
+# is used to encode HtmlHelp index (hhk), content (hhc) and project file
+# content.
+
+CHM_INDEX_ENCODING =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag
+# controls whether a binary table of contents is generated (YES) or a
+# normal table of contents (NO) in the .chm file.
+
+BINARY_TOC = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members
+# to the contents of the HTML help documentation and to the tree view.
+
+TOC_EXPAND = NO
+
+# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and
+# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated
+# that can be used as input for Qt's qhelpgenerator to generate a
+# Qt Compressed Help (.qch) of the generated HTML documentation.
+
+GENERATE_QHP = NO
+
+# If the QHG_LOCATION tag is specified, the QCH_FILE tag can
+# be used to specify the file name of the resulting .qch file.
+# The path specified is relative to the HTML output folder.
+
+QCH_FILE =
+
+# The QHP_NAMESPACE tag specifies the namespace to use when generating
+# Qt Help Project output. For more information please see
+# http://doc.trolltech.com/qthelpproject.html#namespace
+
+QHP_NAMESPACE = org.doxygen.Project
+
+# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating
+# Qt Help Project output. For more information please see
+# http://doc.trolltech.com/qthelpproject.html#virtual-folders
+
+QHP_VIRTUAL_FOLDER = doc
+
+# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to
+# add. For more information please see
+# http://doc.trolltech.com/qthelpproject.html#custom-filters
+
+QHP_CUST_FILTER_NAME =
+
+# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the
+# custom filter to add. For more information please see
+# <a href="http://doc.trolltech.com/qthelpproject.html#custom-filters">
+# Qt Help Project / Custom Filters</a>.
+
+QHP_CUST_FILTER_ATTRS =
+
+# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this
+# project's
+# filter section matches.
+# <a href="http://doc.trolltech.com/qthelpproject.html#filter-attributes">
+# Qt Help Project / Filter Attributes</a>.
+
+QHP_SECT_FILTER_ATTRS =
+
+# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can
+# be used to specify the location of Qt's qhelpgenerator.
+# If non-empty doxygen will try to run qhelpgenerator on the generated
+# .qhp file.
+
+QHG_LOCATION =
+
+# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files
+# will be generated, which together with the HTML files, form an Eclipse help
+# plugin. To install this plugin and make it available under the help contents
+# menu in Eclipse, the contents of the directory containing the HTML and XML
+# files needs to be copied into the plugins directory of eclipse. The name of
+# the directory within the plugins directory should be the same as
+# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before
+# the help appears.
+
+GENERATE_ECLIPSEHELP = NO
+
+# A unique identifier for the eclipse help plugin. When installing the plugin
+# the directory name containing the HTML and XML files should also have
+# this name.
+
+ECLIPSE_DOC_ID = org.doxygen.Project
+
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index at
+# top of each HTML page. The value NO (the default) enables the index and
+# the value YES disables it.
+
+DISABLE_INDEX = NO
+
+# This tag can be used to set the number of enum values (range [0,1..20])
+# that doxygen will group on one line in the generated HTML documentation.
+# Note that a value of 0 will completely suppress the enum values from appearing in the overview section.
+
+ENUM_VALUES_PER_LINE = 4
+
+# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
+# structure should be generated to display hierarchical information.
+# If the tag value is set to YES, a side panel will be generated
+# containing a tree-like index structure (just like the one that
+# is generated for HTML Help). For this to work a browser that supports
+# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser).
+# Windows users are probably better off using the HTML help feature.
+
+GENERATE_TREEVIEW = NO
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be
+# used to set the initial width (in pixels) of the frame in which the tree
+# is shown.
+
+TREEVIEW_WIDTH = 250
+
+# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open
+# links to external symbols imported via tag files in a separate window.
+
+EXT_LINKS_IN_WINDOW = NO
+
+# Use this tag to change the font size of Latex formulas included
+# as images in the HTML documentation. The default is 10. Note that
+# when you change the font size after a successful doxygen run you need
+# to manually remove any form_*.png images from the HTML output directory
+# to force them to be regenerated.
+
+FORMULA_FONTSIZE = 10
+
+# Use the FORMULA_TRANPARENT tag to determine whether or not the images
+# generated for formulas are transparent PNGs. Transparent PNGs are
+# not supported properly for IE 6.0, but are supported on all modern browsers.
+# Note that when changing this option you need to delete any form_*.png files
+# in the HTML output before the changes have effect.
+
+FORMULA_TRANSPARENT = YES
+
+# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax
+# (see http://www.mathjax.org) which uses client side Javascript for the
+# rendering instead of using prerendered bitmaps. Use this if you do not
+# have LaTeX installed or if you want to formulas look prettier in the HTML
+# output. When enabled you also need to install MathJax separately and
+# configure the path to it using the MATHJAX_RELPATH option.
+
+USE_MATHJAX = NO
+
+# When MathJax is enabled you need to specify the location relative to the
+# HTML output directory using the MATHJAX_RELPATH option. The destination
+# directory should contain the MathJax.js script. For instance, if the mathjax
+# directory is located at the same level as the HTML output directory, then
+# MATHJAX_RELPATH should be ../mathjax. The default value points to the mathjax.org site, so you can quickly see the result without installing
+# MathJax, but it is strongly recommended to install a local copy of MathJax
+# before deployment.
+
+MATHJAX_RELPATH = http://www.mathjax.org/mathjax
+
+# When the SEARCHENGINE tag is enabled doxygen will generate a search box
+# for the HTML output. The underlying search engine uses javascript
+# and DHTML and should work on any modern browser. Note that when using
+# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets
+# (GENERATE_DOCSET) there is already a search function so this one should
+# typically be disabled. For large projects the javascript based search engine
+# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution.
+
+SEARCHENGINE = NO
+
+# When the SERVER_BASED_SEARCH tag is enabled the search engine will be
+# implemented using a PHP enabled web server instead of at the web client
+# using Javascript. Doxygen will generate the search PHP script and index
+# file to put on the web server. The advantage of the server
+# based approach is that it scales better to large projects and allows
+# full text search. The disadvantages are that it is more difficult to setup
+# and does not have live searching capabilities.
+
+SERVER_BASED_SEARCH = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
+# generate Latex output.
+
+GENERATE_LATEX = NO
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `latex' will be used as the default path.
+
+LATEX_OUTPUT =
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
+# invoked. If left blank `latex' will be used as the default command name.
+# Note that when enabling USE_PDFLATEX this option is only used for
+# generating bitmaps for formulas in the HTML output, but not in the
+# Makefile that is written to the output directory.
+
+LATEX_CMD_NAME = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to
+# generate index for LaTeX. If left blank `makeindex' will be used as the
+# default command name.
+
+MAKEINDEX_CMD_NAME = makeindex
+
+# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact
+# LaTeX documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_LATEX = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used
+# by the printer. Possible values are: a4, letter, legal and
+# executive. If left blank a4wide will be used.
+
+PAPER_TYPE = a4wide
+
+# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX
+# packages that should be included in the LaTeX output.
+
+EXTRA_PACKAGES =
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for
+# the generated latex document. The header should contain everything until
+# the first chapter. If it is left blank doxygen will generate a
+# standard header. Notice: only use this tag if you know what you are doing!
+
+LATEX_HEADER =
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated
+# is prepared for conversion to pdf (using ps2pdf). The pdf file will
+# contain links (just like the HTML output) instead of page references
+# This makes the output suitable for online browsing using a pdf viewer.
+
+PDF_HYPERLINKS = NO
+
+# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of
+# plain latex in the generated Makefile. Set this option to YES to get a
+# higher quality PDF documentation.
+
+USE_PDFLATEX = NO
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode.
+# command to the generated LaTeX files. This will instruct LaTeX to keep
+# running if errors occur, instead of asking the user for help.
+# This option is also used when generating formulas in HTML.
+
+LATEX_BATCHMODE = NO
+
+# If LATEX_HIDE_INDICES is set to YES then doxygen will not
+# include the index chapters (such as File Index, Compound Index, etc.)
+# in the output.
+
+LATEX_HIDE_INDICES = NO
+
+# If LATEX_SOURCE_CODE is set to YES then doxygen will include
+# source code with syntax highlighting in the LaTeX output.
+# Note that which sources are shown also depends on other settings
+# such as SOURCE_BROWSER.
+
+LATEX_SOURCE_CODE = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output
+# The RTF output is optimized for Word 97 and may not look very pretty with
+# other RTF readers or editors.
+
+GENERATE_RTF = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `rtf' will be used as the default path.
+
+RTF_OUTPUT =
+
+# If the COMPACT_RTF tag is set to YES Doxygen generates more compact
+# RTF documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_RTF = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated
+# will contain hyperlink fields. The RTF file will
+# contain links (just like the HTML output) instead of page references.
+# This makes the output suitable for online browsing using WORD or other
+# programs which support those fields.
+# Note: wordpad (write) and others do not support links.
+
+RTF_HYPERLINKS = NO
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's
+# config file, i.e. a series of assignments. You only have to provide
+# replacements, missing definitions are set to their default value.
+
+RTF_STYLESHEET_FILE =
+
+# Set optional variables used in the generation of an rtf document.
+# Syntax is similar to doxygen's config file.
+
+RTF_EXTENSIONS_FILE =
+
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES (the default) Doxygen will
+# generate man pages
+
+GENERATE_MAN = YES
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `man' will be used as the default path.
+
+MAN_OUTPUT = man
+
+# The MAN_EXTENSION tag determines the extension that is added to
+# the generated man pages (default is the subroutine's section .3)
+
+MAN_EXTENSION = .3
+
+# If the MAN_LINKS tag is set to YES and Doxygen generates man output,
+# then it will generate one additional man file for each entity
+# documented in the real man page(s). These additional files
+# only source the real man page, but without them the man command
+# would be unable to find the correct page. The default is NO.
+
+MAN_LINKS = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES Doxygen will
+# generate an XML file that captures the structure of
+# the code including all documentation.
+
+GENERATE_XML = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `xml' will be used as the default path.
+
+XML_OUTPUT = xml
+
+# If the XML_PROGRAMLISTING tag is set to YES Doxygen will
+# dump the program listings (including syntax highlighting
+# and cross-referencing information) to the XML output. Note that
+# enabling this will significantly increase the size of the XML output.
+
+XML_PROGRAMLISTING = YES
+
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will
+# generate an AutoGen Definitions (see autogen.sf.net) file
+# that captures the structure of the code including all
+# documentation. Note that this feature is still experimental
+# and incomplete at the moment.
+
+GENERATE_AUTOGEN_DEF = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES Doxygen will
+# generate a Perl module file that captures the structure of
+# the code including all documentation. Note that this
+# feature is still experimental and incomplete at the
+# moment.
+
+GENERATE_PERLMOD = NO
+
+# If the PERLMOD_LATEX tag is set to YES Doxygen will generate
+# the necessary Makefile rules, Perl scripts and LaTeX code to be able
+# to generate PDF and DVI output from the Perl module output.
+
+PERLMOD_LATEX = NO
+
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be
+# nicely formatted so it can be parsed by a human reader.
+# This is useful
+# if you want to understand what is going on.
+# On the other hand, if this
+# tag is set to NO the size of the Perl module output will be much smaller
+# and Perl will parse it just the same.
+
+PERLMOD_PRETTY = YES
+
+# The names of the make variables in the generated doxyrules.make file
+# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX.
+# This is useful so different doxyrules.make files included by the same
+# Makefile don't overwrite each other's variables.
+
+PERLMOD_MAKEVAR_PREFIX =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will
+# evaluate all C-preprocessor directives found in the sources and include
+# files.
+
+ENABLE_PREPROCESSING = YES
+
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro
+# names in the source code. If set to NO (the default) only conditional
+# compilation will be performed. Macro expansion can be done in a controlled
+# way by setting EXPAND_ONLY_PREDEF to YES.
+
+MACRO_EXPANSION = YES
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES
+# then the macro expansion is limited to the macros specified with the
+# PREDEFINED and EXPAND_AS_DEFINED tags.
+
+EXPAND_ONLY_PREDEF = YES
+
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files
+# in the INCLUDE_PATH (see below) will be search if a #include is found.
+
+SEARCH_INCLUDES = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that
+# contain include files that are not input files but should be processed by
+# the preprocessor.
+
+INCLUDE_PATH = include
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
+# patterns (like *.h and *.hpp) to filter out the header-files in the
+# directories. If left blank, the patterns specified with FILE_PATTERNS will
+# be used.
+
+INCLUDE_FILE_PATTERNS = *.h
+
+# The PREDEFINED tag can be used to specify one or more macro names that
+# are defined before the preprocessor is started (similar to the -D option of
+# gcc). The argument of the tag is a list of macros of the form: name
+# or name=definition (no spaces). If the definition and the = are
+# omitted =1 is assumed. To prevent a macro definition from being
+# undefined via #undef or recursively expanded use the := operator
+# instead of the = operator.
+
+PREDEFINED = "COROSYNC_BEGIN_DECLS=" \
+ "COROSYNC_END_DECLS=" \
+ "DOXYGEN_SHOULD_SKIP_THIS"
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
+# this tag can be used to specify a list of macro names that should be expanded.
+# The macro definition that is found in the sources will be used.
+# Use the PREDEFINED tag if you want to use a different macro definition that overrules the definition found in the source code.
+
+EXPAND_AS_DEFINED =
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then
+# doxygen's preprocessor will remove all references to function-like macros
+# that are alone on a line, have an all uppercase name, and do not end with a
+# semicolon, because these will confuse the parser if not removed.
+
+SKIP_FUNCTION_MACROS = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references
+#---------------------------------------------------------------------------
+
+# The TAGFILES option can be used to specify one or more tagfiles.
+# Optionally an initial location of the external documentation
+# can be added for each tagfile. The format of a tag file without
+# this location is as follows:
+#
+# TAGFILES = file1 file2 ...
+# Adding location for the tag files is done as follows:
+#
+# TAGFILES = file1=loc1 "file2 = loc2" ...
+# where "loc1" and "loc2" can be relative or absolute paths or
+# URLs. If a location is present for each tag, the installdox tool
+# does not have to be run to correct the links.
+# Note that each tag file must have a unique name
+# (where the name does NOT include the path)
+# If a tag file is not located in the directory in which doxygen
+# is run, you must also specify the path to the tagfile here.
+
+TAGFILES =
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create
+# a tag file that is based on the input files it reads.
+
+GENERATE_TAGFILE =
+
+# If the ALLEXTERNALS tag is set to YES all external classes will be listed
+# in the class index. If set to NO only the inherited external classes
+# will be listed.
+
+ALLEXTERNALS = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed
+# in the modules index. If set to NO, only the current project's groups will
+# be listed.
+
+EXTERNAL_GROUPS = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script
+# interpreter (i.e. the result of `which perl').
+
+PERL_PATH =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will
+# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base
+# or super classes. Setting the tag to NO turns the diagrams off. Note that
+# this option also works with HAVE_DOT disabled, but it is recommended to
+# install and use dot, since it yields more powerful graphs.
+
+CLASS_DIAGRAMS = YES
+
+# You can define message sequence charts within doxygen comments using the \msc
+# command. Doxygen will then run the mscgen tool (see
+# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the
+# documentation. The MSCGEN_PATH tag allows you to specify the directory where
+# the mscgen tool resides. If left empty the tool is assumed to be found in the
+# default search path.
+
+MSCGEN_PATH =
+
+# If set to YES, the inheritance and collaboration graphs will hide
+# inheritance and usage relations if the target is undocumented
+# or is not a class.
+
+HIDE_UNDOC_RELATIONS = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
+# available from the path. This tool is part of Graphviz, a graph visualization
+# toolkit from AT&T and Lucent Bell Labs. The other options in this section
+# have no effect if this option is set to NO (the default)
+
+HAVE_DOT = YES
+
+# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is
+# allowed to run in parallel. When set to 0 (the default) doxygen will
+# base this on the number of processors available in the system. You can set it
+# explicitly to a value larger than 0 to get control over the balance
+# between CPU load and processing speed.
+
+DOT_NUM_THREADS = 0
+
+# By default doxygen will write a font called Helvetica to the output
+# directory and reference it in all dot files that doxygen generates.
+# When you want a differently looking font you can specify the font name
+# using DOT_FONTNAME. You need to make sure dot is able to find the font,
+# which can be done by putting it in a standard location or by setting the
+# DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory
+# containing the font.
+
+DOT_FONTNAME = Helvetica
+
+# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs.
+# The default size is 10pt.
+
+DOT_FONTSIZE = 10
+
+# By default doxygen will tell dot to use the output directory to look for the
+# FreeSans.ttf font (which doxygen will put there itself). If you specify a
+# different font using DOT_FONTNAME you can set the path where dot
+# can find it using this tag.
+
+DOT_FONTPATH =
+
+# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect inheritance relations. Setting this tag to YES will force the
+# the CLASS_DIAGRAMS tag to NO.
+
+CLASS_GRAPH = YES
+
+# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect implementation dependencies (inheritance, containment, and
+# class references variables) of the class with other documented classes.
+
+COLLABORATION_GRAPH = YES
+
+# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for groups, showing the direct groups dependencies
+
+GROUP_GRAPHS = YES
+
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and
+# collaboration diagrams in a style similar to the OMG's Unified Modeling
+# Language.
+
+UML_LOOK = NO
+
+# If set to YES, the inheritance and collaboration graphs will show the
+# relations between templates and their instances.
+
+TEMPLATE_RELATIONS = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT
+# tags are set to YES then doxygen will generate a graph for each documented
+# file showing the direct and indirect include dependencies of the file with
+# other documented files.
+
+INCLUDE_GRAPH = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and
+# HAVE_DOT tags are set to YES then doxygen will generate a graph for each
+# documented header file showing the documented files that directly or
+# indirectly include this file.
+
+INCLUDED_BY_GRAPH = YES
+
+# If the CALL_GRAPH and HAVE_DOT options are set to YES then
+# doxygen will generate a call dependency graph for every global function
+# or class method. Note that enabling this option will significantly increase
+# the time of a run. So in most cases it will be better to enable call graphs
+# for selected functions only using the \callgraph command.
+
+CALL_GRAPH = NO
+
+# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then
+# doxygen will generate a caller dependency graph for every global function
+# or class method. Note that enabling this option will significantly increase
+# the time of a run. So in most cases it will be better to enable caller
+# graphs for selected functions only using the \callergraph command.
+
+CALLER_GRAPH = NO
+
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen
+# will generate a graphical hierarchy of all classes instead of a textual one.
+
+GRAPHICAL_HIERARCHY = YES
+
+# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES
+# then doxygen will show the dependencies a directory has on other directories
+# in a graphical way. The dependency relations are determined by the #include
+# relations between the files in the directories.
+
+DIRECTORY_GRAPH = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
+# generated by dot. Possible values are png, svg, gif or svg.
+# If left blank png will be used.
+
+DOT_IMAGE_FORMAT = png
+
+# The tag DOT_PATH can be used to specify the path where the dot tool can be
+# found. If left blank, it is assumed the dot tool can be found in the path.
+
+DOT_PATH =
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that
+# contain dot files that are included in the documentation (see the
+# \dotfile command).
+
+DOTFILE_DIRS =
+
+# The MSCFILE_DIRS tag can be used to specify one or more directories that
+# contain msc files that are included in the documentation (see the
+# \mscfile command).
+
+#MSCFILE_DIRS =
+
+# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of
+# nodes that will be shown in the graph. If the number of nodes in a graph
+# becomes larger than this value, doxygen will truncate the graph, which is
+# visualized by representing a node as a red box. Note that doxygen if the
+# number of direct children of the root node in a graph is already larger than
+# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note
+# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
+
+DOT_GRAPH_MAX_NODES = 50
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the
+# graphs generated by dot. A depth value of 3 means that only nodes reachable
+# from the root by following a path via at most 3 edges will be shown. Nodes
+# that lay further from the root node will be omitted. Note that setting this
+# option to 1 or 2 may greatly reduce the computation time needed for large
+# code bases. Also note that the size of a graph can be further restricted by
+# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
+
+MAX_DOT_GRAPH_DEPTH = 0
+
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
+# background. This is disabled by default, because dot on Windows does not
+# seem to support this out of the box. Warning: Depending on the platform used,
+# enabling this option may lead to badly anti-aliased labels on the edges of
+# a graph (i.e. they become hard to read).
+
+DOT_TRANSPARENT = NO
+
+# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output
+# files in one run (i.e. multiple -o and -T options on the command line). This
+# makes dot run faster, but since only newer versions of dot (>1.8.10)
+# support this, this feature is disabled by default.
+
+DOT_MULTI_TARGETS = NO
+
+# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will
+# generate a legend page explaining the meaning of the various boxes and
+# arrows in the dot generated graphs.
+
+GENERATE_LEGEND = YES
+
+# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will
+# remove the intermediate dot files that are used to generate
+# the various graphs.
+
+DOT_CLEANUP = YES
diff --git a/INSTALL b/INSTALL
new file mode 100644
index 0000000..bfe684d
--- /dev/null
+++ b/INSTALL
@@ -0,0 +1,167 @@
+----------------------------------------------
+The Corosync Cluster Engine Installation Guide
+----------------------------------------------
+Please read LICENSE for a description of the licensing of this software.
+
+---------------------
+* Building from git *
+---------------------
+When building and installing from git, autoconf 2.61, automake 1.11,
+libtool 2.2.6 and pkgconfig 0.23 (or later versions) are required.
+Prior versions may result in build failures.
+
+Step 1: check out a read only copy of the repository
+git clone git://github.com/corosync/corosync.git
+
+Find the version you want to build. Usually this will be the "master" version.
+If you want to build a specific released version, use git checkout VERSION.
+
+Step 2: Generate the makefiles
+balance:~/corosync% ./autogen.sh
+
+Step 3: Run the configure script
+balance:~/corosync% ./configure
+
+Step 4: Install the binaries
+balance:~/corosync% su
+balance:~/corosync# make install
+
+-------------------------
+* Building from tarball *
+-------------------------
+The tarball is distributed with pregenerated makefiles. There is no need
+to run the autogen.sh script in this case.
+
+Step 1: Run the configure script
+balance:~/corosync% ./configure
+
+Step 2: Install the binaries
+balance:~/corosync% su
+balance:~/corosync# make install
+
+-------------------------------
+* A notice about dependencies *
+-------------------------------
+We have strived very hard to avoid dependencies as much as possible, but there
+are two required libraries: LibQB (https://github.com/ClusterLabs/libqb)
+and KNET (https://kronosnet.org/).
+
+Optional dependencies are support for DBUS, SNMP and libstatgrab.
+
+Also don't forget to install pkgconfig.
+
+-----------------------------------------
+* Building with SNMP/DBUS support *
+-----------------------------------------
+
+You can get SNMP traps on the following corosync events:
+1) node joine/leave
+2) application connect/dissconnect from corosync
+3) quorum gain/lost
+
+There are 2 modes of achieving this DBUS + foghorn and snmp-agentx.
+
+Setting up to get dbus events.
+------------------------------
+foghorn (http://git.fedorahosted.org/git/foghorn.git) converts
+dbus signals into snmp traps. So install foghorn.
+
+$ ./configure --enable-dbus
+$ make && sudo make install
+$ /etc/init.d/corosync start
+$ echo "OPTIONS=\"-d\"" > /etc/sysconfig/corosync-notifyd
+$ /etc/init.d/corosync-notifyd start
+Start foghorn
+
+to see the dbus signals getting sent try:
+$ dbus-monitor --system
+
+Setting up snmp-agentx.
+-----------------------
+If you don't want to use dbus then you can use snmp-agentx.
+
+$ ./configure --enable-snmp
+$ make && sudo make install
+$ /etc/init.d/corosync start
+$ vim /etc/snmp/snmptrapd.conf
+
+Add the following:
+authCommunity log,execute,net public
+$ /etc/init.d/snmptrapd start
+$ echo "OPTIONS=\"-s\"" > /etc/sysconfig/corosync-notifyd
+$ /etc/init.d/corosync-notifyd start
+
+I start up wireshark to see if there are any snmp traps been sent
+as I am too lazy to setup a manager to receive traps.
+
+run a program that talks to corosync e.g.
+$ corosync-cmapctl
+
+And you should get traps
+
+
+------------------------
+* Configuring Corosync *
+------------------------
+The configuration directory (usually /etc/corosync) contains an example
+configuration file (corosync.conf.example). Please copy it as corosync.conf
+and edit it as needed. At the very minimum, the nodelist section will have to be changed
+to list all cluster nodes. For more information about the configuration file
+please read the corosync.conf.5 manual page.
+
+Generate a private key
+----------------------
+corosync uses cryptographic techniques to ensure authenticity and privacy of
+messages. A private key must be generated and shared by all processors for
+correct operation.
+
+First generate the key on one of the nodes:
+
+balance# corosync-keygen
+Corosync Authentication key generator.
+Gathering 8192 bits for key from /dev/random.
+Writing corosync key to /etc/corosync/authkey.
+
+After this is complete, a private key will be in the file /etc/corosync/authkey.
+This private key must be copied to every processor that will be a member of
+the cluster. If the private key isn't the same for every node, those nodes
+with nonmatching private keys will not be able to join the same configuration.
+
+Copy the key to some transportable storage or use ssh to transmit the key
+from node to node. Then install the key with the command:
+
+balance# install -D --group=0 --owner=0 --mode=0400 /path_to_authkey/authkey /etc/corosync/authkey
+
+If the message invalid digest appears, the keys are not the same on each node.
+
+Run the corosync executive
+-------------------------
+Get one or more nodes and run the corosync executive on each node. Run the
+corosync daemon after following the previous directions. The daemon must be
+run as UID 0(root).
+
+Before running any of the test programs
+---------------------------------------
+The corosync executive will ensure security by only allowing the UID 0(root) or
+GID 0(root) to connect to it. To allow other users to access the corosync
+executive, create a directory called /etc/corosync/uidgid.d and place a file in
+it named in some way that is identifiable to you. All files in this directory
+will be scanned and their contents added to the allowed uid gid database. The
+contents of this file should be
+uidgid {
+ uid: username
+ gid: groupname
+}
+
+Please note that these users then have full ability to transmit and receive
+messages in the cluster.
+
+Try out the corosync cpg functionality
+--------------------------------------
+After corosync is running
+
+Run test/testcpg on multiple nodes or on the same node. Messages can be typed
+which will then be sent to other testcpg applications in the cluster.
+
+To see a hashed verified output of data on all nodes, test/cpgverify can be
+run.
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..8d32cd1
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,59 @@
+-----------------------------------------------------------------------------
+The following license applies to every file in this source distribution except
+for the files git-version-gen, and gitlog-to-changelog.
+
+The git* files, which are available under GPLv3 or later, are only used by
+our release process to generate text file content and are not part of any
+generated binary.
+-----------------------------------------------------------------------------
+
+Copyright (c) 2002-2004 MontaVista Software, Inc.
+Copyright (c) 2005-2010 Red Hat, Inc.
+
+All rights reserved.
+
+This software licensed under BSD license, the text of which follows:
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+- Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+- Neither the name of the MontaVista Software, Inc. nor the names of its
+ contributors may be used to endorse or promote products derived from this
+ software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+THE POSSIBILITY OF SUCH DAMAGE.
+
+-----------------------------------------------------------------------------
+The corosync project uses software for release processing which generates
+changelogs and version information for the software. These programs are not
+used by the generated binaries or libraries These files are git-version-gen
+and gitlog-to-changelog.
+-----------------------------------------------------------------------------
+The license for these files is as follows:
+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 3 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, see <http://www.gnu.org/licenses/>.
diff --git a/Makefile.am b/Makefile.am
new file mode 100644
index 0000000..68c7866
--- /dev/null
+++ b/Makefile.am
@@ -0,0 +1,201 @@
+# Copyright (c) 2009 Red Hat, Inc.
+#
+# Authors: Andrew Beekhof
+# Steven Dake (sdake@redhat.com)
+#
+# This software licensed under BSD license, the text of which follows:
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# - Redistributions of source code must retain the above copyright notice,
+# this list of conditions and the following disclaimer.
+# - Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+# - Neither the name of the MontaVista Software, Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from this
+# software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+# THE POSSIBILITY OF SUCH DAMAGE.
+
+SPEC = $(PACKAGE_NAME).spec
+
+TARFILE = $(PACKAGE_NAME)-$(VERSION).tar.gz
+
+EXTRA_DIST = autogen.sh $(SPEC).in \
+ build-aux/git-version-gen \
+ build-aux/gitlog-to-changelog \
+ build-aux/release.mk \
+ build-aux/rust.mk \
+ build-aux/rust-regen.sh \
+ .version
+
+ACLOCAL_AMFLAGS = -I m4
+
+MAINTAINERCLEANFILES = Makefile.in aclocal.m4 configure depcomp \
+ config.guess config.sub missing install-sh \
+ autoheader automake autoconf test_lense.sh \
+ autoscan.log configure.scan ltmain.sh test-driver
+
+dist_doc_DATA = LICENSE INSTALL README.recovery AUTHORS
+
+SUBDIRS = include common_lib lib exec tools test pkgconfig \
+ man init conf vqsim bindings
+
+coverity:
+ rm -rf cov
+ make clean
+ cov-build --dir=cov make
+ cov-analyze --dir cov \
+ --concurrency \
+ -co BAD_FREE:allow_first_field:true \
+ --security \
+ --wait-for-license
+ cov-format-errors --dir cov
+
+coverity-aggressive:
+ rm -rf cov
+ make clean
+ cov-build --dir=cov make
+ cov-analyze --dir cov \
+ --concurrency \
+ --all \
+ --aggressiveness-level high \
+ --security \
+ --wait-for-license
+ cov-format-errors --dir cov
+
+install-exec-local:
+ $(INSTALL) -d $(DESTDIR)/${COROSYSCONFDIR}/service.d
+ $(INSTALL) -d $(DESTDIR)/${COROSYSCONFDIR}/uidgid.d
+ $(INSTALL) -d $(DESTDIR)/${localstatedir}/lib/corosync
+ $(INSTALL) -d $(DESTDIR)/${localstatedir}/log/cluster
+
+uninstall-local:
+ rmdir $(DESTDIR)/${COROSYSCONFDIR}/service.d || :;
+ rmdir $(DESTDIR)/${COROSYSCONFDIR}/uidgid.d || :;
+ rmdir $(DESTDIR)/${localstatedir}/lib/corosync || :;
+ rmdir $(DESTDIR)/${localstatedir}/log/cluster || :;
+
+if AUGTOOL
+check_SCRIPTS = test_lense.sh
+TESTS = $(check_SCRIPTS)
+
+test_lense.sh:
+ echo "augparse -I $(srcdir)/conf/lenses/ $(srcdir)/conf/lenses/tests/test_corosync.aug" > $@
+ chmod +x $@
+
+endif
+
+lint:
+ for dir in lib exec tools test; do make -C $$dir lint; done
+
+.PHONY: doxygen
+doxygen:
+ @if [ "$(DOXYGEN)" = "" ] || [ "$(DOT)" = "" ] ; then \
+ echo "*********************************************" ; \
+ echo "*** ***" ; \
+ echo "*** You must install doxygen and graphviz ***" ; \
+ echo "*** to generate the API documentation. ***" ; \
+ echo "*** ***" ; \
+ echo "*********************************************" ; \
+ exit 1 ; \
+ else \
+ mkdir -p doc/api && $(DOXYGEN) ; \
+ fi
+
+dist-clean-local:
+ rm -f autoconf automake autoheader test_lense.sh
+
+clean-generic:
+ rm -rf doc/api $(SPEC) $(TARFILE) test_lense.sh
+
+## make rpm/srpm section.
+
+$(SPEC): $(SPEC).in
+ rm -f $@-t $@
+ date="$(shell LC_ALL=C date "+%a %b %d %Y")" && \
+ gvgver="`cd $(abs_srcdir); build-aux/git-version-gen --fallback $(VERSION) .tarball-version .gitarchivever`" && \
+ if [ "$$gvgver" = "`echo $$gvgver | sed 's/-/./'`" ];then \
+ rpmver="$$gvgver" && \
+ alphatag="" && \
+ dirty="" && \
+ numcomm="0"; \
+ else \
+ gitver="`echo $$gvgver | sed 's/\(.*\)\./\1-/'`" && \
+ rpmver=`echo $$gitver | sed 's/-.*//g'` && \
+ alphatag=`echo $$gvgver | sed 's/[^-]*-\([^-]*\).*/\1/'` && \
+ numcomm=`echo $$gitver | sed 's/[^-]*-\([^-]*\).*/\1/'` && \
+ dirty="" && \
+ if [ "`echo $$gitver | sed 's/^.*-dirty$$//g'`" = "" ];then \
+ dirty="dirty"; \
+ fi \
+ fi && \
+ if [ -n "$$dirty" ]; then dirty="dirty"; else dirty=""; fi && \
+ if [ "$$numcomm" = "0" ]; then numcomm=""; fi && \
+ if [ -n "$$numcomm" ]; then numcomm="%global numcomm $$numcomm"; fi && \
+ if [ "$$alphatag" = "$$gitver" ]; then alphatag=""; fi && \
+ if [ -n "$$alphatag" ]; then alphatag="%global alphatag $$alphatag"; fi && \
+ if [ -n "$$dirty" ]; then dirty="%global dirty dirty"; fi && \
+ $(SED) \
+ -e "s#@version@#$$rpmver#g" \
+ -e "s#@ALPHATAG@#$$alphatag#g" \
+ -e "s#@NUMCOMM@#$$numcomm#g" \
+ -e "s#@DIRTY@#$$dirty#g" \
+ -e "s#@date@#$$date#g" \
+ $< > $@-t; \
+ chmod a-w $@-t
+ mv $@-t $@
+
+$(TARFILE):
+ $(MAKE) dist
+
+RPMBUILDOPTS = --define "_sourcedir $(abs_builddir)" \
+ --define "_specdir $(abs_builddir)" \
+ --define "_builddir $(abs_builddir)" \
+ --define "_srcrpmdir $(abs_builddir)" \
+ --define "_rpmdir $(abs_builddir)"
+
+srpm: clean
+ $(MAKE) $(SPEC) $(TARFILE)
+ rpmbuild $(WITH_LIST) $(RPMBUILDOPTS) --nodeps -bs $(SPEC)
+
+rpm: clean _version
+ $(MAKE) $(SPEC) $(TARFILE)
+ rpmbuild $(WITH_LIST) $(RPMBUILDOPTS) -ba $(SPEC)
+
+# release/versioning
+BUILT_SOURCES = .version
+.version:
+ echo $(VERSION) > $@-t && mv $@-t $@
+
+dist-hook: gen-ChangeLog
+ echo $(VERSION) > $(distdir)/.tarball-version
+
+gen_start_date = 2000-01-01
+.PHONY: gen-ChangeLog _version
+gen-ChangeLog:
+ if test -d .git; then \
+ LC_ALL=C $(top_srcdir)/build-aux/gitlog-to-changelog \
+ --since=$(gen_start_date) > $(distdir)/cl-t; \
+ rm -f $(distdir)/ChangeLog; \
+ mv $(distdir)/cl-t $(distdir)/ChangeLog; \
+ fi
+
+_version:
+ cd $(srcdir) && rm -rf autom4te.cache .version && autoreconf -i
+ $(MAKE) $(AM_MAKEFLAGS) Makefile
+
+maintainer-clean-local:
+ rm -rf m4
diff --git a/Makefile.in b/Makefile.in
new file mode 100644
index 0000000..a05ddf6
--- /dev/null
+++ b/Makefile.in
@@ -0,0 +1,1446 @@
+# Makefile.in generated by automake 1.13.4 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+# Copyright (c) 2009 Red Hat, Inc.
+#
+# Authors: Andrew Beekhof
+# Steven Dake (sdake@redhat.com)
+#
+# This software licensed under BSD license, the text of which follows:
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# - Redistributions of source code must retain the above copyright notice,
+# this list of conditions and the following disclaimer.
+# - Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+# - Neither the name of the MontaVista Software, Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from this
+# software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+# THE POSSIBILITY OF SUCH DAMAGE.
+
+VPATH = @srcdir@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = .
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+ $(top_srcdir)/configure $(am__configure_deps) \
+ $(top_srcdir)/include/corosync/config.h.in \
+ $(srcdir)/Doxyfile.in $(dist_doc_DATA) test-driver AUTHORS \
+ INSTALL config.guess config.sub install-sh missing ltmain.sh
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/lib/libcfg.verso $(top_srcdir)/lib/libcpg.verso \
+ $(top_srcdir)/lib/libquorum.verso \
+ $(top_srcdir)/lib/libsam.verso \
+ $(top_srcdir)/lib/libvotequorum.verso \
+ $(top_srcdir)/lib/libcmap.verso $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
+ configure.lineno config.status.lineno
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/include/corosync/config.h
+CONFIG_CLEAN_FILES = Doxyfile
+CONFIG_CLEAN_VPATH_FILES =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+SOURCES =
+DIST_SOURCES =
+RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \
+ ctags-recursive dvi-recursive html-recursive info-recursive \
+ install-data-recursive install-dvi-recursive \
+ install-exec-recursive install-html-recursive \
+ install-info-recursive install-pdf-recursive \
+ install-ps-recursive install-recursive installcheck-recursive \
+ installdirs-recursive pdf-recursive ps-recursive \
+ tags-recursive uninstall-recursive
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+am__installdirs = "$(DESTDIR)$(docdir)"
+DATA = $(dist_doc_DATA)
+RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
+ distclean-recursive maintainer-clean-recursive
+am__recursive_targets = \
+ $(RECURSIVE_TARGETS) \
+ $(RECURSIVE_CLEAN_TARGETS) \
+ $(am__extra_recursive_targets)
+AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \
+ cscope check recheck distdir dist dist-all distcheck
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+CSCOPE = cscope
+am__tty_colors_dummy = \
+ mgn= red= grn= lgn= blu= brg= std=; \
+ am__color_tests=no
+am__tty_colors = { \
+ $(am__tty_colors_dummy); \
+ if test "X$(AM_COLOR_TESTS)" = Xno; then \
+ am__color_tests=no; \
+ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \
+ am__color_tests=yes; \
+ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \
+ am__color_tests=yes; \
+ fi; \
+ if test $$am__color_tests = yes; then \
+ red=''; \
+ grn=''; \
+ lgn=''; \
+ blu=''; \
+ mgn=''; \
+ brg=''; \
+ std=''; \
+ fi; \
+}
+am__recheck_rx = ^[ ]*:recheck:[ ]*
+am__global_test_result_rx = ^[ ]*:global-test-result:[ ]*
+am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]*
+# A command that, given a newline-separated list of test names on the
+# standard input, print the name of the tests that are to be re-run
+# upon "make recheck".
+am__list_recheck_tests = $(AWK) '{ \
+ recheck = 1; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ { \
+ if ((getline line2 < ($$0 ".log")) < 0) \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \
+ { \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \
+ { \
+ break; \
+ } \
+ }; \
+ if (recheck) \
+ print $$0; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# A command that, given a newline-separated list of test names on the
+# standard input, create the global log from their .trs and .log files.
+am__create_global_log = $(AWK) ' \
+function fatal(msg) \
+{ \
+ print "fatal: making $@: " msg | "cat >&2"; \
+ exit 1; \
+} \
+function rst_section(header) \
+{ \
+ print header; \
+ len = length(header); \
+ for (i = 1; i <= len; i = i + 1) \
+ printf "="; \
+ printf "\n\n"; \
+} \
+{ \
+ copy_in_global_log = 1; \
+ global_test_result = "RUN"; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".trs"); \
+ if (line ~ /$(am__global_test_result_rx)/) \
+ { \
+ sub("$(am__global_test_result_rx)", "", line); \
+ sub("[ ]*$$", "", line); \
+ global_test_result = line; \
+ } \
+ else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \
+ copy_in_global_log = 0; \
+ }; \
+ if (copy_in_global_log) \
+ { \
+ rst_section(global_test_result ": " $$0); \
+ while ((rc = (getline line < ($$0 ".log"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".log"); \
+ print line; \
+ }; \
+ printf "\n"; \
+ }; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# Restructured Text title.
+am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; }
+# Solaris 10 'make', and several other traditional 'make' implementations,
+# pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it
+# by disabling -e (using the XSI extension "set +e") if it's set.
+am__sh_e_setup = case $$- in *e*) set +e;; esac
+# Default flags passed to test drivers.
+am__common_driver_flags = \
+ --color-tests "$$am__color_tests" \
+ --enable-hard-errors "$$am__enable_hard_errors" \
+ --expect-failure "$$am__expect_failure"
+# To be inserted before the command running the test. Creates the
+# directory for the log if needed. Stores in $dir the directory
+# containing $f, in $tst the test, in $log the log. Executes the
+# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and
+# passes TESTS_ENVIRONMENT. Set up options for the wrapper that
+# will run the test scripts (or their associated LOG_COMPILER, if
+# thy have one).
+am__check_pre = \
+$(am__sh_e_setup); \
+$(am__vpath_adj_setup) $(am__vpath_adj) \
+$(am__tty_colors); \
+srcdir=$(srcdir); export srcdir; \
+case "$@" in \
+ */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \
+ *) am__odir=.;; \
+esac; \
+test "x$$am__odir" = x"." || test -d "$$am__odir" \
+ || $(MKDIR_P) "$$am__odir" || exit $$?; \
+if test -f "./$$f"; then dir=./; \
+elif test -f "$$f"; then dir=; \
+else dir="$(srcdir)/"; fi; \
+tst=$$dir$$f; log='$@'; \
+if test -n '$(DISABLE_HARD_ERRORS)'; then \
+ am__enable_hard_errors=no; \
+else \
+ am__enable_hard_errors=yes; \
+fi; \
+case " $(XFAIL_TESTS) " in \
+ *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \
+ am__expect_failure=yes;; \
+ *) \
+ am__expect_failure=no;; \
+esac; \
+$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT)
+# A shell command to get the names of the tests scripts with any registered
+# extension removed (i.e., equivalently, the names of the test logs, with
+# the '.log' extension removed). The result is saved in the shell variable
+# '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly,
+# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)",
+# since that might cause problem with VPATH rewrites for suffix-less tests.
+# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'.
+am__set_TESTS_bases = \
+ bases='$(TEST_LOGS)'; \
+ bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \
+ bases=`echo $$bases`
+RECHECK_LOGS = $(TEST_LOGS)
+TEST_SUITE_LOG = test-suite.log
+TEST_EXTENSIONS = @EXEEXT@ .test
+LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver
+LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS)
+am__set_b = \
+ case '$@' in \
+ */*) \
+ case '$*' in \
+ */*) b='$*';; \
+ *) b=`echo '$@' | sed 's/\.log$$//'`; \
+ esac;; \
+ *) \
+ b='$*';; \
+ esac
+am__test_logs1 = $(TESTS:=.log)
+am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log)
+TEST_LOGS = $(am__test_logs2:.test.log=.log)
+TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver
+TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
+ $(TEST_LOG_FLAGS)
+DIST_SUBDIRS = $(SUBDIRS)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+distdir = $(PACKAGE)-$(VERSION)
+top_distdir = $(distdir)
+am__remove_distdir = \
+ if test -d "$(distdir)"; then \
+ find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \
+ && rm -rf "$(distdir)" \
+ || { sleep 5 && rm -rf "$(distdir)"; }; \
+ else :; fi
+am__post_remove_distdir = $(am__remove_distdir)
+am__relativize = \
+ dir0=`pwd`; \
+ sed_first='s,^\([^/]*\)/.*$$,\1,'; \
+ sed_rest='s,^[^/]*/*,,'; \
+ sed_last='s,^.*/\([^/]*\)$$,\1,'; \
+ sed_butlast='s,/*[^/]*$$,,'; \
+ while test -n "$$dir1"; do \
+ first=`echo "$$dir1" | sed -e "$$sed_first"`; \
+ if test "$$first" != "."; then \
+ if test "$$first" = ".."; then \
+ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
+ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
+ else \
+ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
+ if test "$$first2" = "$$first"; then \
+ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
+ else \
+ dir2="../$$dir2"; \
+ fi; \
+ dir0="$$dir0"/"$$first"; \
+ fi; \
+ fi; \
+ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
+ done; \
+ reldir="$$dir2"
+DIST_ARCHIVES = $(distdir).tar.gz
+GZIP_ENV = --best
+DIST_TARGETS = dist-gzip
+distuninstallcheck_listfiles = find . -type f -print
+am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \
+ | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$'
+distcleancheck_listfiles = find . -type f -print
+ACLOCAL = @ACLOCAL@
+ALLOCA = @ALLOCA@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUGTOOL = @AUGTOOL@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BASHPATH = @BASHPATH@
+BINDGEN = @BINDGEN@
+CARGO = @CARGO@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFG_SONAME = @CFG_SONAME@
+CFLAGS = @CFLAGS@
+CLIPPY = @CLIPPY@
+CMAP_SONAME = @CMAP_SONAME@
+COROSYSCONFDIR = @COROSYSCONFDIR@
+CPG_SONAME = @CPG_SONAME@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DBUS_CFLAGS = @DBUS_CFLAGS@
+DBUS_LIBS = @DBUS_LIBS@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DOT = @DOT@
+DOXYGEN = @DOXYGEN@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GREP = @GREP@
+GROFF = @GROFF@
+INITCONFIGDIR = @INITCONFIGDIR@
+INITDDIR = @INITDDIR@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBQB_CFLAGS = @LIBQB_CFLAGS@
+LIBQB_LIBS = @LIBQB_LIBS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LINT_FLAGS = @LINT_FLAGS@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LOGDIR = @LOGDIR@
+LOGROTATEDIR = @LOGROTATEDIR@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+QUORUM_SONAME = @QUORUM_SONAME@
+RANLIB = @RANLIB@
+RUSTC = @RUSTC@
+RUSTDOC = @RUSTDOC@
+RUSTFMT = @RUSTFMT@
+RUST_FLAGS = @RUST_FLAGS@
+RUST_TARGET_DIR = @RUST_TARGET_DIR@
+SAM_SONAME = @SAM_SONAME@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SNMPCONFIG = @SNMPCONFIG@
+SNMP_LIBS = @SNMP_LIBS@
+SOMAJOR = @SOMAJOR@
+SOMICRO = @SOMICRO@
+SOMINOR = @SOMINOR@
+SONAME = @SONAME@
+STRIP = @STRIP@
+SYSTEMDDIR = @SYSTEMDDIR@
+VERSCRIPT_LDFLAGS = @VERSCRIPT_LDFLAGS@
+VERSION = @VERSION@
+VOTEQUORUM_SONAME = @VOTEQUORUM_SONAME@
+WITH_LIST = @WITH_LIST@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+corosyncrustver = @corosyncrustver@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+knet_CFLAGS = @knet_CFLAGS@
+knet_LIBS = @knet_LIBS@
+libdir = @libdir@
+libexecdir = @libexecdir@
+libsystemd_CFLAGS = @libsystemd_CFLAGS@
+libsystemd_LIBS = @libsystemd_LIBS@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+nozzle_CFLAGS = @nozzle_CFLAGS@
+nozzle_LIBS = @nozzle_LIBS@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+statgrab_CFLAGS = @statgrab_CFLAGS@
+statgrab_LIBS = @statgrab_LIBS@
+statgrabge090_CFLAGS = @statgrabge090_CFLAGS@
+statgrabge090_LIBS = @statgrabge090_LIBS@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+SPEC = $(PACKAGE_NAME).spec
+TARFILE = $(PACKAGE_NAME)-$(VERSION).tar.gz
+EXTRA_DIST = autogen.sh $(SPEC).in \
+ build-aux/git-version-gen \
+ build-aux/gitlog-to-changelog \
+ build-aux/release.mk \
+ build-aux/rust.mk \
+ build-aux/rust-regen.sh \
+ .version
+
+ACLOCAL_AMFLAGS = -I m4
+MAINTAINERCLEANFILES = Makefile.in aclocal.m4 configure depcomp \
+ config.guess config.sub missing install-sh \
+ autoheader automake autoconf test_lense.sh \
+ autoscan.log configure.scan ltmain.sh test-driver
+
+dist_doc_DATA = LICENSE INSTALL README.recovery AUTHORS
+SUBDIRS = include common_lib lib exec tools test pkgconfig \
+ man init conf vqsim bindings
+
+@AUGTOOL_TRUE@check_SCRIPTS = test_lense.sh
+@AUGTOOL_TRUE@TESTS = $(check_SCRIPTS)
+RPMBUILDOPTS = --define "_sourcedir $(abs_builddir)" \
+ --define "_specdir $(abs_builddir)" \
+ --define "_builddir $(abs_builddir)" \
+ --define "_srcrpmdir $(abs_builddir)" \
+ --define "_rpmdir $(abs_builddir)"
+
+
+# release/versioning
+BUILT_SOURCES = .version
+gen_start_date = 2000-01-01
+all: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) all-recursive
+
+.SUFFIXES:
+.SUFFIXES: .log .test .test$(EXEEXT) .trs
+am--refresh: Makefile
+ @:
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ echo ' cd $(srcdir) && $(AUTOMAKE) --foreign'; \
+ $(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ echo ' $(SHELL) ./config.status'; \
+ $(SHELL) ./config.status;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ $(SHELL) ./config.status --recheck
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ $(am__cd) $(srcdir) && $(AUTOCONF)
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
+$(am__aclocal_m4_deps):
+
+include/corosync/config.h: include/corosync/stamp-h1
+ @if test ! -f $@; then rm -f include/corosync/stamp-h1; else :; fi
+ @if test ! -f $@; then $(MAKE) $(AM_MAKEFLAGS) include/corosync/stamp-h1; else :; fi
+
+include/corosync/stamp-h1: $(top_srcdir)/include/corosync/config.h.in $(top_builddir)/config.status
+ @rm -f include/corosync/stamp-h1
+ cd $(top_builddir) && $(SHELL) ./config.status include/corosync/config.h
+$(top_srcdir)/include/corosync/config.h.in: $(am__configure_deps)
+ ($(am__cd) $(top_srcdir) && $(AUTOHEADER))
+ rm -f include/corosync/stamp-h1
+ touch $@
+
+distclean-hdr:
+ -rm -f include/corosync/config.h include/corosync/stamp-h1
+Doxyfile: $(top_builddir)/config.status $(srcdir)/Doxyfile.in
+ cd $(top_builddir) && $(SHELL) ./config.status $@
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+distclean-libtool:
+ -rm -f libtool config.lt
+install-dist_docDATA: $(dist_doc_DATA)
+ @$(NORMAL_INSTALL)
+ @list='$(dist_doc_DATA)'; test -n "$(docdir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(docdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(docdir)" || exit 1; \
+ fi; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(docdir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(docdir)" || exit $$?; \
+ done
+
+uninstall-dist_docDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(dist_doc_DATA)'; test -n "$(docdir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ dir='$(DESTDIR)$(docdir)'; $(am__uninstall_files_from_dir)
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run 'make' without going through this Makefile.
+# To change the values of 'make' variables: instead of editing Makefiles,
+# (1) if the variable is set in 'config.status', edit 'config.status'
+# (which will cause the Makefiles to be regenerated when you run 'make');
+# (2) otherwise, pass the desired values on the 'make' command line.
+$(am__recursive_targets):
+ @fail=; \
+ if $(am__make_keepgoing); then \
+ failcom='fail=yes'; \
+ else \
+ failcom='exit 1'; \
+ fi; \
+ dot_seen=no; \
+ target=`echo $@ | sed s/-recursive//`; \
+ case "$@" in \
+ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+ *) list='$(SUBDIRS)' ;; \
+ esac; \
+ for subdir in $$list; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ dot_seen=yes; \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || eval $$failcom; \
+ done; \
+ if test "$$dot_seen" = "no"; then \
+ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+ fi; test -z "$$fail"
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-recursive
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
+ include_option=--etags-include; \
+ empty_fix=.; \
+ else \
+ include_option=--include; \
+ empty_fix=; \
+ fi; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test ! -f $$subdir/TAGS || \
+ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
+ fi; \
+ done; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-recursive
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscope: cscope.files
+ test ! -s cscope.files \
+ || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS)
+clean-cscope:
+ -rm -f cscope.files
+cscope.files: clean-cscope cscopelist
+cscopelist: cscopelist-recursive
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+ -rm -f cscope.out cscope.in.out cscope.po.out cscope.files
+
+# Recover from deleted '.trs' file; this should ensure that
+# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create
+# both 'foo.log' and 'foo.trs'. Break the recipe in two subshells
+# to avoid problems with "make -n".
+.log.trs:
+ rm -f $< $@
+ $(MAKE) $(AM_MAKEFLAGS) $<
+
+# Leading 'am--fnord' is there to ensure the list of targets does not
+# expand to empty, as could happen e.g. with make check TESTS=''.
+am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck)
+am--force-recheck:
+ @:
+
+$(TEST_SUITE_LOG): $(TEST_LOGS)
+ @$(am__set_TESTS_bases); \
+ am__f_ok () { test -f "$$1" && test -r "$$1"; }; \
+ redo_bases=`for i in $$bases; do \
+ am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \
+ done`; \
+ if test -n "$$redo_bases"; then \
+ redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \
+ redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \
+ if $(am__make_dryrun); then :; else \
+ rm -f $$redo_logs && rm -f $$redo_results || exit 1; \
+ fi; \
+ fi; \
+ if test -n "$$am__remaking_logs"; then \
+ echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
+ "recursion detected" >&2; \
+ else \
+ am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
+ fi; \
+ if $(am__make_dryrun); then :; else \
+ st=0; \
+ errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \
+ for i in $$redo_bases; do \
+ test -f $$i.trs && test -r $$i.trs \
+ || { echo "$$errmsg $$i.trs" >&2; st=1; }; \
+ test -f $$i.log && test -r $$i.log \
+ || { echo "$$errmsg $$i.log" >&2; st=1; }; \
+ done; \
+ test $$st -eq 0 || exit 1; \
+ fi
+ @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \
+ ws='[ ]'; \
+ results=`for b in $$bases; do echo $$b.trs; done`; \
+ test -n "$$results" || results=/dev/null; \
+ all=` grep "^$$ws*:test-result:" $$results | wc -l`; \
+ pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \
+ fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \
+ skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \
+ xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \
+ xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \
+ error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \
+ if test `expr $$fail + $$xpass + $$error` -eq 0; then \
+ success=true; \
+ else \
+ success=false; \
+ fi; \
+ br='==================='; br=$$br$$br$$br$$br; \
+ result_count () \
+ { \
+ if test x"$$1" = x"--maybe-color"; then \
+ maybe_colorize=yes; \
+ elif test x"$$1" = x"--no-color"; then \
+ maybe_colorize=no; \
+ else \
+ echo "$@: invalid 'result_count' usage" >&2; exit 4; \
+ fi; \
+ shift; \
+ desc=$$1 count=$$2; \
+ if test $$maybe_colorize = yes && test $$count -gt 0; then \
+ color_start=$$3 color_end=$$std; \
+ else \
+ color_start= color_end=; \
+ fi; \
+ echo "$${color_start}# $$desc $$count$${color_end}"; \
+ }; \
+ create_testsuite_report () \
+ { \
+ result_count $$1 "TOTAL:" $$all "$$brg"; \
+ result_count $$1 "PASS: " $$pass "$$grn"; \
+ result_count $$1 "SKIP: " $$skip "$$blu"; \
+ result_count $$1 "XFAIL:" $$xfail "$$lgn"; \
+ result_count $$1 "FAIL: " $$fail "$$red"; \
+ result_count $$1 "XPASS:" $$xpass "$$red"; \
+ result_count $$1 "ERROR:" $$error "$$mgn"; \
+ }; \
+ { \
+ echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \
+ $(am__rst_title); \
+ create_testsuite_report --no-color; \
+ echo; \
+ echo ".. contents:: :depth: 2"; \
+ echo; \
+ for b in $$bases; do echo $$b; done \
+ | $(am__create_global_log); \
+ } >$(TEST_SUITE_LOG).tmp || exit 1; \
+ mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \
+ if $$success; then \
+ col="$$grn"; \
+ else \
+ col="$$red"; \
+ test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \
+ fi; \
+ echo "$${col}$$br$${std}"; \
+ echo "$${col}Testsuite summary for $(PACKAGE_STRING)$${std}"; \
+ echo "$${col}$$br$${std}"; \
+ create_testsuite_report --maybe-color; \
+ echo "$$col$$br$$std"; \
+ if $$success; then :; else \
+ echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \
+ if test -n "$(PACKAGE_BUGREPORT)"; then \
+ echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \
+ fi; \
+ echo "$$col$$br$$std"; \
+ fi; \
+ $$success || exit 1
+
+check-TESTS:
+ @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list
+ @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ trs_list=`for i in $$bases; do echo $$i.trs; done`; \
+ log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \
+ exit $$?;
+recheck: all $(check_SCRIPTS)
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ bases=`for i in $$bases; do echo $$i; done \
+ | $(am__list_recheck_tests)` || exit 1; \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ log_list=`echo $$log_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \
+ am__force_recheck=am--force-recheck \
+ TEST_LOGS="$$log_list"; \
+ exit $$?
+test_lense.sh.log: test_lense.sh
+ @p='test_lense.sh'; \
+ b='test_lense.sh'; \
+ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+.test.log:
+ @p='$<'; \
+ $(am__set_b); \
+ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+@am__EXEEXT_TRUE@.test$(EXEEXT).log:
+@am__EXEEXT_TRUE@ @p='$<'; \
+@am__EXEEXT_TRUE@ $(am__set_b); \
+@am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+@am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \
+@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT)
+
+distdir: $(DISTFILES)
+ $(am__remove_distdir)
+ test -d "$(distdir)" || mkdir "$(distdir)"
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+ @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ $(am__make_dryrun) \
+ || test -d "$(distdir)/$$subdir" \
+ || $(MKDIR_P) "$(distdir)/$$subdir" \
+ || exit 1; \
+ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
+ $(am__relativize); \
+ new_distdir=$$reldir; \
+ dir1=$$subdir; dir2="$(top_distdir)"; \
+ $(am__relativize); \
+ new_top_distdir=$$reldir; \
+ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
+ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
+ ($(am__cd) $$subdir && \
+ $(MAKE) $(AM_MAKEFLAGS) \
+ top_distdir="$$new_top_distdir" \
+ distdir="$$new_distdir" \
+ am__remove_distdir=: \
+ am__skip_length_check=: \
+ am__skip_mode_fix=: \
+ distdir) \
+ || exit 1; \
+ fi; \
+ done
+ $(MAKE) $(AM_MAKEFLAGS) \
+ top_distdir="$(top_distdir)" distdir="$(distdir)" \
+ dist-hook
+ -test -n "$(am__skip_mode_fix)" \
+ || find "$(distdir)" -type d ! -perm -755 \
+ -exec chmod u+rwx,go+rx {} \; -o \
+ ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \
+ ! -type d ! -perm -400 -exec chmod a+r {} \; -o \
+ ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \
+ || chmod -R a+r "$(distdir)"
+dist-gzip: distdir
+ tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
+ $(am__post_remove_distdir)
+
+dist-bzip2: distdir
+ tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2
+ $(am__post_remove_distdir)
+
+dist-lzip: distdir
+ tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz
+ $(am__post_remove_distdir)
+
+dist-xz: distdir
+ tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz
+ $(am__post_remove_distdir)
+
+dist-tarZ: distdir
+ tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z
+ $(am__post_remove_distdir)
+
+dist-shar: distdir
+ shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz
+ $(am__post_remove_distdir)
+
+dist-zip: distdir
+ -rm -f $(distdir).zip
+ zip -rq $(distdir).zip $(distdir)
+ $(am__post_remove_distdir)
+
+dist dist-all:
+ $(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:'
+ $(am__post_remove_distdir)
+
+# This target untars the dist file and tries a VPATH configuration. Then
+# it guarantees that the distribution is self-contained by making another
+# tarfile.
+distcheck: dist
+ case '$(DIST_ARCHIVES)' in \
+ *.tar.gz*) \
+ GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\
+ *.tar.bz2*) \
+ bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\
+ *.tar.lz*) \
+ lzip -dc $(distdir).tar.lz | $(am__untar) ;;\
+ *.tar.xz*) \
+ xz -dc $(distdir).tar.xz | $(am__untar) ;;\
+ *.tar.Z*) \
+ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\
+ *.shar.gz*) \
+ GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\
+ *.zip*) \
+ unzip $(distdir).zip ;;\
+ esac
+ chmod -R a-w $(distdir)
+ chmod u+w $(distdir)
+ mkdir $(distdir)/_build $(distdir)/_inst
+ chmod a-w $(distdir)
+ test -d $(distdir)/_build || exit 0; \
+ dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \
+ && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \
+ && am__cwd=`pwd` \
+ && $(am__cd) $(distdir)/_build \
+ && ../configure --srcdir=.. --prefix="$$dc_install_base" \
+ $(AM_DISTCHECK_CONFIGURE_FLAGS) \
+ $(DISTCHECK_CONFIGURE_FLAGS) \
+ && $(MAKE) $(AM_MAKEFLAGS) \
+ && $(MAKE) $(AM_MAKEFLAGS) dvi \
+ && $(MAKE) $(AM_MAKEFLAGS) check \
+ && $(MAKE) $(AM_MAKEFLAGS) install \
+ && $(MAKE) $(AM_MAKEFLAGS) installcheck \
+ && $(MAKE) $(AM_MAKEFLAGS) uninstall \
+ && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \
+ distuninstallcheck \
+ && chmod -R a-w "$$dc_install_base" \
+ && ({ \
+ (cd ../.. && umask 077 && mkdir "$$dc_destdir") \
+ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \
+ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \
+ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \
+ distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \
+ } || { rm -rf "$$dc_destdir"; exit 1; }) \
+ && rm -rf "$$dc_destdir" \
+ && $(MAKE) $(AM_MAKEFLAGS) dist \
+ && rm -rf $(DIST_ARCHIVES) \
+ && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \
+ && cd "$$am__cwd" \
+ || exit 1
+ $(am__post_remove_distdir)
+ @(echo "$(distdir) archives ready for distribution: "; \
+ list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \
+ sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x'
+distuninstallcheck:
+ @test -n '$(distuninstallcheck_dir)' || { \
+ echo 'ERROR: trying to run $@ with an empty' \
+ '$$(distuninstallcheck_dir)' >&2; \
+ exit 1; \
+ }; \
+ $(am__cd) '$(distuninstallcheck_dir)' || { \
+ echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \
+ exit 1; \
+ }; \
+ test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \
+ || { echo "ERROR: files left after uninstall:" ; \
+ if test -n "$(DESTDIR)"; then \
+ echo " (check DESTDIR support)"; \
+ fi ; \
+ $(distuninstallcheck_listfiles) ; \
+ exit 1; } >&2
+distcleancheck: distclean
+ @if test '$(srcdir)' = . ; then \
+ echo "ERROR: distcleancheck can only run from a VPATH build" ; \
+ exit 1 ; \
+ fi
+ @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \
+ || { echo "ERROR: files left in build directory after distclean:" ; \
+ $(distcleancheck_listfiles) ; \
+ exit 1; } >&2
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) $(check_SCRIPTS)
+ $(MAKE) $(AM_MAKEFLAGS) check-TESTS
+check: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) check-recursive
+all-am: Makefile $(DATA)
+installdirs: installdirs-recursive
+installdirs-am:
+ for dir in "$(DESTDIR)$(docdir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-recursive
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+ -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS)
+ -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs)
+ -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+ -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
+ -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+clean: clean-recursive
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-recursive
+ -rm -f $(am__CONFIG_DISTCLEAN_FILES)
+ -rm -f Makefile
+distclean-am: clean-am distclean-generic distclean-hdr \
+ distclean-libtool distclean-tags
+
+dvi: dvi-recursive
+
+dvi-am:
+
+html: html-recursive
+
+html-am:
+
+info: info-recursive
+
+info-am:
+
+install-data-am: install-dist_docDATA
+
+install-dvi: install-dvi-recursive
+
+install-dvi-am:
+
+install-exec-am: install-exec-local
+
+install-html: install-html-recursive
+
+install-html-am:
+
+install-info: install-info-recursive
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-recursive
+
+install-pdf-am:
+
+install-ps: install-ps-recursive
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-recursive
+ -rm -f $(am__CONFIG_DISTCLEAN_FILES)
+ -rm -rf $(top_srcdir)/autom4te.cache
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic \
+ maintainer-clean-local
+
+mostlyclean: mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-recursive
+
+pdf-am:
+
+ps: ps-recursive
+
+ps-am:
+
+uninstall-am: uninstall-dist_docDATA uninstall-local
+
+.MAKE: $(am__recursive_targets) all check check-am install install-am \
+ install-strip
+
+.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \
+ am--refresh check check-TESTS check-am clean clean-cscope \
+ clean-generic clean-libtool cscope cscopelist-am ctags \
+ ctags-am dist dist-all dist-bzip2 dist-gzip dist-hook \
+ dist-lzip dist-shar dist-tarZ dist-xz dist-zip distcheck \
+ distclean distclean-generic distclean-hdr distclean-libtool \
+ distclean-tags distcleancheck distdir distuninstallcheck dvi \
+ dvi-am html html-am info info-am install install-am \
+ install-data install-data-am install-dist_docDATA install-dvi \
+ install-dvi-am install-exec install-exec-am install-exec-local \
+ install-html install-html-am install-info install-info-am \
+ install-man install-pdf install-pdf-am install-ps \
+ install-ps-am install-strip installcheck installcheck-am \
+ installdirs installdirs-am maintainer-clean \
+ maintainer-clean-generic maintainer-clean-local mostlyclean \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ recheck tags tags-am uninstall uninstall-am \
+ uninstall-dist_docDATA uninstall-local
+
+
+coverity:
+ rm -rf cov
+ make clean
+ cov-build --dir=cov make
+ cov-analyze --dir cov \
+ --concurrency \
+ -co BAD_FREE:allow_first_field:true \
+ --security \
+ --wait-for-license
+ cov-format-errors --dir cov
+
+coverity-aggressive:
+ rm -rf cov
+ make clean
+ cov-build --dir=cov make
+ cov-analyze --dir cov \
+ --concurrency \
+ --all \
+ --aggressiveness-level high \
+ --security \
+ --wait-for-license
+ cov-format-errors --dir cov
+
+install-exec-local:
+ $(INSTALL) -d $(DESTDIR)/${COROSYSCONFDIR}/service.d
+ $(INSTALL) -d $(DESTDIR)/${COROSYSCONFDIR}/uidgid.d
+ $(INSTALL) -d $(DESTDIR)/${localstatedir}/lib/corosync
+ $(INSTALL) -d $(DESTDIR)/${localstatedir}/log/cluster
+
+uninstall-local:
+ rmdir $(DESTDIR)/${COROSYSCONFDIR}/service.d || :;
+ rmdir $(DESTDIR)/${COROSYSCONFDIR}/uidgid.d || :;
+ rmdir $(DESTDIR)/${localstatedir}/lib/corosync || :;
+ rmdir $(DESTDIR)/${localstatedir}/log/cluster || :;
+
+@AUGTOOL_TRUE@test_lense.sh:
+@AUGTOOL_TRUE@ echo "augparse -I $(srcdir)/conf/lenses/ $(srcdir)/conf/lenses/tests/test_corosync.aug" > $@
+@AUGTOOL_TRUE@ chmod +x $@
+
+lint:
+ for dir in lib exec tools test; do make -C $$dir lint; done
+
+.PHONY: doxygen
+doxygen:
+ @if [ "$(DOXYGEN)" = "" ] || [ "$(DOT)" = "" ] ; then \
+ echo "*********************************************" ; \
+ echo "*** ***" ; \
+ echo "*** You must install doxygen and graphviz ***" ; \
+ echo "*** to generate the API documentation. ***" ; \
+ echo "*** ***" ; \
+ echo "*********************************************" ; \
+ exit 1 ; \
+ else \
+ mkdir -p doc/api && $(DOXYGEN) ; \
+ fi
+
+dist-clean-local:
+ rm -f autoconf automake autoheader test_lense.sh
+
+clean-generic:
+ rm -rf doc/api $(SPEC) $(TARFILE) test_lense.sh
+
+$(SPEC): $(SPEC).in
+ rm -f $@-t $@
+ date="$(shell LC_ALL=C date "+%a %b %d %Y")" && \
+ gvgver="`cd $(abs_srcdir); build-aux/git-version-gen --fallback $(VERSION) .tarball-version .gitarchivever`" && \
+ if [ "$$gvgver" = "`echo $$gvgver | sed 's/-/./'`" ];then \
+ rpmver="$$gvgver" && \
+ alphatag="" && \
+ dirty="" && \
+ numcomm="0"; \
+ else \
+ gitver="`echo $$gvgver | sed 's/\(.*\)\./\1-/'`" && \
+ rpmver=`echo $$gitver | sed 's/-.*//g'` && \
+ alphatag=`echo $$gvgver | sed 's/[^-]*-\([^-]*\).*/\1/'` && \
+ numcomm=`echo $$gitver | sed 's/[^-]*-\([^-]*\).*/\1/'` && \
+ dirty="" && \
+ if [ "`echo $$gitver | sed 's/^.*-dirty$$//g'`" = "" ];then \
+ dirty="dirty"; \
+ fi \
+ fi && \
+ if [ -n "$$dirty" ]; then dirty="dirty"; else dirty=""; fi && \
+ if [ "$$numcomm" = "0" ]; then numcomm=""; fi && \
+ if [ -n "$$numcomm" ]; then numcomm="%global numcomm $$numcomm"; fi && \
+ if [ "$$alphatag" = "$$gitver" ]; then alphatag=""; fi && \
+ if [ -n "$$alphatag" ]; then alphatag="%global alphatag $$alphatag"; fi && \
+ if [ -n "$$dirty" ]; then dirty="%global dirty dirty"; fi && \
+ $(SED) \
+ -e "s#@version@#$$rpmver#g" \
+ -e "s#@ALPHATAG@#$$alphatag#g" \
+ -e "s#@NUMCOMM@#$$numcomm#g" \
+ -e "s#@DIRTY@#$$dirty#g" \
+ -e "s#@date@#$$date#g" \
+ $< > $@-t; \
+ chmod a-w $@-t
+ mv $@-t $@
+
+$(TARFILE):
+ $(MAKE) dist
+
+srpm: clean
+ $(MAKE) $(SPEC) $(TARFILE)
+ rpmbuild $(WITH_LIST) $(RPMBUILDOPTS) --nodeps -bs $(SPEC)
+
+rpm: clean _version
+ $(MAKE) $(SPEC) $(TARFILE)
+ rpmbuild $(WITH_LIST) $(RPMBUILDOPTS) -ba $(SPEC)
+.version:
+ echo $(VERSION) > $@-t && mv $@-t $@
+
+dist-hook: gen-ChangeLog
+ echo $(VERSION) > $(distdir)/.tarball-version
+.PHONY: gen-ChangeLog _version
+gen-ChangeLog:
+ if test -d .git; then \
+ LC_ALL=C $(top_srcdir)/build-aux/gitlog-to-changelog \
+ --since=$(gen_start_date) > $(distdir)/cl-t; \
+ rm -f $(distdir)/ChangeLog; \
+ mv $(distdir)/cl-t $(distdir)/ChangeLog; \
+ fi
+
+_version:
+ cd $(srcdir) && rm -rf autom4te.cache .version && autoreconf -i
+ $(MAKE) $(AM_MAKEFLAGS) Makefile
+
+maintainer-clean-local:
+ rm -rf m4
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/README.recovery b/README.recovery
new file mode 100644
index 0000000..bda564b
--- /dev/null
+++ b/README.recovery
@@ -0,0 +1,116 @@
+SYNCHRONIZATION ALGORITHM:
+-------------------------
+The synchronization algorithm is used for every service in corosync to
+synchronize state of the system.
+
+There are 4 events of the synchronization algorithm. These events are in fact
+functions that are registered in the service handler data structure. They
+are called by the synchronization system whenever a network partitions or
+merges.
+
+init:
+Within the init event a service handler should record temporary state variables
+used by the process event.
+
+process:
+The process event is responsible for executing synchronization. This event
+will return a state as to whether it has completed or not. This allows for
+synchronization to be interrupted and recontinue when the message queue buffer
+is full. The process event will be called again by the synchronization service
+if requested to do so by the return variable returned in process.
+
+abort:
+The abort event occurs when during synchronization a processor failure occurs.
+
+activate:
+The activate event occurs when process has returned no more processing is
+necessary for any node in the cluster and all messages originated by process
+have completed.
+
+CHECKPOINT SYNCHRONIZATION ALGORITHM:
+------------------------------------
+The purpose of the checkpoint synchronization algorithm is to synchronize
+checkpoints after a partition or merge of two or more partitions. The
+secondary purpose of the algorithm is to determine the cluster-wide reference
+count for every checkpoint.
+
+Every cluster contains a group of checkpoints. Each checkpoint has a
+checkpoint name and checkpoint number. The number is used to uniquely reference
+an unlinked but still open checkpoint in the cluster.
+
+Every checkpoint contains a reference count which is used to determine when
+that checkpoint may be released. The algorithm rebuilds the reference count
+information each time a partition or merge occurs.
+
+local variables
+my_sync_state may have the values SYNC_CHECKPOINT, SYNC_REFCOUNT
+my_current_iteration_state contains any data used to iterate the checkpoints
+ and sections.
+checkpoint data
+ refcount_set contains reference count for every node consisting of
+ number of opened connections to checkpoint and node identifier
+ refcount contains a summation of every reference count in the refcount_set
+
+pseudocode executed by a processor when the synchronization service calls
+the init event
+ call process_checkpoints_enter
+
+pseudocode executed by a processor when the synchronization service calls
+the process event in the SYNC_CHECKPOINT state
+ if lowest processor identifier of old ring in new ring
+ transmit checkpoints or sections starting from my_current_iteration_state
+ if all checkpoints and sections could be queued
+ call sync_refcounts_enter
+ else
+ record my_current_iteration_state
+
+ require process to continue
+
+pseudocode executed by a processor when the synchronization service calls
+the process event in the SYNC_REFCOUNT state
+ if lowest processor identifier of old ring in new ring
+ transmit checkpoint reference counts
+ if all checkpoint reference counts could be queued
+ require process to not continue
+ else
+ record my_current_iteration_state for checkpoint reference counts
+
+sync_checkpoints_enter:
+ my_sync_state = SYNC_CHECKPOINT
+ my_current_iteration_state set to start of checkpoint list
+
+sync_refcounts_enter:
+ my_sync_state = SYNC_REFCOUNT
+
+on event receipt of foreign ring id message
+ ignore message
+
+pseudocode executed on event receipt of checkpoint update
+ if checkpoint exists in temporary storage
+ ignore message
+ else
+ create checkpoint
+ reset checkpoint refcount array
+
+pseudocode executed on event receipt of checkpoint section update
+ if checkpoint section exists in temporary storage
+ ignore message
+ else
+ create checkpoint section
+
+pseudocode executed on event receipt of reference count update
+ update temporary checkpoint data storage reference count set by adding
+ any reference counts in the temporary message set to those from the
+ event
+ update that checkpoint's reference count
+ set the global checkpoint id to the current checkpoint id + 1 if it
+ would increase the global checkpoint id
+
+pseudocode called when the synchronization service calls the activate event:
+for all checkpoints
+ free all previously committed checkpoints and sections
+ convert temporary checkpoints and sections to regular sections
+copy my_saved_ring_id to my_old_ring_id
+
+pseudocode called when the synchronization service calls the abort event:
+ free all temporary checkpoints and temporary sections
diff --git a/aclocal.m4 b/aclocal.m4
new file mode 100644
index 0000000..ef284d6
--- /dev/null
+++ b/aclocal.m4
@@ -0,0 +1,1244 @@
+# generated automatically by aclocal 1.13.4 -*- Autoconf -*-
+
+# Copyright (C) 1996-2013 Free Software Foundation, Inc.
+
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])])
+m4_ifndef([AC_AUTOCONF_VERSION],
+ [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
+m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],,
+[m4_warning([this file was generated for autoconf 2.69.
+You have another version of autoconf. It may work, but is not guaranteed to.
+If you have problems, you may need to regenerate the build system entirely.
+To do so, use the procedure documented by the package, typically 'autoreconf'.])])
+
+# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*-
+# serial 1 (pkg-config-0.24)
+#
+# Copyright © 2004 Scott James Remnant <scott@netsplit.com>.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# PKG_PROG_PKG_CONFIG([MIN-VERSION])
+# ----------------------------------
+AC_DEFUN([PKG_PROG_PKG_CONFIG],
+[m4_pattern_forbid([^_?PKG_[A-Z_]+$])
+m4_pattern_allow([^PKG_CONFIG(_(PATH|LIBDIR|SYSROOT_DIR|ALLOW_SYSTEM_(CFLAGS|LIBS)))?$])
+m4_pattern_allow([^PKG_CONFIG_(DISABLE_UNINSTALLED|TOP_BUILD_DIR|DEBUG_SPEW)$])
+AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility])
+AC_ARG_VAR([PKG_CONFIG_PATH], [directories to add to pkg-config's search path])
+AC_ARG_VAR([PKG_CONFIG_LIBDIR], [path overriding pkg-config's built-in search path])
+
+if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then
+ AC_PATH_TOOL([PKG_CONFIG], [pkg-config])
+fi
+if test -n "$PKG_CONFIG"; then
+ _pkg_min_version=m4_default([$1], [0.9.0])
+ AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version])
+ if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then
+ AC_MSG_RESULT([yes])
+ else
+ AC_MSG_RESULT([no])
+ PKG_CONFIG=""
+ fi
+fi[]dnl
+])# PKG_PROG_PKG_CONFIG
+
+# PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
+#
+# Check to see whether a particular set of modules exists. Similar
+# to PKG_CHECK_MODULES(), but does not set variables or print errors.
+#
+# Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG])
+# only at the first occurence in configure.ac, so if the first place
+# it's called might be skipped (such as if it is within an "if", you
+# have to call PKG_CHECK_EXISTS manually
+# --------------------------------------------------------------
+AC_DEFUN([PKG_CHECK_EXISTS],
+[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
+if test -n "$PKG_CONFIG" && \
+ AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then
+ m4_default([$2], [:])
+m4_ifvaln([$3], [else
+ $3])dnl
+fi])
+
+# _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES])
+# ---------------------------------------------
+m4_define([_PKG_CONFIG],
+[if test -n "$$1"; then
+ pkg_cv_[]$1="$$1"
+ elif test -n "$PKG_CONFIG"; then
+ PKG_CHECK_EXISTS([$3],
+ [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes ],
+ [pkg_failed=yes])
+ else
+ pkg_failed=untried
+fi[]dnl
+])# _PKG_CONFIG
+
+# _PKG_SHORT_ERRORS_SUPPORTED
+# -----------------------------
+AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED],
+[AC_REQUIRE([PKG_PROG_PKG_CONFIG])
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+ _pkg_short_errors_supported=yes
+else
+ _pkg_short_errors_supported=no
+fi[]dnl
+])# _PKG_SHORT_ERRORS_SUPPORTED
+
+
+# PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND],
+# [ACTION-IF-NOT-FOUND])
+#
+#
+# Note that if there is a possibility the first call to
+# PKG_CHECK_MODULES might not happen, you should be sure to include an
+# explicit call to PKG_PROG_PKG_CONFIG in your configure.ac
+#
+#
+# --------------------------------------------------------------
+AC_DEFUN([PKG_CHECK_MODULES],
+[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
+AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl
+AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl
+
+pkg_failed=no
+AC_MSG_CHECKING([for $1])
+
+_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2])
+_PKG_CONFIG([$1][_LIBS], [libs], [$2])
+
+m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS
+and $1[]_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details.])
+
+if test $pkg_failed = yes; then
+ AC_MSG_RESULT([no])
+ _PKG_SHORT_ERRORS_SUPPORTED
+ if test $_pkg_short_errors_supported = yes; then
+ $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1`
+ else
+ $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1`
+ fi
+ # Put the nasty error message in config.log where it belongs
+ echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD
+
+ m4_default([$4], [AC_MSG_ERROR(
+[Package requirements ($2) were not met:
+
+$$1_PKG_ERRORS
+
+Consider adjusting the PKG_CONFIG_PATH environment variable if you
+installed software in a non-standard prefix.
+
+_PKG_TEXT])[]dnl
+ ])
+elif test $pkg_failed = untried; then
+ AC_MSG_RESULT([no])
+ m4_default([$4], [AC_MSG_FAILURE(
+[The pkg-config script could not be found or is too old. Make sure it
+is in your PATH or set the PKG_CONFIG environment variable to the full
+path to pkg-config.
+
+_PKG_TEXT
+
+To get pkg-config, see <http://pkg-config.freedesktop.org/>.])[]dnl
+ ])
+else
+ $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS
+ $1[]_LIBS=$pkg_cv_[]$1[]_LIBS
+ AC_MSG_RESULT([yes])
+ $3
+fi[]dnl
+])# PKG_CHECK_MODULES
+
+
+# PKG_INSTALLDIR(DIRECTORY)
+# -------------------------
+# Substitutes the variable pkgconfigdir as the location where a module
+# should install pkg-config .pc files. By default the directory is
+# $libdir/pkgconfig, but the default can be changed by passing
+# DIRECTORY. The user can override through the --with-pkgconfigdir
+# parameter.
+AC_DEFUN([PKG_INSTALLDIR],
+[m4_pushdef([pkg_default], [m4_default([$1], ['${libdir}/pkgconfig'])])
+m4_pushdef([pkg_description],
+ [pkg-config installation directory @<:@]pkg_default[@:>@])
+AC_ARG_WITH([pkgconfigdir],
+ [AS_HELP_STRING([--with-pkgconfigdir], pkg_description)],,
+ [with_pkgconfigdir=]pkg_default)
+AC_SUBST([pkgconfigdir], [$with_pkgconfigdir])
+m4_popdef([pkg_default])
+m4_popdef([pkg_description])
+]) dnl PKG_INSTALLDIR
+
+
+# PKG_NOARCH_INSTALLDIR(DIRECTORY)
+# -------------------------
+# Substitutes the variable noarch_pkgconfigdir as the location where a
+# module should install arch-independent pkg-config .pc files. By
+# default the directory is $datadir/pkgconfig, but the default can be
+# changed by passing DIRECTORY. The user can override through the
+# --with-noarch-pkgconfigdir parameter.
+AC_DEFUN([PKG_NOARCH_INSTALLDIR],
+[m4_pushdef([pkg_default], [m4_default([$1], ['${datadir}/pkgconfig'])])
+m4_pushdef([pkg_description],
+ [pkg-config arch-independent installation directory @<:@]pkg_default[@:>@])
+AC_ARG_WITH([noarch-pkgconfigdir],
+ [AS_HELP_STRING([--with-noarch-pkgconfigdir], pkg_description)],,
+ [with_noarch_pkgconfigdir=]pkg_default)
+AC_SUBST([noarch_pkgconfigdir], [$with_noarch_pkgconfigdir])
+m4_popdef([pkg_default])
+m4_popdef([pkg_description])
+]) dnl PKG_NOARCH_INSTALLDIR
+
+# Copyright (C) 2002-2013 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_AUTOMAKE_VERSION(VERSION)
+# ----------------------------
+# Automake X.Y traces this macro to ensure aclocal.m4 has been
+# generated from the m4 files accompanying Automake X.Y.
+# (This private macro should not be called outside this file.)
+AC_DEFUN([AM_AUTOMAKE_VERSION],
+[am__api_version='1.13'
+dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
+dnl require some minimum version. Point them to the right macro.
+m4_if([$1], [1.13.4], [],
+ [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
+])
+
+# _AM_AUTOCONF_VERSION(VERSION)
+# -----------------------------
+# aclocal traces this macro to find the Autoconf version.
+# This is a private macro too. Using m4_define simplifies
+# the logic in aclocal, which can simply ignore this definition.
+m4_define([_AM_AUTOCONF_VERSION], [])
+
+# AM_SET_CURRENT_AUTOMAKE_VERSION
+# -------------------------------
+# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
+# This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
+AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
+[AM_AUTOMAKE_VERSION([1.13.4])dnl
+m4_ifndef([AC_AUTOCONF_VERSION],
+ [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
+_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
+
+# AM_AUX_DIR_EXPAND -*- Autoconf -*-
+
+# Copyright (C) 2001-2013 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets
+# $ac_aux_dir to '$srcdir/foo'. In other projects, it is set to
+# '$srcdir', '$srcdir/..', or '$srcdir/../..'.
+#
+# Of course, Automake must honor this variable whenever it calls a
+# tool from the auxiliary directory. The problem is that $srcdir (and
+# therefore $ac_aux_dir as well) can be either absolute or relative,
+# depending on how configure is run. This is pretty annoying, since
+# it makes $ac_aux_dir quite unusable in subdirectories: in the top
+# source directory, any form will work fine, but in subdirectories a
+# relative path needs to be adjusted first.
+#
+# $ac_aux_dir/missing
+# fails when called from a subdirectory if $ac_aux_dir is relative
+# $top_srcdir/$ac_aux_dir/missing
+# fails if $ac_aux_dir is absolute,
+# fails when called from a subdirectory in a VPATH build with
+# a relative $ac_aux_dir
+#
+# The reason of the latter failure is that $top_srcdir and $ac_aux_dir
+# are both prefixed by $srcdir. In an in-source build this is usually
+# harmless because $srcdir is '.', but things will broke when you
+# start a VPATH build or use an absolute $srcdir.
+#
+# So we could use something similar to $top_srcdir/$ac_aux_dir/missing,
+# iff we strip the leading $srcdir from $ac_aux_dir. That would be:
+# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"`
+# and then we would define $MISSING as
+# MISSING="\${SHELL} $am_aux_dir/missing"
+# This will work as long as MISSING is not called from configure, because
+# unfortunately $(top_srcdir) has no meaning in configure.
+# However there are other variables, like CC, which are often used in
+# configure, and could therefore not use this "fixed" $ac_aux_dir.
+#
+# Another solution, used here, is to always expand $ac_aux_dir to an
+# absolute PATH. The drawback is that using absolute paths prevent a
+# configured tree to be moved without reconfiguration.
+
+AC_DEFUN([AM_AUX_DIR_EXPAND],
+[dnl Rely on autoconf to set up CDPATH properly.
+AC_PREREQ([2.50])dnl
+# expand $ac_aux_dir to an absolute path
+am_aux_dir=`cd $ac_aux_dir && pwd`
+])
+
+# AM_CONDITIONAL -*- Autoconf -*-
+
+# Copyright (C) 1997-2013 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_CONDITIONAL(NAME, SHELL-CONDITION)
+# -------------------------------------
+# Define a conditional.
+AC_DEFUN([AM_CONDITIONAL],
+[AC_PREREQ([2.52])dnl
+ m4_if([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])],
+ [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl
+AC_SUBST([$1_TRUE])dnl
+AC_SUBST([$1_FALSE])dnl
+_AM_SUBST_NOTMAKE([$1_TRUE])dnl
+_AM_SUBST_NOTMAKE([$1_FALSE])dnl
+m4_define([_AM_COND_VALUE_$1], [$2])dnl
+if $2; then
+ $1_TRUE=
+ $1_FALSE='#'
+else
+ $1_TRUE='#'
+ $1_FALSE=
+fi
+AC_CONFIG_COMMANDS_PRE(
+[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then
+ AC_MSG_ERROR([[conditional "$1" was never defined.
+Usually this means the macro was only invoked conditionally.]])
+fi])])
+
+# Copyright (C) 1999-2013 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+
+# There are a few dirty hacks below to avoid letting 'AC_PROG_CC' be
+# written in clear, in which case automake, when reading aclocal.m4,
+# will think it sees a *use*, and therefore will trigger all it's
+# C support machinery. Also note that it means that autoscan, seeing
+# CC etc. in the Makefile, will ask for an AC_PROG_CC use...
+
+
+# _AM_DEPENDENCIES(NAME)
+# ----------------------
+# See how the compiler implements dependency checking.
+# NAME is "CC", "CXX", "OBJC", "OBJCXX", "UPC", or "GJC".
+# We try a few techniques and use that to set a single cache variable.
+#
+# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was
+# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular
+# dependency, and given that the user is not expected to run this macro,
+# just rely on AC_PROG_CC.
+AC_DEFUN([_AM_DEPENDENCIES],
+[AC_REQUIRE([AM_SET_DEPDIR])dnl
+AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl
+AC_REQUIRE([AM_MAKE_INCLUDE])dnl
+AC_REQUIRE([AM_DEP_TRACK])dnl
+
+m4_if([$1], [CC], [depcc="$CC" am_compiler_list=],
+ [$1], [CXX], [depcc="$CXX" am_compiler_list=],
+ [$1], [OBJC], [depcc="$OBJC" am_compiler_list='gcc3 gcc'],
+ [$1], [OBJCXX], [depcc="$OBJCXX" am_compiler_list='gcc3 gcc'],
+ [$1], [UPC], [depcc="$UPC" am_compiler_list=],
+ [$1], [GCJ], [depcc="$GCJ" am_compiler_list='gcc3 gcc'],
+ [depcc="$$1" am_compiler_list=])
+
+AC_CACHE_CHECK([dependency style of $depcc],
+ [am_cv_$1_dependencies_compiler_type],
+[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+ # We make a subdir and do the tests there. Otherwise we can end up
+ # making bogus files that we don't know about and never remove. For
+ # instance it was reported that on HP-UX the gcc test will end up
+ # making a dummy file named 'D' -- because '-MD' means "put the output
+ # in D".
+ rm -rf conftest.dir
+ mkdir conftest.dir
+ # Copy depcomp to subdir because otherwise we won't find it if we're
+ # using a relative directory.
+ cp "$am_depcomp" conftest.dir
+ cd conftest.dir
+ # We will build objects and dependencies in a subdirectory because
+ # it helps to detect inapplicable dependency modes. For instance
+ # both Tru64's cc and ICC support -MD to output dependencies as a
+ # side effect of compilation, but ICC will put the dependencies in
+ # the current directory while Tru64 will put them in the object
+ # directory.
+ mkdir sub
+
+ am_cv_$1_dependencies_compiler_type=none
+ if test "$am_compiler_list" = ""; then
+ am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp`
+ fi
+ am__universal=false
+ m4_case([$1], [CC],
+ [case " $depcc " in #(
+ *\ -arch\ *\ -arch\ *) am__universal=true ;;
+ esac],
+ [CXX],
+ [case " $depcc " in #(
+ *\ -arch\ *\ -arch\ *) am__universal=true ;;
+ esac])
+
+ for depmode in $am_compiler_list; do
+ # Setup a source with many dependencies, because some compilers
+ # like to wrap large dependency lists on column 80 (with \), and
+ # we should not choose a depcomp mode which is confused by this.
+ #
+ # We need to recreate these files for each test, as the compiler may
+ # overwrite some of them when testing with obscure command lines.
+ # This happens at least with the AIX C compiler.
+ : > sub/conftest.c
+ for i in 1 2 3 4 5 6; do
+ echo '#include "conftst'$i'.h"' >> sub/conftest.c
+ # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with
+ # Solaris 10 /bin/sh.
+ echo '/* dummy */' > sub/conftst$i.h
+ done
+ echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+ # We check with '-c' and '-o' for the sake of the "dashmstdout"
+ # mode. It turns out that the SunPro C++ compiler does not properly
+ # handle '-M -o', and we need to detect this. Also, some Intel
+ # versions had trouble with output in subdirs.
+ am__obj=sub/conftest.${OBJEXT-o}
+ am__minus_obj="-o $am__obj"
+ case $depmode in
+ gcc)
+ # This depmode causes a compiler race in universal mode.
+ test "$am__universal" = false || continue
+ ;;
+ nosideeffect)
+ # After this tag, mechanisms are not by side-effect, so they'll
+ # only be used when explicitly requested.
+ if test "x$enable_dependency_tracking" = xyes; then
+ continue
+ else
+ break
+ fi
+ ;;
+ msvc7 | msvc7msys | msvisualcpp | msvcmsys)
+ # This compiler won't grok '-c -o', but also, the minuso test has
+ # not run yet. These depmodes are late enough in the game, and
+ # so weak that their functioning should not be impacted.
+ am__obj=conftest.${OBJEXT-o}
+ am__minus_obj=
+ ;;
+ none) break ;;
+ esac
+ if depmode=$depmode \
+ source=sub/conftest.c object=$am__obj \
+ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \
+ >/dev/null 2>conftest.err &&
+ grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep $am__obj sub/conftest.Po > /dev/null 2>&1 &&
+ ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+ # icc doesn't choke on unknown options, it will just issue warnings
+ # or remarks (even with -Werror). So we grep stderr for any message
+ # that says an option was ignored or not supported.
+ # When given -MP, icc 7.0 and 7.1 complain thusly:
+ # icc: Command line warning: ignoring option '-M'; no argument required
+ # The diagnosis changed in icc 8.0:
+ # icc: Command line remark: option '-MP' not supported
+ if (grep 'ignoring option' conftest.err ||
+ grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
+ am_cv_$1_dependencies_compiler_type=$depmode
+ break
+ fi
+ fi
+ done
+
+ cd ..
+ rm -rf conftest.dir
+else
+ am_cv_$1_dependencies_compiler_type=none
+fi
+])
+AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type])
+AM_CONDITIONAL([am__fastdep$1], [
+ test "x$enable_dependency_tracking" != xno \
+ && test "$am_cv_$1_dependencies_compiler_type" = gcc3])
+])
+
+
+# AM_SET_DEPDIR
+# -------------
+# Choose a directory name for dependency files.
+# This macro is AC_REQUIREd in _AM_DEPENDENCIES.
+AC_DEFUN([AM_SET_DEPDIR],
+[AC_REQUIRE([AM_SET_LEADING_DOT])dnl
+AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl
+])
+
+
+# AM_DEP_TRACK
+# ------------
+AC_DEFUN([AM_DEP_TRACK],
+[AC_ARG_ENABLE([dependency-tracking], [dnl
+AS_HELP_STRING(
+ [--enable-dependency-tracking],
+ [do not reject slow dependency extractors])
+AS_HELP_STRING(
+ [--disable-dependency-tracking],
+ [speeds up one-time build])])
+if test "x$enable_dependency_tracking" != xno; then
+ am_depcomp="$ac_aux_dir/depcomp"
+ AMDEPBACKSLASH='\'
+ am__nodep='_no'
+fi
+AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno])
+AC_SUBST([AMDEPBACKSLASH])dnl
+_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl
+AC_SUBST([am__nodep])dnl
+_AM_SUBST_NOTMAKE([am__nodep])dnl
+])
+
+# Generate code to set up dependency tracking. -*- Autoconf -*-
+
+# Copyright (C) 1999-2013 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+
+# _AM_OUTPUT_DEPENDENCY_COMMANDS
+# ------------------------------
+AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
+[{
+ # Older Autoconf quotes --file arguments for eval, but not when files
+ # are listed without --file. Let's play safe and only enable the eval
+ # if we detect the quoting.
+ case $CONFIG_FILES in
+ *\'*) eval set x "$CONFIG_FILES" ;;
+ *) set x $CONFIG_FILES ;;
+ esac
+ shift
+ for mf
+ do
+ # Strip MF so we end up with the name of the file.
+ mf=`echo "$mf" | sed -e 's/:.*$//'`
+ # Check whether this is an Automake generated Makefile or not.
+ # We used to match only the files named 'Makefile.in', but
+ # some people rename them; so instead we look at the file content.
+ # Grep'ing the first line is not enough: some people post-process
+ # each Makefile.in and add a new line on top of each file to say so.
+ # Grep'ing the whole file is not good either: AIX grep has a line
+ # limit of 2048, but all sed's we know have understand at least 4000.
+ if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then
+ dirpart=`AS_DIRNAME("$mf")`
+ else
+ continue
+ fi
+ # Extract the definition of DEPDIR, am__include, and am__quote
+ # from the Makefile without running 'make'.
+ DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
+ test -z "$DEPDIR" && continue
+ am__include=`sed -n 's/^am__include = //p' < "$mf"`
+ test -z "$am__include" && continue
+ am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
+ # Find all dependency output files, they are included files with
+ # $(DEPDIR) in their names. We invoke sed twice because it is the
+ # simplest approach to changing $(DEPDIR) to its actual value in the
+ # expansion.
+ for file in `sed -n "
+ s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
+ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do
+ # Make sure the directory exists.
+ test -f "$dirpart/$file" && continue
+ fdir=`AS_DIRNAME(["$file"])`
+ AS_MKDIR_P([$dirpart/$fdir])
+ # echo "creating $dirpart/$file"
+ echo '# dummy' > "$dirpart/$file"
+ done
+ done
+}
+])# _AM_OUTPUT_DEPENDENCY_COMMANDS
+
+
+# AM_OUTPUT_DEPENDENCY_COMMANDS
+# -----------------------------
+# This macro should only be invoked once -- use via AC_REQUIRE.
+#
+# This code is only required when automatic dependency tracking
+# is enabled. FIXME. This creates each '.P' file that we will
+# need in order to bootstrap the dependency handling code.
+AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
+[AC_CONFIG_COMMANDS([depfiles],
+ [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS],
+ [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"])
+])
+
+# Do all the work for Automake. -*- Autoconf -*-
+
+# Copyright (C) 1996-2013 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This macro actually does too much. Some checks are only needed if
+# your package does certain things. But this isn't really a big deal.
+
+# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE])
+# AM_INIT_AUTOMAKE([OPTIONS])
+# -----------------------------------------------
+# The call with PACKAGE and VERSION arguments is the old style
+# call (pre autoconf-2.50), which is being phased out. PACKAGE
+# and VERSION should now be passed to AC_INIT and removed from
+# the call to AM_INIT_AUTOMAKE.
+# We support both call styles for the transition. After
+# the next Automake release, Autoconf can make the AC_INIT
+# arguments mandatory, and then we can depend on a new Autoconf
+# release and drop the old call support.
+AC_DEFUN([AM_INIT_AUTOMAKE],
+[AC_PREREQ([2.65])dnl
+dnl Autoconf wants to disallow AM_ names. We explicitly allow
+dnl the ones we care about.
+m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl
+AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl
+AC_REQUIRE([AC_PROG_INSTALL])dnl
+if test "`cd $srcdir && pwd`" != "`pwd`"; then
+ # Use -I$(srcdir) only when $(srcdir) != ., so that make's output
+ # is not polluted with repeated "-I."
+ AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl
+ # test to see if srcdir already configured
+ if test -f $srcdir/config.status; then
+ AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
+ fi
+fi
+
+# test whether we have cygpath
+if test -z "$CYGPATH_W"; then
+ if (cygpath --version) >/dev/null 2>/dev/null; then
+ CYGPATH_W='cygpath -w'
+ else
+ CYGPATH_W=echo
+ fi
+fi
+AC_SUBST([CYGPATH_W])
+
+# Define the identity of the package.
+dnl Distinguish between old-style and new-style calls.
+m4_ifval([$2],
+[AC_DIAGNOSE([obsolete],
+ [$0: two- and three-arguments forms are deprecated.])
+m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl
+ AC_SUBST([PACKAGE], [$1])dnl
+ AC_SUBST([VERSION], [$2])],
+[_AM_SET_OPTIONS([$1])dnl
+dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT.
+m4_if(
+ m4_ifdef([AC_PACKAGE_NAME], [ok]):m4_ifdef([AC_PACKAGE_VERSION], [ok]),
+ [ok:ok],,
+ [m4_fatal([AC_INIT should be called with package and version arguments])])dnl
+ AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl
+ AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl
+
+_AM_IF_OPTION([no-define],,
+[AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package])
+ AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [Version number of package])])dnl
+
+# Some tools Automake needs.
+AC_REQUIRE([AM_SANITY_CHECK])dnl
+AC_REQUIRE([AC_ARG_PROGRAM])dnl
+AM_MISSING_PROG([ACLOCAL], [aclocal-${am__api_version}])
+AM_MISSING_PROG([AUTOCONF], [autoconf])
+AM_MISSING_PROG([AUTOMAKE], [automake-${am__api_version}])
+AM_MISSING_PROG([AUTOHEADER], [autoheader])
+AM_MISSING_PROG([MAKEINFO], [makeinfo])
+AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
+AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl
+AC_REQUIRE([AC_PROG_MKDIR_P])dnl
+# For better backward compatibility. To be removed once Automake 1.9.x
+# dies out for good. For more background, see:
+# <http://lists.gnu.org/archive/html/automake/2012-07/msg00001.html>
+# <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
+AC_SUBST([mkdir_p], ['$(MKDIR_P)'])
+# We need awk for the "check" target. The system "awk" is bad on
+# some platforms.
+AC_REQUIRE([AC_PROG_AWK])dnl
+AC_REQUIRE([AC_PROG_MAKE_SET])dnl
+AC_REQUIRE([AM_SET_LEADING_DOT])dnl
+_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])],
+ [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])],
+ [_AM_PROG_TAR([v7])])])
+_AM_IF_OPTION([no-dependencies],,
+[AC_PROVIDE_IFELSE([AC_PROG_CC],
+ [_AM_DEPENDENCIES([CC])],
+ [m4_define([AC_PROG_CC],
+ m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_CXX],
+ [_AM_DEPENDENCIES([CXX])],
+ [m4_define([AC_PROG_CXX],
+ m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_OBJC],
+ [_AM_DEPENDENCIES([OBJC])],
+ [m4_define([AC_PROG_OBJC],
+ m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_OBJCXX],
+ [_AM_DEPENDENCIES([OBJCXX])],
+ [m4_define([AC_PROG_OBJCXX],
+ m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl
+])
+AC_REQUIRE([AM_SILENT_RULES])dnl
+dnl The testsuite driver may need to know about EXEEXT, so add the
+dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This
+dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below.
+AC_CONFIG_COMMANDS_PRE(dnl
+[m4_provide_if([_AM_COMPILER_EXEEXT],
+ [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl
+])
+
+dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not
+dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further
+dnl mangled by Autoconf and run in a shell conditional statement.
+m4_define([_AC_COMPILER_EXEEXT],
+m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])])
+
+
+# When config.status generates a header, we must update the stamp-h file.
+# This file resides in the same directory as the config header
+# that is generated. The stamp files are numbered to have different names.
+
+# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the
+# loop where config.status creates the headers, so we can generate
+# our stamp files there.
+AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK],
+[# Compute $1's index in $config_headers.
+_am_arg=$1
+_am_stamp_count=1
+for _am_header in $config_headers :; do
+ case $_am_header in
+ $_am_arg | $_am_arg:* )
+ break ;;
+ * )
+ _am_stamp_count=`expr $_am_stamp_count + 1` ;;
+ esac
+done
+echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count])
+
+# Copyright (C) 2001-2013 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_PROG_INSTALL_SH
+# ------------------
+# Define $install_sh.
+AC_DEFUN([AM_PROG_INSTALL_SH],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+if test x"${install_sh}" != xset; then
+ case $am_aux_dir in
+ *\ * | *\ *)
+ install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;;
+ *)
+ install_sh="\${SHELL} $am_aux_dir/install-sh"
+ esac
+fi
+AC_SUBST([install_sh])])
+
+# Copyright (C) 2003-2013 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# Check whether the underlying file-system supports filenames
+# with a leading dot. For instance MS-DOS doesn't.
+AC_DEFUN([AM_SET_LEADING_DOT],
+[rm -rf .tst 2>/dev/null
+mkdir .tst 2>/dev/null
+if test -d .tst; then
+ am__leading_dot=.
+else
+ am__leading_dot=_
+fi
+rmdir .tst 2>/dev/null
+AC_SUBST([am__leading_dot])])
+
+# Check to see how 'make' treats includes. -*- Autoconf -*-
+
+# Copyright (C) 2001-2013 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_MAKE_INCLUDE()
+# -----------------
+# Check to see how make treats includes.
+AC_DEFUN([AM_MAKE_INCLUDE],
+[am_make=${MAKE-make}
+cat > confinc << 'END'
+am__doit:
+ @echo this is the am__doit target
+.PHONY: am__doit
+END
+# If we don't find an include directive, just comment out the code.
+AC_MSG_CHECKING([for style of include used by $am_make])
+am__include="#"
+am__quote=
+_am_result=none
+# First try GNU make style include.
+echo "include confinc" > confmf
+# Ignore all kinds of additional output from 'make'.
+case `$am_make -s -f confmf 2> /dev/null` in #(
+*the\ am__doit\ target*)
+ am__include=include
+ am__quote=
+ _am_result=GNU
+ ;;
+esac
+# Now try BSD make style include.
+if test "$am__include" = "#"; then
+ echo '.include "confinc"' > confmf
+ case `$am_make -s -f confmf 2> /dev/null` in #(
+ *the\ am__doit\ target*)
+ am__include=.include
+ am__quote="\""
+ _am_result=BSD
+ ;;
+ esac
+fi
+AC_SUBST([am__include])
+AC_SUBST([am__quote])
+AC_MSG_RESULT([$_am_result])
+rm -f confinc confmf
+])
+
+# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*-
+
+# Copyright (C) 1997-2013 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_MISSING_PROG(NAME, PROGRAM)
+# ------------------------------
+AC_DEFUN([AM_MISSING_PROG],
+[AC_REQUIRE([AM_MISSING_HAS_RUN])
+$1=${$1-"${am_missing_run}$2"}
+AC_SUBST($1)])
+
+# AM_MISSING_HAS_RUN
+# ------------------
+# Define MISSING if not defined so far and test if it is modern enough.
+# If it is, set am_missing_run to use it, otherwise, to nothing.
+AC_DEFUN([AM_MISSING_HAS_RUN],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+AC_REQUIRE_AUX_FILE([missing])dnl
+if test x"${MISSING+set}" != xset; then
+ case $am_aux_dir in
+ *\ * | *\ *)
+ MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;;
+ *)
+ MISSING="\${SHELL} $am_aux_dir/missing" ;;
+ esac
+fi
+# Use eval to expand $SHELL
+if eval "$MISSING --is-lightweight"; then
+ am_missing_run="$MISSING "
+else
+ am_missing_run=
+ AC_MSG_WARN(['missing' script is too old or missing])
+fi
+])
+
+# Helper functions for option handling. -*- Autoconf -*-
+
+# Copyright (C) 2001-2013 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# _AM_MANGLE_OPTION(NAME)
+# -----------------------
+AC_DEFUN([_AM_MANGLE_OPTION],
+[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])])
+
+# _AM_SET_OPTION(NAME)
+# --------------------
+# Set option NAME. Presently that only means defining a flag for this option.
+AC_DEFUN([_AM_SET_OPTION],
+[m4_define(_AM_MANGLE_OPTION([$1]), [1])])
+
+# _AM_SET_OPTIONS(OPTIONS)
+# ------------------------
+# OPTIONS is a space-separated list of Automake options.
+AC_DEFUN([_AM_SET_OPTIONS],
+[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])])
+
+# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET])
+# -------------------------------------------
+# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
+AC_DEFUN([_AM_IF_OPTION],
+[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
+
+# Check to make sure that the build environment is sane. -*- Autoconf -*-
+
+# Copyright (C) 1996-2013 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_SANITY_CHECK
+# ---------------
+AC_DEFUN([AM_SANITY_CHECK],
+[AC_MSG_CHECKING([whether build environment is sane])
+# Reject unsafe characters in $srcdir or the absolute working directory
+# name. Accept space and tab only in the latter.
+am_lf='
+'
+case `pwd` in
+ *[[\\\"\#\$\&\'\`$am_lf]]*)
+ AC_MSG_ERROR([unsafe absolute working directory name]);;
+esac
+case $srcdir in
+ *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*)
+ AC_MSG_ERROR([unsafe srcdir value: '$srcdir']);;
+esac
+
+# Do 'set' in a subshell so we don't clobber the current shell's
+# arguments. Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+ am_has_slept=no
+ for am_try in 1 2; do
+ echo "timestamp, slept: $am_has_slept" > conftest.file
+ set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null`
+ if test "$[*]" = "X"; then
+ # -L didn't work.
+ set X `ls -t "$srcdir/configure" conftest.file`
+ fi
+ if test "$[*]" != "X $srcdir/configure conftest.file" \
+ && test "$[*]" != "X conftest.file $srcdir/configure"; then
+
+ # If neither matched, then we have a broken ls. This can happen
+ # if, for instance, CONFIG_SHELL is bash and it inherits a
+ # broken ls alias from the environment. This has actually
+ # happened. Such a system could not be considered "sane".
+ AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken
+ alias in your environment])
+ fi
+ if test "$[2]" = conftest.file || test $am_try -eq 2; then
+ break
+ fi
+ # Just in case.
+ sleep 1
+ am_has_slept=yes
+ done
+ test "$[2]" = conftest.file
+ )
+then
+ # Ok.
+ :
+else
+ AC_MSG_ERROR([newly created file is older than distributed files!
+Check your system clock])
+fi
+AC_MSG_RESULT([yes])
+# If we didn't sleep, we still need to ensure time stamps of config.status and
+# generated files are strictly newer.
+am_sleep_pid=
+if grep 'slept: no' conftest.file >/dev/null 2>&1; then
+ ( sleep 1 ) &
+ am_sleep_pid=$!
+fi
+AC_CONFIG_COMMANDS_PRE(
+ [AC_MSG_CHECKING([that generated files are newer than configure])
+ if test -n "$am_sleep_pid"; then
+ # Hide warnings about reused PIDs.
+ wait $am_sleep_pid 2>/dev/null
+ fi
+ AC_MSG_RESULT([done])])
+rm -f conftest.file
+])
+
+# Copyright (C) 2009-2013 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_SILENT_RULES([DEFAULT])
+# --------------------------
+# Enable less verbose build rules; with the default set to DEFAULT
+# ("yes" being less verbose, "no" or empty being verbose).
+AC_DEFUN([AM_SILENT_RULES],
+[AC_ARG_ENABLE([silent-rules], [dnl
+AS_HELP_STRING(
+ [--enable-silent-rules],
+ [less verbose build output (undo: "make V=1")])
+AS_HELP_STRING(
+ [--disable-silent-rules],
+ [verbose build output (undo: "make V=0")])dnl
+])
+case $enable_silent_rules in @%:@ (((
+ yes) AM_DEFAULT_VERBOSITY=0;;
+ no) AM_DEFAULT_VERBOSITY=1;;
+ *) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);;
+esac
+dnl
+dnl A few 'make' implementations (e.g., NonStop OS and NextStep)
+dnl do not support nested variable expansions.
+dnl See automake bug#9928 and bug#10237.
+am_make=${MAKE-make}
+AC_CACHE_CHECK([whether $am_make supports nested variables],
+ [am_cv_make_support_nested_variables],
+ [if AS_ECHO([['TRUE=$(BAR$(V))
+BAR0=false
+BAR1=true
+V=1
+am__doit:
+ @$(TRUE)
+.PHONY: am__doit']]) | $am_make -f - >/dev/null 2>&1; then
+ am_cv_make_support_nested_variables=yes
+else
+ am_cv_make_support_nested_variables=no
+fi])
+if test $am_cv_make_support_nested_variables = yes; then
+ dnl Using '$V' instead of '$(V)' breaks IRIX make.
+ AM_V='$(V)'
+ AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)'
+else
+ AM_V=$AM_DEFAULT_VERBOSITY
+ AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY
+fi
+AC_SUBST([AM_V])dnl
+AM_SUBST_NOTMAKE([AM_V])dnl
+AC_SUBST([AM_DEFAULT_V])dnl
+AM_SUBST_NOTMAKE([AM_DEFAULT_V])dnl
+AC_SUBST([AM_DEFAULT_VERBOSITY])dnl
+AM_BACKSLASH='\'
+AC_SUBST([AM_BACKSLASH])dnl
+_AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl
+])
+
+# Copyright (C) 2001-2013 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_PROG_INSTALL_STRIP
+# ---------------------
+# One issue with vendor 'install' (even GNU) is that you can't
+# specify the program used to strip binaries. This is especially
+# annoying in cross-compiling environments, where the build's strip
+# is unlikely to handle the host's binaries.
+# Fortunately install-sh will honor a STRIPPROG variable, so we
+# always use install-sh in "make install-strip", and initialize
+# STRIPPROG with the value of the STRIP variable (set by the user).
+AC_DEFUN([AM_PROG_INSTALL_STRIP],
+[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
+# Installed binaries are usually stripped using 'strip' when the user
+# run "make install-strip". However 'strip' might not be the right
+# tool to use in cross-compilation environments, therefore Automake
+# will honor the 'STRIP' environment variable to overrule this program.
+dnl Don't test for $cross_compiling = yes, because it might be 'maybe'.
+if test "$cross_compiling" != no; then
+ AC_CHECK_TOOL([STRIP], [strip], :)
+fi
+INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
+AC_SUBST([INSTALL_STRIP_PROGRAM])])
+
+# Copyright (C) 2006-2013 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# _AM_SUBST_NOTMAKE(VARIABLE)
+# ---------------------------
+# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in.
+# This macro is traced by Automake.
+AC_DEFUN([_AM_SUBST_NOTMAKE])
+
+# AM_SUBST_NOTMAKE(VARIABLE)
+# --------------------------
+# Public sister of _AM_SUBST_NOTMAKE.
+AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])
+
+# Check how to create a tarball. -*- Autoconf -*-
+
+# Copyright (C) 2004-2013 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# _AM_PROG_TAR(FORMAT)
+# --------------------
+# Check how to create a tarball in format FORMAT.
+# FORMAT should be one of 'v7', 'ustar', or 'pax'.
+#
+# Substitute a variable $(am__tar) that is a command
+# writing to stdout a FORMAT-tarball containing the directory
+# $tardir.
+# tardir=directory && $(am__tar) > result.tar
+#
+# Substitute a variable $(am__untar) that extract such
+# a tarball read from stdin.
+# $(am__untar) < result.tar
+#
+AC_DEFUN([_AM_PROG_TAR],
+[# Always define AMTAR for backward compatibility. Yes, it's still used
+# in the wild :-( We should find a proper way to deprecate it ...
+AC_SUBST([AMTAR], ['$${TAR-tar}'])
+
+# We'll loop over all known methods to create a tar archive until one works.
+_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none'
+
+m4_if([$1], [v7],
+ [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'],
+
+ [m4_case([$1],
+ [ustar],
+ [# The POSIX 1988 'ustar' format is defined with fixed-size fields.
+ # There is notably a 21 bits limit for the UID and the GID. In fact,
+ # the 'pax' utility can hang on bigger UID/GID (see automake bug#8343
+ # and bug#13588).
+ am_max_uid=2097151 # 2^21 - 1
+ am_max_gid=$am_max_uid
+ # The $UID and $GID variables are not portable, so we need to resort
+ # to the POSIX-mandated id(1) utility. Errors in the 'id' calls
+ # below are definitely unexpected, so allow the users to see them
+ # (that is, avoid stderr redirection).
+ am_uid=`id -u || echo unknown`
+ am_gid=`id -g || echo unknown`
+ AC_MSG_CHECKING([whether UID '$am_uid' is supported by ustar format])
+ if test $am_uid -le $am_max_uid; then
+ AC_MSG_RESULT([yes])
+ else
+ AC_MSG_RESULT([no])
+ _am_tools=none
+ fi
+ AC_MSG_CHECKING([whether GID '$am_gid' is supported by ustar format])
+ if test $am_gid -le $am_max_gid; then
+ AC_MSG_RESULT([yes])
+ else
+ AC_MSG_RESULT([no])
+ _am_tools=none
+ fi],
+
+ [pax],
+ [],
+
+ [m4_fatal([Unknown tar format])])
+
+ AC_MSG_CHECKING([how to create a $1 tar archive])
+
+ # Go ahead even if we have the value already cached. We do so because we
+ # need to set the values for the 'am__tar' and 'am__untar' variables.
+ _am_tools=${am_cv_prog_tar_$1-$_am_tools}
+
+ for _am_tool in $_am_tools; do
+ case $_am_tool in
+ gnutar)
+ for _am_tar in tar gnutar gtar; do
+ AM_RUN_LOG([$_am_tar --version]) && break
+ done
+ am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"'
+ am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"'
+ am__untar="$_am_tar -xf -"
+ ;;
+ plaintar)
+ # Must skip GNU tar: if it does not support --format= it doesn't create
+ # ustar tarball either.
+ (tar --version) >/dev/null 2>&1 && continue
+ am__tar='tar chf - "$$tardir"'
+ am__tar_='tar chf - "$tardir"'
+ am__untar='tar xf -'
+ ;;
+ pax)
+ am__tar='pax -L -x $1 -w "$$tardir"'
+ am__tar_='pax -L -x $1 -w "$tardir"'
+ am__untar='pax -r'
+ ;;
+ cpio)
+ am__tar='find "$$tardir" -print | cpio -o -H $1 -L'
+ am__tar_='find "$tardir" -print | cpio -o -H $1 -L'
+ am__untar='cpio -i -H $1 -d'
+ ;;
+ none)
+ am__tar=false
+ am__tar_=false
+ am__untar=false
+ ;;
+ esac
+
+ # If the value was cached, stop now. We just wanted to have am__tar
+ # and am__untar set.
+ test -n "${am_cv_prog_tar_$1}" && break
+
+ # tar/untar a dummy directory, and stop if the command works.
+ rm -rf conftest.dir
+ mkdir conftest.dir
+ echo GrepMe > conftest.dir/file
+ AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar])
+ rm -rf conftest.dir
+ if test -s conftest.tar; then
+ AM_RUN_LOG([$am__untar <conftest.tar])
+ AM_RUN_LOG([cat conftest.dir/file])
+ grep GrepMe conftest.dir/file >/dev/null 2>&1 && break
+ fi
+ done
+ rm -rf conftest.dir
+
+ AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool])
+ AC_MSG_RESULT([$am_cv_prog_tar_$1])])
+
+AC_SUBST([am__tar])
+AC_SUBST([am__untar])
+]) # _AM_PROG_TAR
+
+m4_include([m4/libtool.m4])
+m4_include([m4/ltoptions.m4])
+m4_include([m4/ltsugar.m4])
+m4_include([m4/ltversion.m4])
+m4_include([m4/lt~obsolete.m4])
diff --git a/autogen.sh b/autogen.sh
new file mode 100755
index 0000000..35f44b3
--- /dev/null
+++ b/autogen.sh
@@ -0,0 +1,5 @@
+#!/bin/sh
+# Run this to generate all the initial makefiles, etc.
+mkdir -p m4
+echo Building configuration system...
+autoreconf -i && echo Now run ./configure and make
diff --git a/bindings/Makefile.am b/bindings/Makefile.am
new file mode 100644
index 0000000..0ba6aac
--- /dev/null
+++ b/bindings/Makefile.am
@@ -0,0 +1,15 @@
+#
+# Copyright (C) 2022-2023 Red Hat, Inc. All rights reserved.
+#
+# Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+#
+# This software licensed under GPL-2.0+
+#
+
+MAINTAINERCLEANFILES = Makefile.in
+
+SUBDIRS = .
+
+if BUILD_RUST_BINDINGS
+SUBDIRS += rust
+endif
diff --git a/bindings/Makefile.in b/bindings/Makefile.in
new file mode 100644
index 0000000..4a7dace
--- /dev/null
+++ b/bindings/Makefile.in
@@ -0,0 +1,670 @@
+# Makefile.in generated by automake 1.13.4 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+#
+# Copyright (C) 2022-2023 Red Hat, Inc. All rights reserved.
+#
+# Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+#
+# This software licensed under GPL-2.0+
+#
+VPATH = @srcdir@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+@BUILD_RUST_BINDINGS_TRUE@am__append_1 = rust
+subdir = bindings
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/lib/libcfg.verso $(top_srcdir)/lib/libcpg.verso \
+ $(top_srcdir)/lib/libquorum.verso \
+ $(top_srcdir)/lib/libsam.verso \
+ $(top_srcdir)/lib/libvotequorum.verso \
+ $(top_srcdir)/lib/libcmap.verso $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/include/corosync/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+SOURCES =
+DIST_SOURCES =
+RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \
+ ctags-recursive dvi-recursive html-recursive info-recursive \
+ install-data-recursive install-dvi-recursive \
+ install-exec-recursive install-html-recursive \
+ install-info-recursive install-pdf-recursive \
+ install-ps-recursive install-recursive installcheck-recursive \
+ installdirs-recursive pdf-recursive ps-recursive \
+ tags-recursive uninstall-recursive
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
+ distclean-recursive maintainer-clean-recursive
+am__recursive_targets = \
+ $(RECURSIVE_TARGETS) \
+ $(RECURSIVE_CLEAN_TARGETS) \
+ $(am__extra_recursive_targets)
+AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \
+ distdir
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+DIST_SUBDIRS = . rust
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+am__relativize = \
+ dir0=`pwd`; \
+ sed_first='s,^\([^/]*\)/.*$$,\1,'; \
+ sed_rest='s,^[^/]*/*,,'; \
+ sed_last='s,^.*/\([^/]*\)$$,\1,'; \
+ sed_butlast='s,/*[^/]*$$,,'; \
+ while test -n "$$dir1"; do \
+ first=`echo "$$dir1" | sed -e "$$sed_first"`; \
+ if test "$$first" != "."; then \
+ if test "$$first" = ".."; then \
+ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
+ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
+ else \
+ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
+ if test "$$first2" = "$$first"; then \
+ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
+ else \
+ dir2="../$$dir2"; \
+ fi; \
+ dir0="$$dir0"/"$$first"; \
+ fi; \
+ fi; \
+ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
+ done; \
+ reldir="$$dir2"
+ACLOCAL = @ACLOCAL@
+ALLOCA = @ALLOCA@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUGTOOL = @AUGTOOL@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BASHPATH = @BASHPATH@
+BINDGEN = @BINDGEN@
+CARGO = @CARGO@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFG_SONAME = @CFG_SONAME@
+CFLAGS = @CFLAGS@
+CLIPPY = @CLIPPY@
+CMAP_SONAME = @CMAP_SONAME@
+COROSYSCONFDIR = @COROSYSCONFDIR@
+CPG_SONAME = @CPG_SONAME@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DBUS_CFLAGS = @DBUS_CFLAGS@
+DBUS_LIBS = @DBUS_LIBS@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DOT = @DOT@
+DOXYGEN = @DOXYGEN@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GREP = @GREP@
+GROFF = @GROFF@
+INITCONFIGDIR = @INITCONFIGDIR@
+INITDDIR = @INITDDIR@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBQB_CFLAGS = @LIBQB_CFLAGS@
+LIBQB_LIBS = @LIBQB_LIBS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LINT_FLAGS = @LINT_FLAGS@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LOGDIR = @LOGDIR@
+LOGROTATEDIR = @LOGROTATEDIR@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+QUORUM_SONAME = @QUORUM_SONAME@
+RANLIB = @RANLIB@
+RUSTC = @RUSTC@
+RUSTDOC = @RUSTDOC@
+RUSTFMT = @RUSTFMT@
+RUST_FLAGS = @RUST_FLAGS@
+RUST_TARGET_DIR = @RUST_TARGET_DIR@
+SAM_SONAME = @SAM_SONAME@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SNMPCONFIG = @SNMPCONFIG@
+SNMP_LIBS = @SNMP_LIBS@
+SOMAJOR = @SOMAJOR@
+SOMICRO = @SOMICRO@
+SOMINOR = @SOMINOR@
+SONAME = @SONAME@
+STRIP = @STRIP@
+SYSTEMDDIR = @SYSTEMDDIR@
+VERSCRIPT_LDFLAGS = @VERSCRIPT_LDFLAGS@
+VERSION = @VERSION@
+VOTEQUORUM_SONAME = @VOTEQUORUM_SONAME@
+WITH_LIST = @WITH_LIST@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+corosyncrustver = @corosyncrustver@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+knet_CFLAGS = @knet_CFLAGS@
+knet_LIBS = @knet_LIBS@
+libdir = @libdir@
+libexecdir = @libexecdir@
+libsystemd_CFLAGS = @libsystemd_CFLAGS@
+libsystemd_LIBS = @libsystemd_LIBS@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+nozzle_CFLAGS = @nozzle_CFLAGS@
+nozzle_LIBS = @nozzle_LIBS@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+statgrab_CFLAGS = @statgrab_CFLAGS@
+statgrab_LIBS = @statgrab_LIBS@
+statgrabge090_CFLAGS = @statgrabge090_CFLAGS@
+statgrabge090_LIBS = @statgrabge090_LIBS@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+MAINTAINERCLEANFILES = Makefile.in
+SUBDIRS = . $(am__append_1)
+all: all-recursive
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign bindings/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign bindings/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run 'make' without going through this Makefile.
+# To change the values of 'make' variables: instead of editing Makefiles,
+# (1) if the variable is set in 'config.status', edit 'config.status'
+# (which will cause the Makefiles to be regenerated when you run 'make');
+# (2) otherwise, pass the desired values on the 'make' command line.
+$(am__recursive_targets):
+ @fail=; \
+ if $(am__make_keepgoing); then \
+ failcom='fail=yes'; \
+ else \
+ failcom='exit 1'; \
+ fi; \
+ dot_seen=no; \
+ target=`echo $@ | sed s/-recursive//`; \
+ case "$@" in \
+ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+ *) list='$(SUBDIRS)' ;; \
+ esac; \
+ for subdir in $$list; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ dot_seen=yes; \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || eval $$failcom; \
+ done; \
+ if test "$$dot_seen" = "no"; then \
+ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+ fi; test -z "$$fail"
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-recursive
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
+ include_option=--etags-include; \
+ empty_fix=.; \
+ else \
+ include_option=--include; \
+ empty_fix=; \
+ fi; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test ! -f $$subdir/TAGS || \
+ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
+ fi; \
+ done; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-recursive
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-recursive
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+ @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ $(am__make_dryrun) \
+ || test -d "$(distdir)/$$subdir" \
+ || $(MKDIR_P) "$(distdir)/$$subdir" \
+ || exit 1; \
+ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
+ $(am__relativize); \
+ new_distdir=$$reldir; \
+ dir1=$$subdir; dir2="$(top_distdir)"; \
+ $(am__relativize); \
+ new_top_distdir=$$reldir; \
+ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
+ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
+ ($(am__cd) $$subdir && \
+ $(MAKE) $(AM_MAKEFLAGS) \
+ top_distdir="$$new_top_distdir" \
+ distdir="$$new_distdir" \
+ am__remove_distdir=: \
+ am__skip_length_check=: \
+ am__skip_mode_fix=: \
+ distdir) \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-recursive
+all-am: Makefile
+installdirs: installdirs-recursive
+installdirs-am:
+install: install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-recursive
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+ -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+clean: clean-recursive
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-recursive
+ -rm -f Makefile
+distclean-am: clean-am distclean-generic distclean-tags
+
+dvi: dvi-recursive
+
+dvi-am:
+
+html: html-recursive
+
+html-am:
+
+info: info-recursive
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-recursive
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-recursive
+
+install-html-am:
+
+install-info: install-info-recursive
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-recursive
+
+install-pdf-am:
+
+install-ps: install-ps-recursive
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-recursive
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-recursive
+
+pdf-am:
+
+ps: ps-recursive
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: $(am__recursive_targets) install-am install-strip
+
+.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \
+ check-am clean clean-generic clean-libtool cscopelist-am ctags \
+ ctags-am distclean distclean-generic distclean-libtool \
+ distclean-tags distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-ps install-ps-am \
+ install-strip installcheck installcheck-am installdirs \
+ installdirs-am maintainer-clean maintainer-clean-generic \
+ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \
+ ps ps-am tags tags-am uninstall uninstall-am
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/bindings/rust/Cargo.toml.in b/bindings/rust/Cargo.toml.in
new file mode 100644
index 0000000..d357605
--- /dev/null
+++ b/bindings/rust/Cargo.toml.in
@@ -0,0 +1,16 @@
+[package]
+name = "rust-corosync"
+version = "@corosyncrustver@"
+authors = ["Christine Caulfield <ccaulfie@redhat.com>"]
+edition = "2021"
+readme = "README.md"
+license = "MIT OR Apache-2.0"
+repository = "https://github.com/corosync/corosync/"
+description = "Rust bindings for corosync libraries"
+categories = ["api-bindings"]
+keywords = ["cluster", "high-availability"]
+
+[dependencies]
+lazy_static = "1.4.0"
+num_enum = "0.5.4"
+bitflags = "1.3.2"
diff --git a/bindings/rust/Makefile.am b/bindings/rust/Makefile.am
new file mode 100644
index 0000000..c22b84b
--- /dev/null
+++ b/bindings/rust/Makefile.am
@@ -0,0 +1,60 @@
+#
+# Copyright (C) 2022-2023 Red Hat, Inc. All rights reserved.
+#
+# Author: Christine Caulfield <ccaulfie@redhat.com>
+#
+# This software licensed under GPL-2.0+
+#
+
+MAINTAINERCLEANFILES = Makefile.in
+
+include $(top_srcdir)/build-aux/rust.mk
+
+# required for make check
+localver = $(corosyncrustver)
+
+SUBDIRS = . tests
+
+EXTRA_DIST = \
+ $(RUST_COMMON) \
+ $(RUST_SHIP_SRCS) \
+ README.md
+
+RUST_SHIP_SRCS = \
+ src/cpg.rs \
+ src/cfg.rs \
+ src/quorum.rs \
+ src/votequorum.rs \
+ src/cmap.rs \
+ src/lib.rs \
+ src/sys/mod.rs
+
+RUST_BUILT_SRCS = \
+ src/sys/cpg.rs \
+ src/sys/cfg.rs \
+ src/sys/quorum.rs \
+ src/sys/votequorum.rs \
+ src/sys/cmap.rs
+
+src/sys/cpg.rs: cargo-tree-prep ../../include/corosync/cpg.h
+ $(top_srcdir)/build-aux/rust-regen.sh $(top_srcdir)/include/corosync/cpg.h $@ CPG --blocklist-function=inet6.* --blocklist-function==.*etsourcefilter -- -I$(top_srcdir)/include
+
+src/sys/cfg.rs: cargo-tree-prep ../../include/corosync/cfg.h
+ $(top_srcdir)/build-aux/rust-regen.sh $(top_srcdir)/include/corosync/cfg.h $@ CFG --blocklist-function=inet6.* --blocklist-function=.*etsourcefilter -- -I$(top_srcdir)/include
+
+src/sys/quorum.rs: cargo-tree-prep ../../include/corosync/quorum.h
+ $(top_srcdir)/build-aux/rust-regen.sh $(top_srcdir)/include/corosync/quorum.h $@ QUORUM -- -I$(top_srcdir)/include
+
+src/sys/votequorum.rs: cargo-tree-prep ../../include/corosync/votequorum.h
+ $(top_srcdir)/build-aux/rust-regen.sh $(top_srcdir)/include/corosync/votequorum.h $@ VOTEQUORUM -- -I$(top_srcdir)/include
+
+src/sys/cmap.rs: cargo-tree-prep ../../include/corosync/cmap.h
+ $(top_srcdir)/build-aux/rust-regen.sh $(top_srcdir)/include/corosync/cmap.h $@ CMAP -- -I$(top_srcdir)/include $(LIBQB_CFLAGS)
+
+all-local: target/$(RUST_TARGET_DIR)/cpg.rlib \
+ target/$(RUST_TARGET_DIR)/cfg.rlib \
+ target/$(RUST_TARGET_DIR)/quorum.rlib \
+ target/$(RUST_TARGET_DIR)/votequorum.rlib \
+ target/$(RUST_TARGET_DIR)/cmap.rlib
+
+clean-local: cargo-clean
diff --git a/bindings/rust/Makefile.in b/bindings/rust/Makefile.in
new file mode 100644
index 0000000..a2a6169
--- /dev/null
+++ b/bindings/rust/Makefile.in
@@ -0,0 +1,836 @@
+# Makefile.in generated by automake 1.13.4 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+#
+# Copyright (C) 2022-2023 Red Hat, Inc. All rights reserved.
+#
+# Author: Christine Caulfield <ccaulfie@redhat.com>
+#
+# This software licensed under GPL-2.0+
+#
+
+#
+# Copyright (C) 2021-2022 Red Hat, Inc. All rights reserved.
+#
+# Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+#
+# This software licensed under GPL-2.0+
+#
+VPATH = @srcdir@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+DIST_COMMON = $(top_srcdir)/build-aux/rust.mk $(srcdir)/Makefile.in \
+ $(srcdir)/Makefile.am $(srcdir)/Cargo.toml.in
+subdir = bindings/rust
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/lib/libcfg.verso $(top_srcdir)/lib/libcpg.verso \
+ $(top_srcdir)/lib/libquorum.verso \
+ $(top_srcdir)/lib/libsam.verso \
+ $(top_srcdir)/lib/libvotequorum.verso \
+ $(top_srcdir)/lib/libcmap.verso $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/include/corosync/config.h
+CONFIG_CLEAN_FILES = Cargo.toml
+CONFIG_CLEAN_VPATH_FILES =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+SOURCES =
+DIST_SOURCES =
+RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \
+ ctags-recursive dvi-recursive html-recursive info-recursive \
+ install-data-recursive install-dvi-recursive \
+ install-exec-recursive install-html-recursive \
+ install-info-recursive install-pdf-recursive \
+ install-ps-recursive install-recursive installcheck-recursive \
+ installdirs-recursive pdf-recursive ps-recursive \
+ tags-recursive uninstall-recursive
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
+ distclean-recursive maintainer-clean-recursive
+am__recursive_targets = \
+ $(RECURSIVE_TARGETS) \
+ $(RECURSIVE_CLEAN_TARGETS) \
+ $(am__extra_recursive_targets)
+AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \
+ distdir
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+DIST_SUBDIRS = $(SUBDIRS)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+am__relativize = \
+ dir0=`pwd`; \
+ sed_first='s,^\([^/]*\)/.*$$,\1,'; \
+ sed_rest='s,^[^/]*/*,,'; \
+ sed_last='s,^.*/\([^/]*\)$$,\1,'; \
+ sed_butlast='s,/*[^/]*$$,,'; \
+ while test -n "$$dir1"; do \
+ first=`echo "$$dir1" | sed -e "$$sed_first"`; \
+ if test "$$first" != "."; then \
+ if test "$$first" = ".."; then \
+ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
+ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
+ else \
+ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
+ if test "$$first2" = "$$first"; then \
+ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
+ else \
+ dir2="../$$dir2"; \
+ fi; \
+ dir0="$$dir0"/"$$first"; \
+ fi; \
+ fi; \
+ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
+ done; \
+ reldir="$$dir2"
+ACLOCAL = @ACLOCAL@
+ALLOCA = @ALLOCA@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUGTOOL = @AUGTOOL@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BASHPATH = @BASHPATH@
+BINDGEN = @BINDGEN@
+CARGO = @CARGO@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFG_SONAME = @CFG_SONAME@
+CFLAGS = @CFLAGS@
+CLIPPY = @CLIPPY@
+CMAP_SONAME = @CMAP_SONAME@
+COROSYSCONFDIR = @COROSYSCONFDIR@
+CPG_SONAME = @CPG_SONAME@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DBUS_CFLAGS = @DBUS_CFLAGS@
+DBUS_LIBS = @DBUS_LIBS@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DOT = @DOT@
+DOXYGEN = @DOXYGEN@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GREP = @GREP@
+GROFF = @GROFF@
+INITCONFIGDIR = @INITCONFIGDIR@
+INITDDIR = @INITDDIR@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBQB_CFLAGS = @LIBQB_CFLAGS@
+LIBQB_LIBS = @LIBQB_LIBS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LINT_FLAGS = @LINT_FLAGS@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LOGDIR = @LOGDIR@
+LOGROTATEDIR = @LOGROTATEDIR@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+QUORUM_SONAME = @QUORUM_SONAME@
+RANLIB = @RANLIB@
+RUSTC = @RUSTC@
+RUSTDOC = @RUSTDOC@
+RUSTFMT = @RUSTFMT@
+RUST_FLAGS = @RUST_FLAGS@
+RUST_TARGET_DIR = @RUST_TARGET_DIR@
+SAM_SONAME = @SAM_SONAME@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SNMPCONFIG = @SNMPCONFIG@
+SNMP_LIBS = @SNMP_LIBS@
+SOMAJOR = @SOMAJOR@
+SOMICRO = @SOMICRO@
+SOMINOR = @SOMINOR@
+SONAME = @SONAME@
+STRIP = @STRIP@
+SYSTEMDDIR = @SYSTEMDDIR@
+VERSCRIPT_LDFLAGS = @VERSCRIPT_LDFLAGS@
+VERSION = @VERSION@
+VOTEQUORUM_SONAME = @VOTEQUORUM_SONAME@
+WITH_LIST = @WITH_LIST@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+corosyncrustver = @corosyncrustver@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+knet_CFLAGS = @knet_CFLAGS@
+knet_LIBS = @knet_LIBS@
+libdir = @libdir@
+libexecdir = @libexecdir@
+libsystemd_CFLAGS = @libsystemd_CFLAGS@
+libsystemd_LIBS = @libsystemd_LIBS@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+nozzle_CFLAGS = @nozzle_CFLAGS@
+nozzle_LIBS = @nozzle_LIBS@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+statgrab_CFLAGS = @statgrab_CFLAGS@
+statgrab_LIBS = @statgrab_LIBS@
+statgrabge090_CFLAGS = @statgrabge090_CFLAGS@
+statgrabge090_LIBS = @statgrabge090_LIBS@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+MAINTAINERCLEANFILES = Makefile.in
+RUST_COMMON = \
+ build.rs.in
+
+RUST_SRCS = $(RUST_SHIP_SRCS) $(RUST_BUILT_SRCS)
+
+# required for make check
+localver = $(corosyncrustver)
+SUBDIRS = . tests
+EXTRA_DIST = \
+ $(RUST_COMMON) \
+ $(RUST_SHIP_SRCS) \
+ README.md
+
+RUST_SHIP_SRCS = \
+ src/cpg.rs \
+ src/cfg.rs \
+ src/quorum.rs \
+ src/votequorum.rs \
+ src/cmap.rs \
+ src/lib.rs \
+ src/sys/mod.rs
+
+RUST_BUILT_SRCS = \
+ src/sys/cpg.rs \
+ src/sys/cfg.rs \
+ src/sys/quorum.rs \
+ src/sys/votequorum.rs \
+ src/sys/cmap.rs
+
+all: all-recursive
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(top_srcdir)/build-aux/rust.mk $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign bindings/rust/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign bindings/rust/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+$(top_srcdir)/build-aux/rust.mk:
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+Cargo.toml: $(top_builddir)/config.status $(srcdir)/Cargo.toml.in
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run 'make' without going through this Makefile.
+# To change the values of 'make' variables: instead of editing Makefiles,
+# (1) if the variable is set in 'config.status', edit 'config.status'
+# (which will cause the Makefiles to be regenerated when you run 'make');
+# (2) otherwise, pass the desired values on the 'make' command line.
+$(am__recursive_targets):
+ @fail=; \
+ if $(am__make_keepgoing); then \
+ failcom='fail=yes'; \
+ else \
+ failcom='exit 1'; \
+ fi; \
+ dot_seen=no; \
+ target=`echo $@ | sed s/-recursive//`; \
+ case "$@" in \
+ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+ *) list='$(SUBDIRS)' ;; \
+ esac; \
+ for subdir in $$list; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ dot_seen=yes; \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || eval $$failcom; \
+ done; \
+ if test "$$dot_seen" = "no"; then \
+ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+ fi; test -z "$$fail"
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-recursive
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
+ include_option=--etags-include; \
+ empty_fix=.; \
+ else \
+ include_option=--include; \
+ empty_fix=; \
+ fi; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test ! -f $$subdir/TAGS || \
+ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
+ fi; \
+ done; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-recursive
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-recursive
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+ @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ $(am__make_dryrun) \
+ || test -d "$(distdir)/$$subdir" \
+ || $(MKDIR_P) "$(distdir)/$$subdir" \
+ || exit 1; \
+ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
+ $(am__relativize); \
+ new_distdir=$$reldir; \
+ dir1=$$subdir; dir2="$(top_distdir)"; \
+ $(am__relativize); \
+ new_top_distdir=$$reldir; \
+ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
+ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
+ ($(am__cd) $$subdir && \
+ $(MAKE) $(AM_MAKEFLAGS) \
+ top_distdir="$$new_top_distdir" \
+ distdir="$$new_distdir" \
+ am__remove_distdir=: \
+ am__skip_length_check=: \
+ am__skip_mode_fix=: \
+ distdir) \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) check-local
+check: check-recursive
+all-am: Makefile all-local
+installdirs: installdirs-recursive
+installdirs-am:
+install: install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-recursive
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+ -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+clean: clean-recursive
+
+clean-am: clean-generic clean-libtool clean-local mostlyclean-am
+
+distclean: distclean-recursive
+ -rm -f Makefile
+distclean-am: clean-am distclean-generic distclean-tags
+
+dvi: dvi-recursive
+
+dvi-am:
+
+html: html-recursive
+
+html-am:
+
+info: info-recursive
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-recursive
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-recursive
+
+install-html-am:
+
+install-info: install-info-recursive
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-recursive
+
+install-pdf-am:
+
+install-ps: install-ps-recursive
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-recursive
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-recursive
+
+pdf-am:
+
+ps: ps-recursive
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: $(am__recursive_targets) check-am install-am install-strip
+
+.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am all-local \
+ check check-am check-local clean clean-generic clean-libtool \
+ clean-local cscopelist-am ctags ctags-am distclean \
+ distclean-generic distclean-libtool distclean-tags distdir dvi \
+ dvi-am html html-am info info-am install install-am \
+ install-data install-data-am install-dvi install-dvi-am \
+ install-exec install-exec-am install-html install-html-am \
+ install-info install-info-am install-man install-pdf \
+ install-pdf-am install-ps install-ps-am install-strip \
+ installcheck installcheck-am installdirs installdirs-am \
+ maintainer-clean maintainer-clean-generic mostlyclean \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags tags-am uninstall uninstall-am
+
+
+%.rlib: $(RUST_SRCS) Cargo.toml build.rs
+ PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) $(CARGO) build $(RUST_FLAGS)
+
+%-test: $(RUST_SRCS) Cargo.toml build.rs
+ PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) $(CARGO) build $(RUST_FLAGS)
+
+build.rs: build.rs.in
+ rm -f $@ $@-t
+ cat $^ | sed \
+ -e 's#@ABSTOPLEVELSRC@#$(abs_top_srcdir)#g' \
+ -e 's#@ABSTOPLEVELBUILD@#$(abs_top_builddir)#g' \
+ -e 's#@LIBQBLIBS@#$(LIBQB_LIBS)#g' \
+ > $@-t
+ chmod a-w $@-t
+ mv $@-t $@
+ rm -f $@-t
+
+cargo-tree-prep:
+ if [ "${abs_builddir}" != "${abs_srcdir}" ]; then \
+ echo "Generating builddir out-of-tree rust symlinks"; \
+ src_realpath=$(shell realpath ${abs_srcdir}); \
+ for i in `find "$$src_realpath/" -type d | \
+ grep -v "${abs_builddir}" | \
+ sed -e 's#^'$$src_realpath'/##g'`; do \
+ $(MKDIR_P) ${abs_builddir}/$${i}; \
+ done; \
+ find "$$src_realpath/" -type f | { while read src; do \
+ process=no; \
+ copy=no; \
+ case $$src in \
+ ${abs_builddir}*) \
+ ;; \
+ *Makefile.*|*.in) \
+ ;; \
+ *) \
+ process=yes; \
+ ;; \
+ esac ; \
+ dst=`echo $$src | sed -e 's#^'$$src_realpath'/##g'`; \
+ if [ $${process} == yes ]; then \
+ rm -f ${abs_builddir}/$$dst; \
+ $(LN_S) $$src ${abs_builddir}/$$dst; \
+ fi; \
+ if [ $${copy} == yes ]; then \
+ rm -f ${abs_builddir}/$$dst; \
+ cp $$src ${abs_builddir}/$$dst; \
+ chmod u+w ${abs_builddir}/$$dst; \
+ fi; \
+ done; }; \
+ fi
+
+cargo-clean:
+ -$(CARGO) clean
+ rm -rf Cargo.lock $(RUST_BUILT_SRCS) build.rs target/
+ if [ "${abs_builddir}" != "${abs_srcdir}" ]; then \
+ echo "Cleaning out-of-tree rust symlinks" ; \
+ find "${abs_builddir}/" -type l -delete; \
+ find "${abs_builddir}/" -type d -empty -delete; \
+ fi
+
+clippy-check:
+ $(CARGO) clippy --verbose --all-features -- -D warnings
+
+format-check:
+ if [ "${abs_builddir}" = "${abs_srcdir}" ]; then \
+ $(CARGO) fmt --all --check; \
+ else \
+ echo "!!!!! WARNING: skipping format check !!!!!"; \
+ fi
+
+doc-check:
+ $(CARGO) doc --verbose --all-features
+
+publish-check:
+ if [ -f "${abs_srcdir}/README.md" ]; then \
+ $(CARGO) publish --dry-run; \
+ fi
+
+crates-publish:
+ if [ -f "${abs_srcdir}/README.md" ]; then \
+ bindingname=`cat Cargo.toml | grep ^name | sed -e 's#.*= ##g' -e 's#"##g'` && \
+ cratesver=`cargo search $$bindingname | grep "^$$bindingname " | sed -e 's#.*= ##g' -e 's#"##g' -e 's/\+.*//g'` && \
+ testver=`echo $(localver) | sed -e 's/\+.*//g'` && \
+ if [ "$$cratesver" != "$$testver" ]; then \
+ $(CARGO) publish; \
+ fi; \
+ fi
+
+crates-check:
+ if [ -f "${abs_srcdir}/README.md" ]; then \
+ bindingname=`cat Cargo.toml | grep ^name | sed -e 's#.*= ##g' -e 's#"##g'` && \
+ cratesver=`cargo search $$bindingname | grep "^$$bindingname " | sed -e 's#.*= ##g' -e 's#"##g' -e 's/\+.*//g'` && \
+ testver=`echo $(localver) | sed -e 's/\+.*//g'` && \
+ if [ "$$cratesver" != "$$testver" ]; then \
+ echo "!!!!! WARNING !!!!!"; \
+ echo "!!!!! WARNING: $$bindingname local version ($$testver) is higher than the current published one on crates.io ($$cratesver)"; \
+ echo "!!!!! WARNING !!!!!"; \
+ fi; \
+ fi
+
+check-local: clippy-check format-check doc-check crates-check publish-check
+
+src/sys/cpg.rs: cargo-tree-prep ../../include/corosync/cpg.h
+ $(top_srcdir)/build-aux/rust-regen.sh $(top_srcdir)/include/corosync/cpg.h $@ CPG --blocklist-function=inet6.* --blocklist-function==.*etsourcefilter -- -I$(top_srcdir)/include
+
+src/sys/cfg.rs: cargo-tree-prep ../../include/corosync/cfg.h
+ $(top_srcdir)/build-aux/rust-regen.sh $(top_srcdir)/include/corosync/cfg.h $@ CFG --blocklist-function=inet6.* --blocklist-function=.*etsourcefilter -- -I$(top_srcdir)/include
+
+src/sys/quorum.rs: cargo-tree-prep ../../include/corosync/quorum.h
+ $(top_srcdir)/build-aux/rust-regen.sh $(top_srcdir)/include/corosync/quorum.h $@ QUORUM -- -I$(top_srcdir)/include
+
+src/sys/votequorum.rs: cargo-tree-prep ../../include/corosync/votequorum.h
+ $(top_srcdir)/build-aux/rust-regen.sh $(top_srcdir)/include/corosync/votequorum.h $@ VOTEQUORUM -- -I$(top_srcdir)/include
+
+src/sys/cmap.rs: cargo-tree-prep ../../include/corosync/cmap.h
+ $(top_srcdir)/build-aux/rust-regen.sh $(top_srcdir)/include/corosync/cmap.h $@ CMAP -- -I$(top_srcdir)/include $(LIBQB_CFLAGS)
+
+all-local: target/$(RUST_TARGET_DIR)/cpg.rlib \
+ target/$(RUST_TARGET_DIR)/cfg.rlib \
+ target/$(RUST_TARGET_DIR)/quorum.rlib \
+ target/$(RUST_TARGET_DIR)/votequorum.rlib \
+ target/$(RUST_TARGET_DIR)/cmap.rlib
+
+clean-local: cargo-clean
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/bindings/rust/README.md b/bindings/rust/README.md
new file mode 100644
index 0000000..cb2f9cc
--- /dev/null
+++ b/bindings/rust/README.md
@@ -0,0 +1,20 @@
+# rust-corosync
+Rust bindings for corosync
+
+Rust bindings for cfg, cmap, cpg, quorum, votequorum are part of this
+source tree, but are included here mainly to keep all of the
+corosync APIs in one place and to ensure that everything is kept
+up-to-date and properly tested in our CI system.
+
+The correct place to get the Rust crates for corosync
+is still crates.io as it would be for other crates. These will be
+updated when we issue a new release of corosync.
+
+https://crates.io/crates/rust-corosync
+
+Of course, if you want to try any new features in the APIs that
+may have not yet been released then you can try these sources, but
+please keep in touch with us via email or IRC if you do so.
+
+#clusterlabs or #kronosnet on libera IRC
+users@clusterlabs.org
diff --git a/bindings/rust/build.rs.in b/bindings/rust/build.rs.in
new file mode 100644
index 0000000..e7de170
--- /dev/null
+++ b/bindings/rust/build.rs.in
@@ -0,0 +1,7 @@
+fn main() {
+ println!("cargo:rustc-link-lib=cpg");
+ println!("cargo:rustc-link-lib=cfg");
+ println!("cargo:rustc-link-lib=cmap");
+ println!("cargo:rustc-link-lib=quorum");
+ println!("cargo:rustc-link-lib=votequorum");
+}
diff --git a/bindings/rust/src/cfg.rs b/bindings/rust/src/cfg.rs
new file mode 100644
index 0000000..b4eecac
--- /dev/null
+++ b/bindings/rust/src/cfg.rs
@@ -0,0 +1,348 @@
+// libcfg interface for Rust
+// Copyright (c) 2021 Red Hat, Inc.
+//
+// All rights reserved.
+//
+// Author: Christine Caulfield (ccaulfi@redhat.com)
+//
+
+// For the code generated by bindgen
+use crate::sys::cfg as ffi;
+
+use std::collections::HashMap;
+use std::ffi::CString;
+use std::os::raw::{c_int, c_void};
+use std::sync::Mutex;
+
+use crate::string_from_bytes;
+use crate::{CsError, DispatchFlags, NodeId, Result};
+
+// Used to convert a CFG handle into one of ours
+lazy_static! {
+ static ref HANDLE_HASH: Mutex<HashMap<u64, Handle>> = Mutex::new(HashMap::new());
+}
+
+/// Callback from [track_start]. Will be called if another process
+/// requests to shut down corosync. [reply_to_shutdown] should be called
+/// with a [ShutdownReply] of either Yes or No.
+#[derive(Copy, Clone)]
+pub struct Callbacks {
+ pub corosync_cfg_shutdown_callback_fn: Option<fn(handle: &Handle, flags: u32)>,
+}
+
+/// A handle into the cfg library. returned from [initialize] and needed for all other calls
+#[derive(Copy, Clone)]
+pub struct Handle {
+ cfg_handle: u64,
+ callbacks: Callbacks,
+}
+
+/// Flags for [try_shutdown]
+pub enum ShutdownFlags {
+ /// Request shutdown (other daemons will be consulted)
+ Request,
+ /// Tells other daemons but ignore their opinions
+ Regardless,
+ /// Go down straight away (but still tell other nodes)
+ Immediate,
+}
+
+/// Responses for [reply_to_shutdown]
+pub enum ShutdownReply {
+ Yes = 1,
+ No = 0,
+}
+
+/// Trackflags for [track_start]. None currently supported
+pub enum TrackFlags {
+ None,
+}
+
+/// Version of the [NodeStatus] structure returned from [node_status_get]
+#[derive(Debug, Copy, Clone)]
+pub enum NodeStatusVersion {
+ V1,
+}
+
+/// Status of a link inside [NodeStatus] struct
+#[derive(Debug)]
+pub struct LinkStatus {
+ pub enabled: bool,
+ pub connected: bool,
+ pub dynconnected: bool,
+ pub mtu: u32,
+ pub src_ipaddr: String,
+ pub dst_ipaddr: String,
+}
+
+/// Structure returned from [node_status_get], shows all the details of a node
+/// that is known to corosync, including all configured links
+#[derive(Debug)]
+pub struct NodeStatus {
+ pub version: NodeStatusVersion,
+ pub nodeid: NodeId,
+ pub reachable: bool,
+ pub remote: bool,
+ pub external: bool,
+ pub onwire_min: u8,
+ pub onwire_max: u8,
+ pub onwire_ver: u8,
+ pub link_status: Vec<LinkStatus>,
+}
+
+extern "C" fn rust_shutdown_notification_fn(handle: ffi::corosync_cfg_handle_t, flags: u32) {
+ if let Some(h) = HANDLE_HASH.lock().unwrap().get(&handle) {
+ if let Some(cb) = h.callbacks.corosync_cfg_shutdown_callback_fn {
+ (cb)(h, flags);
+ }
+ }
+}
+
+/// Initialize a connection to the cfg library. You must call this before doing anything
+/// else and use the passed back [Handle].
+/// Remember to free the handle using [finalize] when finished.
+pub fn initialize(callbacks: &Callbacks) -> Result<Handle> {
+ let mut handle: ffi::corosync_cfg_handle_t = 0;
+
+ let c_callbacks = ffi::corosync_cfg_callbacks_t {
+ corosync_cfg_shutdown_callback: Some(rust_shutdown_notification_fn),
+ };
+
+ unsafe {
+ let res = ffi::corosync_cfg_initialize(&mut handle, &c_callbacks);
+ if res == ffi::CS_OK {
+ let rhandle = Handle {
+ cfg_handle: handle,
+ callbacks: *callbacks,
+ };
+ HANDLE_HASH.lock().unwrap().insert(handle, rhandle);
+ Ok(rhandle)
+ } else {
+ Err(CsError::from_c(res))
+ }
+ }
+}
+
+/// Finish with a connection to corosync, after calling this the [Handle] is invalid
+pub fn finalize(handle: Handle) -> Result<()> {
+ let res = unsafe { ffi::corosync_cfg_finalize(handle.cfg_handle) };
+ if res == ffi::CS_OK {
+ HANDLE_HASH.lock().unwrap().remove(&handle.cfg_handle);
+ Ok(())
+ } else {
+ Err(CsError::from_c(res))
+ }
+}
+
+// not sure if an fd is the right thing to return here, but it will do for now.
+/// Returns a file descriptor to use for poll/select on the CFG handle
+pub fn fd_get(handle: Handle) -> Result<i32> {
+ let c_fd: *mut c_int = &mut 0 as *mut _ as *mut c_int;
+ let res = unsafe { ffi::corosync_cfg_fd_get(handle.cfg_handle, c_fd) };
+ if res == ffi::CS_OK {
+ Ok(c_fd as i32)
+ } else {
+ Err(CsError::from_c(res))
+ }
+}
+
+/// Get the local [NodeId]
+pub fn local_get(handle: Handle) -> Result<NodeId> {
+ let mut nodeid: u32 = 0;
+ let res = unsafe { ffi::corosync_cfg_local_get(handle.cfg_handle, &mut nodeid) };
+ if res == ffi::CS_OK {
+ Ok(NodeId::from(nodeid))
+ } else {
+ Err(CsError::from_c(res))
+ }
+}
+
+/// Reload the cluster configuration on all nodes
+pub fn reload_cnfig(handle: Handle) -> Result<()> {
+ let res = unsafe { ffi::corosync_cfg_reload_config(handle.cfg_handle) };
+ if res == ffi::CS_OK {
+ Ok(())
+ } else {
+ Err(CsError::from_c(res))
+ }
+}
+
+/// Re-open the cluster log files, on this node only
+pub fn reopen_log_files(handle: Handle) -> Result<()> {
+ let res = unsafe { ffi::corosync_cfg_reopen_log_files(handle.cfg_handle) };
+ if res == ffi::CS_OK {
+ Ok(())
+ } else {
+ Err(CsError::from_c(res))
+ }
+}
+
+/// Tell another cluster node to shutdown. reason is a string that
+/// will be written to the system log files.
+pub fn kill_node(handle: Handle, nodeid: NodeId, reason: &str) -> Result<()> {
+ let c_string = {
+ match CString::new(reason) {
+ Ok(cs) => cs,
+ Err(_) => return Err(CsError::CsErrInvalidParam),
+ }
+ };
+
+ let res = unsafe {
+ ffi::corosync_cfg_kill_node(handle.cfg_handle, u32::from(nodeid), c_string.as_ptr())
+ };
+ if res == ffi::CS_OK {
+ Ok(())
+ } else {
+ Err(CsError::from_c(res))
+ }
+}
+
+/// Ask this cluster node to shutdown. If [ShutdownFlags] is set to Request then
+///it may be refused by other applications
+/// that have registered for shutdown callbacks.
+pub fn try_shutdown(handle: Handle, flags: ShutdownFlags) -> Result<()> {
+ let c_flags = match flags {
+ ShutdownFlags::Request => 0,
+ ShutdownFlags::Regardless => 1,
+ ShutdownFlags::Immediate => 2,
+ };
+ let res = unsafe { ffi::corosync_cfg_try_shutdown(handle.cfg_handle, c_flags) };
+ if res == ffi::CS_OK {
+ Ok(())
+ } else {
+ Err(CsError::from_c(res))
+ }
+}
+
+/// Reply to a shutdown request with Yes or No [ShutdownReply]
+pub fn reply_to_shutdown(handle: Handle, flags: ShutdownReply) -> Result<()> {
+ let c_flags = match flags {
+ ShutdownReply::No => 0,
+ ShutdownReply::Yes => 1,
+ };
+ let res = unsafe { ffi::corosync_cfg_replyto_shutdown(handle.cfg_handle, c_flags) };
+ if res == ffi::CS_OK {
+ Ok(())
+ } else {
+ Err(CsError::from_c(res))
+ }
+}
+
+/// Call any/all active CFG callbacks for this [Handle] see [DispatchFlags] for details
+pub fn dispatch(handle: Handle, flags: DispatchFlags) -> Result<()> {
+ let res = unsafe { ffi::corosync_cfg_dispatch(handle.cfg_handle, flags as u32) };
+ if res == ffi::CS_OK {
+ Ok(())
+ } else {
+ Err(CsError::from_c(res))
+ }
+}
+
+// Quick & dirty u8 to boolean
+fn u8_to_bool(val: u8) -> bool {
+ val != 0
+}
+
+const CFG_MAX_LINKS: usize = 8;
+const CFG_MAX_HOST_LEN: usize = 256;
+fn unpack_nodestatus(c_nodestatus: ffi::corosync_cfg_node_status_v1) -> Result<NodeStatus> {
+ let mut ns = NodeStatus {
+ version: NodeStatusVersion::V1,
+ nodeid: NodeId::from(c_nodestatus.nodeid),
+ reachable: u8_to_bool(c_nodestatus.reachable),
+ remote: u8_to_bool(c_nodestatus.remote),
+ external: u8_to_bool(c_nodestatus.external),
+ onwire_min: c_nodestatus.onwire_min,
+ onwire_max: c_nodestatus.onwire_max,
+ onwire_ver: c_nodestatus.onwire_min,
+ link_status: Vec::<LinkStatus>::new(),
+ };
+ for i in 0..CFG_MAX_LINKS {
+ let ls = LinkStatus {
+ enabled: u8_to_bool(c_nodestatus.link_status[i].enabled),
+ connected: u8_to_bool(c_nodestatus.link_status[i].connected),
+ dynconnected: u8_to_bool(c_nodestatus.link_status[i].dynconnected),
+ mtu: c_nodestatus.link_status[i].mtu,
+ src_ipaddr: string_from_bytes(
+ &c_nodestatus.link_status[i].src_ipaddr[0],
+ CFG_MAX_HOST_LEN,
+ )?,
+ dst_ipaddr: string_from_bytes(
+ &c_nodestatus.link_status[i].dst_ipaddr[0],
+ CFG_MAX_HOST_LEN,
+ )?,
+ };
+ ns.link_status.push(ls);
+ }
+
+ Ok(ns)
+}
+
+// Constructor for link status to make c_ndostatus initialization tidier.
+fn new_ls() -> ffi::corosync_knet_link_status_v1 {
+ ffi::corosync_knet_link_status_v1 {
+ enabled: 0,
+ connected: 0,
+ dynconnected: 0,
+ mtu: 0,
+ src_ipaddr: [0; 256],
+ dst_ipaddr: [0; 256],
+ }
+}
+
+/// Get the extended status of a node in the cluster (including active links) from its [NodeId].
+/// Returns a filled in [NodeStatus] struct
+pub fn node_status_get(
+ handle: Handle,
+ nodeid: NodeId,
+ _version: NodeStatusVersion,
+) -> Result<NodeStatus> {
+ // Currently only supports V1 struct
+ unsafe {
+ // We need to initialize this even though it's all going to be overwritten.
+ let mut c_nodestatus = ffi::corosync_cfg_node_status_v1 {
+ version: 1,
+ nodeid: 0,
+ reachable: 0,
+ remote: 0,
+ external: 0,
+ onwire_min: 0,
+ onwire_max: 0,
+ onwire_ver: 0,
+ link_status: [new_ls(); 8],
+ };
+
+ let res = ffi::corosync_cfg_node_status_get(
+ handle.cfg_handle,
+ u32::from(nodeid),
+ 1,
+ &mut c_nodestatus as *mut _ as *mut c_void,
+ );
+
+ if res == ffi::CS_OK {
+ unpack_nodestatus(c_nodestatus)
+ } else {
+ Err(CsError::from_c(res))
+ }
+ }
+}
+
+/// Start tracking for shutdown notifications
+pub fn track_start(handle: Handle, _flags: TrackFlags) -> Result<()> {
+ let res = unsafe { ffi::corosync_cfg_trackstart(handle.cfg_handle, 0) };
+ if res == ffi::CS_OK {
+ Ok(())
+ } else {
+ Err(CsError::from_c(res))
+ }
+}
+
+/// Stop tracking for shutdown notifications
+pub fn track_stop(handle: Handle) -> Result<()> {
+ let res = unsafe { ffi::corosync_cfg_trackstop(handle.cfg_handle) };
+ if res == ffi::CS_OK {
+ Ok(())
+ } else {
+ Err(CsError::from_c(res))
+ }
+}
diff --git a/bindings/rust/src/cmap.rs b/bindings/rust/src/cmap.rs
new file mode 100644
index 0000000..454fbee
--- /dev/null
+++ b/bindings/rust/src/cmap.rs
@@ -0,0 +1,894 @@
+// libcmap interface for Rust
+// Copyright (c) 2021 Red Hat, Inc.
+//
+// All rights reserved.
+//
+// Author: Christine Caulfield (ccaulfi@redhat.com)
+//
+
+#![allow(clippy::type_complexity)]
+
+// For the code generated by bindgen
+use crate::sys::cmap as ffi;
+
+use num_enum::TryFromPrimitive;
+use std::any::type_name;
+use std::collections::HashMap;
+use std::convert::TryFrom;
+use std::ffi::CString;
+use std::fmt;
+use std::os::raw::{c_char, c_int, c_void};
+use std::ptr::copy_nonoverlapping;
+use std::sync::Mutex;
+
+use crate::string_from_bytes;
+use crate::{CsError, DispatchFlags, Result};
+
+// Maps:
+/// "Maps" available to [initialize]
+pub enum Map {
+ Icmap,
+ Stats,
+}
+
+bitflags! {
+/// Tracker types for cmap, both passed into [track_add]
+/// and returned from its callback.
+ pub struct TrackType: i32
+ {
+ const DELETE = 1;
+ const MODIFY = 2;
+ const ADD = 4;
+ const PREFIX = 8;
+ }
+}
+
+impl fmt::Display for TrackType {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ if self.contains(TrackType::DELETE) {
+ write!(f, "DELETE ")?
+ }
+ if self.contains(TrackType::MODIFY) {
+ write!(f, "MODIFY ")?
+ }
+ if self.contains(TrackType::ADD) {
+ write!(f, "ADD ")?
+ }
+ if self.contains(TrackType::PREFIX) {
+ write!(f, "PREFIX ")
+ } else {
+ Ok(())
+ }
+ }
+}
+
+#[derive(Copy, Clone)]
+/// A handle returned from [initialize], needs to be passed to all other cmap API calls
+pub struct Handle {
+ cmap_handle: u64,
+}
+
+#[derive(Copy, Clone)]
+/// A handle for a specific CMAP tracker. returned from [track_add].
+/// There may be multiple TrackHandles per [Handle]
+pub struct TrackHandle {
+ track_handle: u64,
+ notify_callback: NotifyCallback,
+}
+
+// Used to convert CMAP handles into one of ours, for callbacks
+lazy_static! {
+ static ref TRACKHANDLE_HASH: Mutex<HashMap<u64, TrackHandle>> = Mutex::new(HashMap::new());
+ static ref HANDLE_HASH: Mutex<HashMap<u64, Handle>> = Mutex::new(HashMap::new());
+}
+
+/// Initialize a connection to the cmap subsystem.
+/// map specifies which cmap "map" to use.
+/// Returns a [Handle] into the cmap library
+pub fn initialize(map: Map) -> Result<Handle> {
+ let mut handle: ffi::cmap_handle_t = 0;
+ let c_map = match map {
+ Map::Icmap => ffi::CMAP_MAP_ICMAP,
+ Map::Stats => ffi::CMAP_MAP_STATS,
+ };
+
+ unsafe {
+ let res = ffi::cmap_initialize_map(&mut handle, c_map);
+ if res == ffi::CS_OK {
+ let rhandle = Handle {
+ cmap_handle: handle,
+ };
+ HANDLE_HASH.lock().unwrap().insert(handle, rhandle);
+ Ok(rhandle)
+ } else {
+ Err(CsError::from_c(res))
+ }
+ }
+}
+
+/// Finish with a connection to corosync.
+/// Takes a [Handle] as returned from [initialize]
+pub fn finalize(handle: Handle) -> Result<()> {
+ let res = unsafe { ffi::cmap_finalize(handle.cmap_handle) };
+ if res == ffi::CS_OK {
+ HANDLE_HASH.lock().unwrap().remove(&handle.cmap_handle);
+ Ok(())
+ } else {
+ Err(CsError::from_c(res))
+ }
+}
+
+/// Return a file descriptor to use for poll/select on the CMAP handle.
+/// Takes a [Handle] as returned from [initialize],
+/// returns a C file descriptor as i32
+pub fn fd_get(handle: Handle) -> Result<i32> {
+ let c_fd: *mut c_int = &mut 0 as *mut _ as *mut c_int;
+ let res = unsafe { ffi::cmap_fd_get(handle.cmap_handle, c_fd) };
+ if res == ffi::CS_OK {
+ Ok(c_fd as i32)
+ } else {
+ Err(CsError::from_c(res))
+ }
+}
+
+/// Dispatch any/all active CMAP callbacks.
+/// Takes a [Handle] as returned from [initialize],
+/// flags [DispatchFlags] tells it how many items to dispatch before returning
+pub fn dispatch(handle: Handle, flags: DispatchFlags) -> Result<()> {
+ let res = unsafe { ffi::cmap_dispatch(handle.cmap_handle, flags as u32) };
+ if res == ffi::CS_OK {
+ Ok(())
+ } else {
+ Err(CsError::from_c(res))
+ }
+}
+
+/// Get the current 'context' value for this handle
+/// The context value is an arbitrary value that is always passed
+/// back to callbacks to help identify the source
+pub fn context_get(handle: Handle) -> Result<u64> {
+ let (res, context) = unsafe {
+ let mut context: u64 = 0;
+ let c_context: *mut c_void = &mut context as *mut _ as *mut c_void;
+ let r = ffi::cmap_context_get(handle.cmap_handle, c_context as *mut *const c_void);
+ (r, context)
+ };
+ if res == ffi::CS_OK {
+ Ok(context)
+ } else {
+ Err(CsError::from_c(res))
+ }
+}
+
+/// Set the current 'context' value for this handle
+/// The context value is an arbitrary value that is always passed
+/// back to callbacks to help identify the source.
+/// Normally this is set in [initialize], but this allows it to be changed
+pub fn context_set(handle: Handle, context: u64) -> Result<()> {
+ let res = unsafe {
+ let c_context = context as *mut c_void;
+ ffi::cmap_context_set(handle.cmap_handle, c_context)
+ };
+ if res == ffi::CS_OK {
+ Ok(())
+ } else {
+ Err(CsError::from_c(res))
+ }
+}
+
+/// The type of data returned from [get] or in a
+/// tracker callback or iterator, part of the [Data] struct
+#[derive(Clone, Copy, Debug, Eq, PartialEq, TryFromPrimitive)]
+#[repr(u32)]
+pub enum DataType {
+ Int8 = ffi::CMAP_VALUETYPE_INT8,
+ UInt8 = ffi::CMAP_VALUETYPE_UINT8,
+ Int16 = ffi::CMAP_VALUETYPE_INT16,
+ UInt16 = ffi::CMAP_VALUETYPE_UINT16,
+ Int32 = ffi::CMAP_VALUETYPE_INT32,
+ UInt32 = ffi::CMAP_VALUETYPE_UINT32,
+ Int64 = ffi::CMAP_VALUETYPE_INT64,
+ UInt64 = ffi::CMAP_VALUETYPE_UINT64,
+ Float = ffi::CMAP_VALUETYPE_FLOAT,
+ Double = ffi::CMAP_VALUETYPE_DOUBLE,
+ String = ffi::CMAP_VALUETYPE_STRING,
+ Binary = ffi::CMAP_VALUETYPE_BINARY,
+ Unknown = 999,
+}
+
+fn cmap_to_enum(cmap_type: u32) -> DataType {
+ match DataType::try_from(cmap_type) {
+ Ok(e) => e,
+ Err(_) => DataType::Unknown,
+ }
+}
+
+/// Data returned from the cmap::get() call and tracker & iterators.
+/// Contains the data itself and the type of that data.
+pub enum Data {
+ Int8(i8),
+ UInt8(u8),
+ Int16(i16),
+ UInt16(u16),
+ Int32(i32),
+ UInt32(u32),
+ Int64(i64),
+ UInt64(u64),
+ Float(f32),
+ Double(f64),
+ String(String),
+ Binary(Vec<u8>),
+ Unknown,
+}
+
+impl fmt::Display for DataType {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ match self {
+ DataType::Int8 => write!(f, "Int8"),
+ DataType::UInt8 => write!(f, "UInt8"),
+ DataType::Int16 => write!(f, "Int16"),
+ DataType::UInt16 => write!(f, "UInt16"),
+ DataType::Int32 => write!(f, "Int32"),
+ DataType::UInt32 => write!(f, "UInt32"),
+ DataType::Int64 => write!(f, "Int64"),
+ DataType::UInt64 => write!(f, "UInt64"),
+ DataType::Float => write!(f, "Float"),
+ DataType::Double => write!(f, "Double"),
+ DataType::String => write!(f, "String"),
+ DataType::Binary => write!(f, "Binary"),
+ DataType::Unknown => write!(f, "Unknown"),
+ }
+ }
+}
+
+impl fmt::Display for Data {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ match self {
+ Data::Int8(v) => write!(f, "{v} (Int8)"),
+ Data::UInt8(v) => write!(f, "{v} (UInt8)"),
+ Data::Int16(v) => write!(f, "{v} (Int16)"),
+ Data::UInt16(v) => write!(f, "{v} (UInt16)"),
+ Data::Int32(v) => write!(f, "{v} (Int32)"),
+ Data::UInt32(v) => write!(f, "{v} (UInt32)"),
+ Data::Int64(v) => write!(f, "{v} (Int64)"),
+ Data::UInt64(v) => write!(f, "{v} (UInt64)"),
+ Data::Float(v) => write!(f, "{v} (Float)"),
+ Data::Double(v) => write!(f, "{v} (Double)"),
+ Data::String(v) => write!(f, "{v} (String)"),
+ Data::Binary(v) => write!(f, "{v:?} (Binary)"),
+ Data::Unknown => write!(f, "Unknown)"),
+ }
+ }
+}
+
+const CMAP_KEYNAME_MAXLENGTH: usize = 255;
+fn string_to_cstring_validated(key: &str, maxlen: usize) -> Result<CString> {
+ if maxlen > 0 && key.chars().count() >= maxlen {
+ return Err(CsError::CsErrInvalidParam);
+ }
+
+ match CString::new(key) {
+ Ok(n) => Ok(n),
+ Err(_) => Err(CsError::CsErrLibrary),
+ }
+}
+
+fn set_value(
+ handle: Handle,
+ key_name: &str,
+ datatype: DataType,
+ value: *mut c_void,
+ length: usize,
+) -> Result<()> {
+ let csname = string_to_cstring_validated(key_name, CMAP_KEYNAME_MAXLENGTH)?;
+ let res = unsafe {
+ ffi::cmap_set(
+ handle.cmap_handle,
+ csname.as_ptr(),
+ value,
+ length,
+ datatype as u32,
+ )
+ };
+ if res == ffi::CS_OK {
+ Ok(())
+ } else {
+ Err(CsError::from_c(res))
+ }
+}
+
+// Returns type and size
+fn generic_to_cmap<T>(_value: T) -> (DataType, usize) {
+ match type_name::<T>() {
+ "u8" => (DataType::UInt8, 1),
+ "i8" => (DataType::Int8, 1),
+ "u16" => (DataType::UInt16, 2),
+ "i16" => (DataType::Int16, 2),
+ "u32" => (DataType::UInt32, 4),
+ "i32" => (DataType::Int32, 4),
+ "u64" => (DataType::UInt64, 4),
+ "f32" => (DataType::Float, 4),
+ "f64" => (DataType::Double, 8),
+ "&str" => (DataType::String, 0),
+ // Binary not currently supported here
+ _ => (DataType::Unknown, 0),
+ }
+}
+
+fn is_numeric_type(dtype: DataType) -> bool {
+ matches!(
+ dtype,
+ DataType::UInt8
+ | DataType::Int8
+ | DataType::UInt16
+ | DataType::Int16
+ | DataType::UInt32
+ | DataType::Int32
+ | DataType::UInt64
+ | DataType::Int64
+ | DataType::Float
+ | DataType::Double
+ )
+}
+
+/// Function to set a generic numeric value
+/// This doesn't work for strings or binaries
+pub fn set_number<T: Copy>(handle: Handle, key_name: &str, value: T) -> Result<()> {
+ let (c_type, c_size) = generic_to_cmap(value);
+
+ if is_numeric_type(c_type) {
+ let mut tmp = value;
+ let c_value: *mut c_void = &mut tmp as *mut _ as *mut c_void;
+ set_value(handle, key_name, c_type, c_value as *mut c_void, c_size)
+ } else {
+ Err(CsError::CsErrNotSupported)
+ }
+}
+
+pub fn set_u8(handle: Handle, key_name: &str, value: u8) -> Result<()> {
+ let mut tmp = value;
+ let c_value: *mut c_void = &mut tmp as *mut _ as *mut c_void;
+ set_value(handle, key_name, DataType::UInt8, c_value as *mut c_void, 1)
+}
+
+/// Sets an i8 value into cmap
+pub fn set_i8(handle: Handle, key_name: &str, value: i8) -> Result<()> {
+ let mut tmp = value;
+ let c_value: *mut c_void = &mut tmp as *mut _ as *mut c_void;
+ set_value(handle, key_name, DataType::Int8, c_value as *mut c_void, 1)
+}
+
+/// Sets a u16 value into cmap
+pub fn set_u16(handle: Handle, key_name: &str, value: u16) -> Result<()> {
+ let mut tmp = value;
+ let c_value: *mut c_void = &mut tmp as *mut _ as *mut c_void;
+ set_value(
+ handle,
+ key_name,
+ DataType::UInt16,
+ c_value as *mut c_void,
+ 2,
+ )
+}
+
+/// Sets an i16 value into cmap
+pub fn set_i16(handle: Handle, key_name: &str, value: i16) -> Result<()> {
+ let mut tmp = value;
+ let c_value: *mut c_void = &mut tmp as *mut _ as *mut c_void;
+ set_value(handle, key_name, DataType::Int16, c_value as *mut c_void, 2)
+}
+
+/// Sets a u32 value into cmap
+pub fn set_u32(handle: Handle, key_name: &str, value: u32) -> Result<()> {
+ let mut tmp = value;
+ let c_value: *mut c_void = &mut tmp as *mut _ as *mut c_void;
+ set_value(handle, key_name, DataType::UInt32, c_value, 4)
+}
+
+/// Sets an i32 value into cmap
+pub fn set_i132(handle: Handle, key_name: &str, value: i32) -> Result<()> {
+ let mut tmp = value;
+ let c_value: *mut c_void = &mut tmp as *mut _ as *mut c_void;
+ set_value(handle, key_name, DataType::Int32, c_value as *mut c_void, 4)
+}
+
+/// Sets a u64 value into cmap
+pub fn set_u64(handle: Handle, key_name: &str, value: u64) -> Result<()> {
+ let mut tmp = value;
+ let c_value: *mut c_void = &mut tmp as *mut _ as *mut c_void;
+ set_value(
+ handle,
+ key_name,
+ DataType::UInt64,
+ c_value as *mut c_void,
+ 8,
+ )
+}
+
+/// Sets an i64 value into cmap
+pub fn set_i164(handle: Handle, key_name: &str, value: i64) -> Result<()> {
+ let mut tmp = value;
+ let c_value: *mut c_void = &mut tmp as *mut _ as *mut c_void;
+ set_value(handle, key_name, DataType::Int64, c_value as *mut c_void, 8)
+}
+
+/// Sets a string value into cmap
+pub fn set_string(handle: Handle, key_name: &str, value: &str) -> Result<()> {
+ let v_string = string_to_cstring_validated(value, 0)?;
+ set_value(
+ handle,
+ key_name,
+ DataType::String,
+ v_string.as_ptr() as *mut c_void,
+ value.chars().count(),
+ )
+}
+
+/// Sets a binary value into cmap
+pub fn set_binary(handle: Handle, key_name: &str, value: &[u8]) -> Result<()> {
+ set_value(
+ handle,
+ key_name,
+ DataType::Binary,
+ value.as_ptr() as *mut c_void,
+ value.len(),
+ )
+}
+
+/// Sets a [Data] type into cmap
+pub fn set(handle: Handle, key_name: &str, data: &Data) -> Result<()> {
+ let (datatype, datalen, c_value) = match data {
+ Data::Int8(v) => {
+ let mut tmp = *v;
+ let cv: *mut c_void = &mut tmp as *mut _ as *mut c_void;
+ (DataType::Int8, 1, cv)
+ }
+ Data::UInt8(v) => {
+ let mut tmp = *v;
+ let cv: *mut c_void = &mut tmp as *mut _ as *mut c_void;
+ (DataType::UInt8, 1, cv)
+ }
+ Data::Int16(v) => {
+ let mut tmp = *v;
+ let cv: *mut c_void = &mut tmp as *mut _ as *mut c_void;
+ (DataType::Int16, 2, cv)
+ }
+ Data::UInt16(v) => {
+ let mut tmp = *v;
+ let cv: *mut c_void = &mut tmp as *mut _ as *mut c_void;
+ (DataType::UInt8, 2, cv)
+ }
+ Data::Int32(v) => {
+ let mut tmp = *v;
+ let cv: *mut c_void = &mut tmp as *mut _ as *mut c_void;
+ (DataType::Int32, 4, cv)
+ }
+ Data::UInt32(v) => {
+ let mut tmp = *v;
+ let cv: *mut c_void = &mut tmp as *mut _ as *mut c_void;
+ (DataType::UInt32, 4, cv)
+ }
+ Data::Int64(v) => {
+ let mut tmp = *v;
+ let cv: *mut c_void = &mut tmp as *mut _ as *mut c_void;
+ (DataType::Int64, 8, cv)
+ }
+ Data::UInt64(v) => {
+ let mut tmp = *v;
+ let cv: *mut c_void = &mut tmp as *mut _ as *mut c_void;
+ (DataType::UInt64, 8, cv)
+ }
+ Data::Float(v) => {
+ let mut tmp = *v;
+ let cv: *mut c_void = &mut tmp as *mut _ as *mut c_void;
+ (DataType::Float, 4, cv)
+ }
+ Data::Double(v) => {
+ let mut tmp = *v;
+ let cv: *mut c_void = &mut tmp as *mut _ as *mut c_void;
+ (DataType::Double, 8, cv)
+ }
+ Data::String(v) => {
+ let cv = string_to_cstring_validated(v, 0)?;
+ // Can't let cv go out of scope
+ return set_value(
+ handle,
+ key_name,
+ DataType::String,
+ cv.as_ptr() as *mut c_void,
+ v.chars().count(),
+ );
+ }
+ Data::Binary(v) => {
+ // Vec doesn't return quite the right types.
+ return set_value(
+ handle,
+ key_name,
+ DataType::Binary,
+ v.as_ptr() as *mut c_void,
+ v.len(),
+ );
+ }
+ Data::Unknown => return Err(CsError::CsErrInvalidParam),
+ };
+
+ set_value(handle, key_name, datatype, c_value, datalen)
+}
+
+// Local function to parse out values from the C mess
+// Assumes the c_value is complete. So cmap::get() will need to check the size
+// and re-get before calling us with a resized buffer
+fn c_to_data(value_size: usize, c_key_type: u32, c_value: *const u8) -> Result<Data> {
+ unsafe {
+ match cmap_to_enum(c_key_type) {
+ DataType::UInt8 => {
+ let mut ints = [0u8; 1];
+ copy_nonoverlapping(c_value as *mut u8, ints.as_mut_ptr(), value_size);
+ Ok(Data::UInt8(ints[0]))
+ }
+ DataType::Int8 => {
+ let mut ints = [0i8; 1];
+ copy_nonoverlapping(c_value as *mut u8, ints.as_mut_ptr() as *mut u8, value_size);
+ Ok(Data::Int8(ints[0]))
+ }
+ DataType::UInt16 => {
+ let mut ints = [0u16; 1];
+ copy_nonoverlapping(c_value as *mut u8, ints.as_mut_ptr() as *mut u8, value_size);
+ Ok(Data::UInt16(ints[0]))
+ }
+ DataType::Int16 => {
+ let mut ints = [0i16; 1];
+ copy_nonoverlapping(c_value as *mut u8, ints.as_mut_ptr() as *mut u8, value_size);
+ Ok(Data::Int16(ints[0]))
+ }
+ DataType::UInt32 => {
+ let mut ints = [0u32; 1];
+ copy_nonoverlapping(c_value as *mut u8, ints.as_mut_ptr() as *mut u8, value_size);
+ Ok(Data::UInt32(ints[0]))
+ }
+ DataType::Int32 => {
+ let mut ints = [0i32; 1];
+ copy_nonoverlapping(c_value as *mut u8, ints.as_mut_ptr() as *mut u8, value_size);
+ Ok(Data::Int32(ints[0]))
+ }
+ DataType::UInt64 => {
+ let mut ints = [0u64; 1];
+ copy_nonoverlapping(c_value as *mut u8, ints.as_mut_ptr() as *mut u8, value_size);
+ Ok(Data::UInt64(ints[0]))
+ }
+ DataType::Int64 => {
+ let mut ints = [0i64; 1];
+ copy_nonoverlapping(c_value as *mut u8, ints.as_mut_ptr() as *mut u8, value_size);
+ Ok(Data::Int64(ints[0]))
+ }
+ DataType::Float => {
+ let mut ints = [0f32; 1];
+ copy_nonoverlapping(c_value as *mut u8, ints.as_mut_ptr() as *mut u8, value_size);
+ Ok(Data::Float(ints[0]))
+ }
+ DataType::Double => {
+ let mut ints = [0f64; 1];
+ copy_nonoverlapping(c_value as *mut u8, ints.as_mut_ptr() as *mut u8, value_size);
+ Ok(Data::Double(ints[0]))
+ }
+ DataType::String => {
+ let mut ints = vec![0u8; value_size];
+ copy_nonoverlapping(c_value as *mut u8, ints.as_mut_ptr(), value_size);
+ // -1 here so CString doesn't see the NUL
+ let cs = match CString::new(&ints[0..value_size - 1_usize]) {
+ Ok(c1) => c1,
+ Err(_) => return Err(CsError::CsErrLibrary),
+ };
+ match cs.into_string() {
+ Ok(s) => Ok(Data::String(s)),
+ Err(_) => Err(CsError::CsErrLibrary),
+ }
+ }
+ DataType::Binary => {
+ let mut ints = vec![0u8; value_size];
+ copy_nonoverlapping(c_value as *mut u8, ints.as_mut_ptr(), value_size);
+ Ok(Data::Binary(ints))
+ }
+ DataType::Unknown => Ok(Data::Unknown),
+ }
+ }
+}
+
+const INITIAL_SIZE: usize = 256;
+
+/// Get a value from cmap, returned as a [Data] struct, so could be anything
+pub fn get(handle: Handle, key_name: &str) -> Result<Data> {
+ let csname = string_to_cstring_validated(key_name, CMAP_KEYNAME_MAXLENGTH)?;
+ let mut value_size: usize = 16;
+ let mut c_key_type: u32 = 0;
+
+ // First guess at a size for Strings and Binaries. Expand if needed
+ let mut c_value = vec![0u8; INITIAL_SIZE];
+
+ unsafe {
+ let res = ffi::cmap_get(
+ handle.cmap_handle,
+ csname.as_ptr(),
+ c_value.as_mut_ptr() as *mut c_void,
+ &mut value_size,
+ &mut c_key_type,
+ );
+ if res == ffi::CS_OK {
+ if value_size > INITIAL_SIZE {
+ // Need to try again with a bigger buffer
+ c_value.resize(value_size, 0u8);
+ let res2 = ffi::cmap_get(
+ handle.cmap_handle,
+ csname.as_ptr(),
+ c_value.as_mut_ptr() as *mut c_void,
+ &mut value_size,
+ &mut c_key_type,
+ );
+ if res2 != ffi::CS_OK {
+ return Err(CsError::from_c(res2));
+ }
+ }
+
+ // Convert to Rust type and return as a Data enum
+ c_to_data(value_size, c_key_type, c_value.as_ptr())
+ } else {
+ Err(CsError::from_c(res))
+ }
+ }
+}
+
+/// increment the value in a cmap key (must be a numeric type)
+pub fn inc(handle: Handle, key_name: &str) -> Result<()> {
+ let csname = string_to_cstring_validated(key_name, CMAP_KEYNAME_MAXLENGTH)?;
+ let res = unsafe { ffi::cmap_inc(handle.cmap_handle, csname.as_ptr()) };
+ if res == ffi::CS_OK {
+ Ok(())
+ } else {
+ Err(CsError::from_c(res))
+ }
+}
+
+/// decrement the value in a cmap key (must be a numeric type)
+pub fn dec(handle: Handle, key_name: &str) -> Result<()> {
+ let csname = string_to_cstring_validated(key_name, CMAP_KEYNAME_MAXLENGTH)?;
+ let res = unsafe { ffi::cmap_dec(handle.cmap_handle, csname.as_ptr()) };
+ if res == ffi::CS_OK {
+ Ok(())
+ } else {
+ Err(CsError::from_c(res))
+ }
+}
+
+// Callback for CMAP notify events from corosync, convert params to Rust and pass on.
+extern "C" fn rust_notify_fn(
+ cmap_handle: ffi::cmap_handle_t,
+ cmap_track_handle: ffi::cmap_track_handle_t,
+ event: i32,
+ key_name: *const ::std::os::raw::c_char,
+ new_value: ffi::cmap_notify_value,
+ old_value: ffi::cmap_notify_value,
+ user_data: *mut ::std::os::raw::c_void,
+) {
+ // If cmap_handle doesn't match then throw away the callback.
+ if let Some(r_cmap_handle) = HANDLE_HASH.lock().unwrap().get(&cmap_handle) {
+ if let Some(h) = TRACKHANDLE_HASH.lock().unwrap().get(&cmap_track_handle) {
+ let r_keyname = match string_from_bytes(key_name, CMAP_KEYNAME_MAXLENGTH) {
+ Ok(s) => s,
+ Err(_) => return,
+ };
+
+ let r_old = match c_to_data(old_value.len, old_value.type_, old_value.data as *const u8)
+ {
+ Ok(v) => v,
+ Err(_) => return,
+ };
+ let r_new = match c_to_data(new_value.len, new_value.type_, new_value.data as *const u8)
+ {
+ Ok(v) => v,
+ Err(_) => return,
+ };
+
+ if let Some(cb) = h.notify_callback.notify_fn {
+ (cb)(
+ r_cmap_handle,
+ h,
+ TrackType { bits: event },
+ &r_keyname,
+ &r_old,
+ &r_new,
+ user_data as u64,
+ );
+ }
+ }
+ }
+}
+
+/// Callback function called every time a tracker reports a change in a tracked value
+#[derive(Copy, Clone)]
+pub struct NotifyCallback {
+ pub notify_fn: Option<
+ fn(
+ handle: &Handle,
+ track_handle: &TrackHandle,
+ event: TrackType,
+ key_name: &str,
+ new_value: &Data,
+ old_value: &Data,
+ user_data: u64,
+ ),
+ >,
+}
+
+/// Track changes in cmap values, multiple [TrackHandle]s per [Handle] are allowed
+pub fn track_add(
+ handle: Handle,
+ key_name: &str,
+ track_type: TrackType,
+ notify_callback: &NotifyCallback,
+ user_data: u64,
+) -> Result<TrackHandle> {
+ let c_name = string_to_cstring_validated(key_name, CMAP_KEYNAME_MAXLENGTH)?;
+ let mut c_trackhandle = 0u64;
+ let res = unsafe {
+ ffi::cmap_track_add(
+ handle.cmap_handle,
+ c_name.as_ptr(),
+ track_type.bits,
+ Some(rust_notify_fn),
+ user_data as *mut c_void,
+ &mut c_trackhandle,
+ )
+ };
+ if res == ffi::CS_OK {
+ let rhandle = TrackHandle {
+ track_handle: c_trackhandle,
+ notify_callback: *notify_callback,
+ };
+ TRACKHANDLE_HASH
+ .lock()
+ .unwrap()
+ .insert(c_trackhandle, rhandle);
+ Ok(rhandle)
+ } else {
+ Err(CsError::from_c(res))
+ }
+}
+
+/// Remove a tracker frm this [Handle]
+pub fn track_delete(handle: Handle, track_handle: TrackHandle) -> Result<()> {
+ let res = unsafe { ffi::cmap_track_delete(handle.cmap_handle, track_handle.track_handle) };
+ if res == ffi::CS_OK {
+ TRACKHANDLE_HASH
+ .lock()
+ .unwrap()
+ .remove(&track_handle.track_handle);
+ Ok(())
+ } else {
+ Err(CsError::from_c(res))
+ }
+}
+
+/// Create one of these to start iterating over cmap values.
+pub struct CmapIterStart {
+ iter_handle: u64,
+ cmap_handle: u64,
+}
+
+pub struct CmapIntoIter {
+ cmap_handle: u64,
+ iter_handle: u64,
+}
+
+/// Value returned from the iterator. contains the key name and the [Data]
+pub struct CmapIter {
+ key_name: String,
+ data: Data,
+}
+
+impl CmapIter {
+ pub fn key_name(&self) -> &str {
+ &self.key_name
+ }
+ pub fn data(&self) -> &Data {
+ &self.data
+ }
+}
+
+impl fmt::Debug for CmapIter {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ write!(f, "{}: {}", self.key_name, self.data)
+ }
+}
+
+impl Iterator for CmapIntoIter {
+ type Item = CmapIter;
+
+ fn next(&mut self) -> Option<CmapIter> {
+ let mut c_key_name = [0u8; CMAP_KEYNAME_MAXLENGTH + 1];
+ let mut c_value_len = 0usize;
+ let mut c_value_type = 0u32;
+ let res = unsafe {
+ ffi::cmap_iter_next(
+ self.cmap_handle,
+ self.iter_handle,
+ c_key_name.as_mut_ptr() as *mut c_char,
+ &mut c_value_len,
+ &mut c_value_type,
+ )
+ };
+ if res == ffi::CS_OK {
+ // Return the Data for this iteration
+ let mut c_value = vec![0u8; c_value_len];
+ let res = unsafe {
+ ffi::cmap_get(
+ self.cmap_handle,
+ c_key_name.as_ptr() as *mut c_char,
+ c_value.as_mut_ptr() as *mut c_void,
+ &mut c_value_len,
+ &mut c_value_type,
+ )
+ };
+ if res == ffi::CS_OK {
+ match c_to_data(c_value_len, c_value_type, c_value.as_ptr()) {
+ Ok(d) => {
+ let r_keyname = match string_from_bytes(
+ c_key_name.as_ptr() as *mut c_char,
+ CMAP_KEYNAME_MAXLENGTH,
+ ) {
+ Ok(s) => s,
+ Err(_) => return None,
+ };
+ Some(CmapIter {
+ key_name: r_keyname,
+ data: d,
+ })
+ }
+ Err(_) => None,
+ }
+ } else {
+ // cmap_get returned error
+ None
+ }
+ } else if res == ffi::CS_ERR_NO_SECTIONS {
+ // End of list
+ unsafe {
+ // Yeah, we don't check this return code. There's nowhere to report it.
+ ffi::cmap_iter_finalize(self.cmap_handle, self.iter_handle)
+ };
+ None
+ } else {
+ None
+ }
+ }
+}
+
+impl CmapIterStart {
+ /// Create a new [CmapIterStart] object for iterating over a list of cmap keys
+ pub fn new(cmap_handle: Handle, prefix: &str) -> Result<CmapIterStart> {
+ let mut iter_handle: u64 = 0;
+ let res = unsafe {
+ let c_prefix = string_to_cstring_validated(prefix, CMAP_KEYNAME_MAXLENGTH)?;
+ ffi::cmap_iter_init(cmap_handle.cmap_handle, c_prefix.as_ptr(), &mut iter_handle)
+ };
+ if res == ffi::CS_OK {
+ Ok(CmapIterStart {
+ cmap_handle: cmap_handle.cmap_handle,
+ iter_handle,
+ })
+ } else {
+ Err(CsError::from_c(res))
+ }
+ }
+}
+
+impl IntoIterator for CmapIterStart {
+ type Item = CmapIter;
+ type IntoIter = CmapIntoIter;
+
+ fn into_iter(self) -> Self::IntoIter {
+ CmapIntoIter {
+ iter_handle: self.iter_handle,
+ cmap_handle: self.cmap_handle,
+ }
+ }
+}
diff --git a/bindings/rust/src/cpg.rs b/bindings/rust/src/cpg.rs
new file mode 100644
index 0000000..1246497
--- /dev/null
+++ b/bindings/rust/src/cpg.rs
@@ -0,0 +1,628 @@
+// libcpg interface for Rust
+// Copyright (c) 2020 Red Hat, Inc.
+//
+// All rights reserved.
+//
+// Author: Christine Caulfield (ccaulfi@redhat.com)
+//
+
+#![allow(clippy::single_match)]
+#![allow(clippy::needless_range_loop)]
+#![allow(clippy::type_complexity)]
+
+// For the code generated by bindgen
+use crate::sys::cpg as ffi;
+
+use std::collections::HashMap;
+use std::ffi::{CStr, CString};
+use std::fmt;
+use std::os::raw::{c_int, c_void};
+use std::ptr::copy_nonoverlapping;
+use std::slice;
+use std::string::String;
+use std::sync::Mutex;
+
+// General corosync things
+use crate::string_from_bytes;
+use crate::{CsError, DispatchFlags, NodeId, Result};
+
+const CPG_NAMELEN_MAX: usize = 128;
+const CPG_MEMBERS_MAX: usize = 128;
+
+/// RingId returned by totem_confchg_fn
+#[derive(Copy, Clone)]
+pub struct RingId {
+ pub nodeid: NodeId,
+ pub seq: u64,
+}
+
+/// Totem delivery guarantee options for [mcast_joined]
+// The C enum doesn't have numbers in the code
+// so don't assume we can match them
+#[derive(Copy, Clone)]
+pub enum Guarantee {
+ TypeUnordered,
+ TypeFifo,
+ TypeAgreed,
+ TypeSafe,
+}
+
+// Convert internal to cpg.h values.
+impl Guarantee {
+ pub fn to_c(&self) -> u32 {
+ match self {
+ Guarantee::TypeUnordered => ffi::CPG_TYPE_UNORDERED,
+ Guarantee::TypeFifo => ffi::CPG_TYPE_FIFO,
+ Guarantee::TypeAgreed => ffi::CPG_TYPE_AGREED,
+ Guarantee::TypeSafe => ffi::CPG_TYPE_SAFE,
+ }
+ }
+}
+
+/// Flow control state returned from [flow_control_state_get]
+#[derive(Copy, Clone)]
+pub enum FlowControlState {
+ Disabled,
+ Enabled,
+}
+
+/// No flags current specified for model1 so leave this at None
+#[derive(Copy, Clone)]
+pub enum Model1Flags {
+ None,
+}
+
+/// Reason for cpg item callback
+#[derive(Copy, Clone)]
+pub enum Reason {
+ Undefined = 0,
+ Join = 1,
+ Leave = 2,
+ NodeDown = 3,
+ NodeUp = 4,
+ ProcDown = 5,
+}
+
+// Convert to cpg.h values
+impl Reason {
+ pub fn new(r: u32) -> Reason {
+ match r {
+ 0 => Reason::Undefined,
+ 1 => Reason::Join,
+ 2 => Reason::Leave,
+ 3 => Reason::NodeDown,
+ 4 => Reason::NodeUp,
+ 5 => Reason::ProcDown,
+ _ => Reason::Undefined,
+ }
+ }
+}
+impl fmt::Display for Reason {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ match self {
+ Reason::Undefined => write!(f, "Undefined"),
+ Reason::Join => write!(f, "Join"),
+ Reason::Leave => write!(f, "Leave"),
+ Reason::NodeDown => write!(f, "NodeDown"),
+ Reason::NodeUp => write!(f, "NodeUp"),
+ Reason::ProcDown => write!(f, "ProcDown"),
+ }
+ }
+}
+
+/// A CPG address entry returned in the callbacks
+pub struct Address {
+ pub nodeid: NodeId,
+ pub pid: u32,
+ pub reason: Reason,
+}
+impl fmt::Debug for Address {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ write!(
+ f,
+ "[nodeid: {}, pid: {}, reason: {}]",
+ self.nodeid, self.pid, self.reason
+ )
+ }
+}
+
+/// Data for model1 [initialize]
+#[derive(Copy, Clone)]
+pub struct Model1Data {
+ pub flags: Model1Flags,
+ pub deliver_fn: Option<
+ fn(
+ handle: &Handle,
+ group_name: String,
+ nodeid: NodeId,
+ pid: u32,
+ msg: &[u8],
+ msg_len: usize,
+ ),
+ >,
+ pub confchg_fn: Option<
+ fn(
+ handle: &Handle,
+ group_name: &str,
+ member_list: Vec<Address>,
+ left_list: Vec<Address>,
+ joined_list: Vec<Address>,
+ ),
+ >,
+ pub totem_confchg_fn: Option<fn(handle: &Handle, ring_id: RingId, member_list: Vec<NodeId>)>,
+}
+
+/// Modeldata for [initialize], only v1 supported at the moment
+#[derive(Copy, Clone)]
+pub enum ModelData {
+ ModelNone,
+ ModelV1(Model1Data),
+}
+
+/// A handle into the cpg library. Returned from [initialize] and needed for all other calls
+#[derive(Copy, Clone)]
+pub struct Handle {
+ cpg_handle: u64, // Corosync library handle
+ model_data: ModelData,
+}
+
+// Used to convert a CPG handle into one of ours
+lazy_static! {
+ static ref HANDLE_HASH: Mutex<HashMap<u64, Handle>> = Mutex::new(HashMap::new());
+}
+
+// Convert a Rust String into a cpg_name struct for libcpg
+fn string_to_cpg_name(group: &str) -> Result<ffi::cpg_name> {
+ if group.len() > CPG_NAMELEN_MAX - 1 {
+ return Err(CsError::CsErrInvalidParam);
+ }
+
+ let c_name = match CString::new(group) {
+ Ok(n) => n,
+ Err(_) => return Err(CsError::CsErrLibrary),
+ };
+ let mut c_group = ffi::cpg_name {
+ length: group.len() as u32,
+ value: [0; CPG_NAMELEN_MAX],
+ };
+
+ unsafe {
+ // NOTE param order is 'wrong-way round' from C
+ copy_nonoverlapping(c_name.as_ptr(), c_group.value.as_mut_ptr(), group.len());
+ }
+
+ Ok(c_group)
+}
+
+// Convert an array of cpg_addresses to a Vec<cpg::Address> - used in callbacks
+fn cpg_array_to_vec(list: *const ffi::cpg_address, list_entries: usize) -> Vec<Address> {
+ let temp: &[ffi::cpg_address] = unsafe { slice::from_raw_parts(list, list_entries) };
+ let mut r_vec = Vec::<Address>::new();
+
+ for i in 0..list_entries {
+ let a: Address = Address {
+ nodeid: NodeId::from(temp[i].nodeid),
+ pid: temp[i].pid,
+ reason: Reason::new(temp[i].reason),
+ };
+ r_vec.push(a);
+ }
+ r_vec
+}
+
+// Called from CPG callback function - munge params back to Rust from C
+extern "C" fn rust_deliver_fn(
+ handle: ffi::cpg_handle_t,
+ group_name: *const ffi::cpg_name,
+ nodeid: u32,
+ pid: u32,
+ msg: *mut ::std::os::raw::c_void,
+ msg_len: usize,
+) {
+ if let Some(h) = HANDLE_HASH.lock().unwrap().get(&handle) {
+ // Convert group_name into a Rust str.
+ let r_group_name = unsafe {
+ CStr::from_ptr(&(*group_name).value[0])
+ .to_string_lossy()
+ .into_owned()
+ };
+
+ let data: &[u8] = unsafe { std::slice::from_raw_parts(msg as *const u8, msg_len) };
+
+ match h.model_data {
+ ModelData::ModelV1(md) => {
+ if let Some(cb) = md.deliver_fn {
+ (cb)(h, r_group_name, NodeId::from(nodeid), pid, data, msg_len);
+ }
+ }
+ _ => {}
+ }
+ }
+}
+
+// Called from CPG callback function - munge params back to Rust from C
+extern "C" fn rust_confchg_fn(
+ handle: ffi::cpg_handle_t,
+ group_name: *const ffi::cpg_name,
+ member_list: *const ffi::cpg_address,
+ member_list_entries: usize,
+ left_list: *const ffi::cpg_address,
+ left_list_entries: usize,
+ joined_list: *const ffi::cpg_address,
+ joined_list_entries: usize,
+) {
+ if let Some(h) = HANDLE_HASH.lock().unwrap().get(&handle) {
+ let r_group_name = unsafe {
+ CStr::from_ptr(&(*group_name).value[0])
+ .to_string_lossy()
+ .into_owned()
+ };
+ let r_member_list = cpg_array_to_vec(member_list, member_list_entries);
+ let r_left_list = cpg_array_to_vec(left_list, left_list_entries);
+ let r_joined_list = cpg_array_to_vec(joined_list, joined_list_entries);
+
+ match h.model_data {
+ ModelData::ModelV1(md) => {
+ if let Some(cb) = md.confchg_fn {
+ (cb)(h, &r_group_name, r_member_list, r_left_list, r_joined_list);
+ }
+ }
+ _ => {}
+ }
+ }
+}
+
+// Called from CPG callback function - munge params back to Rust from C
+extern "C" fn rust_totem_confchg_fn(
+ handle: ffi::cpg_handle_t,
+ ring_id: ffi::cpg_ring_id,
+ member_list_entries: u32,
+ member_list: *const u32,
+) {
+ if let Some(h) = HANDLE_HASH.lock().unwrap().get(&handle) {
+ let r_ring_id = RingId {
+ nodeid: NodeId::from(ring_id.nodeid),
+ seq: ring_id.seq,
+ };
+ let mut r_member_list = Vec::<NodeId>::new();
+ let temp_members: &[u32] =
+ unsafe { slice::from_raw_parts(member_list, member_list_entries as usize) };
+ for i in 0..member_list_entries as usize {
+ r_member_list.push(NodeId::from(temp_members[i]));
+ }
+
+ match h.model_data {
+ ModelData::ModelV1(md) => {
+ if let Some(cb) = md.totem_confchg_fn {
+ (cb)(h, r_ring_id, r_member_list);
+ }
+ }
+ _ => {}
+ }
+ }
+}
+
+/// Initialize a connection to the cpg library. You must call this before doing anything
+/// else and use the passed back [Handle].
+/// Remember to free the handle using [finalize] when finished.
+pub fn initialize(model_data: &ModelData, context: u64) -> Result<Handle> {
+ let mut handle: ffi::cpg_handle_t = 0;
+ let mut m = match model_data {
+ ModelData::ModelV1(_v1) => {
+ ffi::cpg_model_v1_data_t {
+ model: ffi::CPG_MODEL_V1,
+ cpg_deliver_fn: Some(rust_deliver_fn),
+ cpg_confchg_fn: Some(rust_confchg_fn),
+ cpg_totem_confchg_fn: Some(rust_totem_confchg_fn),
+ flags: 0, // No supported flags (yet)
+ }
+ }
+ _ => return Err(CsError::CsErrInvalidParam),
+ };
+
+ unsafe {
+ let c_context: *mut c_void = &mut &context as *mut _ as *mut c_void;
+ let c_model: *mut ffi::cpg_model_data_t = &mut m as *mut _ as *mut ffi::cpg_model_data_t;
+ let res = ffi::cpg_model_initialize(&mut handle, m.model, c_model, c_context);
+
+ if res == ffi::CS_OK {
+ let rhandle = Handle {
+ cpg_handle: handle,
+ model_data: *model_data,
+ };
+ HANDLE_HASH.lock().unwrap().insert(handle, rhandle);
+ Ok(rhandle)
+ } else {
+ Err(CsError::from_c(res))
+ }
+ }
+}
+
+/// Finish with a connection to corosync
+pub fn finalize(handle: Handle) -> Result<()> {
+ let res = unsafe { ffi::cpg_finalize(handle.cpg_handle) };
+ if res == ffi::CS_OK {
+ HANDLE_HASH.lock().unwrap().remove(&handle.cpg_handle);
+ Ok(())
+ } else {
+ Err(CsError::from_c(res))
+ }
+}
+
+// Not sure if an FD is the right thing to return here, but it will do for now.
+/// Returns a file descriptor to use for poll/select on the CPG handle
+pub fn fd_get(handle: Handle) -> Result<i32> {
+ let c_fd: *mut c_int = &mut 0 as *mut _ as *mut c_int;
+ let res = unsafe { ffi::cpg_fd_get(handle.cpg_handle, c_fd) };
+ if res == ffi::CS_OK {
+ Ok(c_fd as i32)
+ } else {
+ Err(CsError::from_c(res))
+ }
+}
+
+/// Call any/all active CPG callbacks for this [Handle] see [DispatchFlags] for details
+pub fn dispatch(handle: Handle, flags: DispatchFlags) -> Result<()> {
+ let res = unsafe { ffi::cpg_dispatch(handle.cpg_handle, flags as u32) };
+ if res == ffi::CS_OK {
+ Ok(())
+ } else {
+ Err(CsError::from_c(res))
+ }
+}
+
+/// Joins a CPG group for sending and receiving messages
+pub fn join(handle: Handle, group: &str) -> Result<()> {
+ let res = unsafe {
+ let c_group = string_to_cpg_name(group)?;
+ ffi::cpg_join(handle.cpg_handle, &c_group)
+ };
+ if res == ffi::CS_OK {
+ Ok(())
+ } else {
+ Err(CsError::from_c(res))
+ }
+}
+
+/// Leave the currently joined CPG group, another group can now be joined on
+/// the same [Handle] or [finalize] can be called to finish using CPG
+pub fn leave(handle: Handle, group: &str) -> Result<()> {
+ let res = unsafe {
+ let c_group = string_to_cpg_name(group)?;
+ ffi::cpg_leave(handle.cpg_handle, &c_group)
+ };
+ if res == ffi::CS_OK {
+ Ok(())
+ } else {
+ Err(CsError::from_c(res))
+ }
+}
+
+/// Get the local node ID
+pub fn local_get(handle: Handle) -> Result<NodeId> {
+ let mut nodeid: u32 = 0;
+ let res = unsafe { ffi::cpg_local_get(handle.cpg_handle, &mut nodeid) };
+ if res == ffi::CS_OK {
+ Ok(NodeId::from(nodeid))
+ } else {
+ Err(CsError::from_c(res))
+ }
+}
+
+/// Get a list of members of a CPG group as a vector of [Address] structs
+pub fn membership_get(handle: Handle, group: &str) -> Result<Vec<Address>> {
+ let mut member_list_entries: i32 = 0;
+ let member_list = [ffi::cpg_address {
+ nodeid: 0,
+ pid: 0,
+ reason: 0,
+ }; CPG_MEMBERS_MAX];
+ let res = unsafe {
+ let mut c_group = string_to_cpg_name(group)?;
+ let c_memlist = member_list.as_ptr() as *mut ffi::cpg_address;
+ ffi::cpg_membership_get(
+ handle.cpg_handle,
+ &mut c_group,
+ &mut *c_memlist,
+ &mut member_list_entries,
+ )
+ };
+ if res == ffi::CS_OK {
+ Ok(cpg_array_to_vec(
+ member_list.as_ptr(),
+ member_list_entries as usize,
+ ))
+ } else {
+ Err(CsError::from_c(res))
+ }
+}
+
+/// Get the maximum size that CPG can send in one corosync message,
+/// any messages sent via [mcast_joined] that are larger than this
+/// will be fragmented
+pub fn max_atomic_msgsize_get(handle: Handle) -> Result<u32> {
+ let mut asize: u32 = 0;
+ let res = unsafe { ffi::cpg_max_atomic_msgsize_get(handle.cpg_handle, &mut asize) };
+ if res == ffi::CS_OK {
+ Ok(asize)
+ } else {
+ Err(CsError::from_c(res))
+ }
+}
+
+/// Get the current 'context' value for this handle.
+/// The context value is an arbitrary value that is always passed
+/// back to callbacks to help identify the source
+pub fn context_get(handle: Handle) -> Result<u64> {
+ let mut c_context: *mut c_void = &mut 0u64 as *mut _ as *mut c_void;
+ let (res, context) = unsafe {
+ let r = ffi::cpg_context_get(handle.cpg_handle, &mut c_context);
+ let context: u64 = c_context as u64;
+ (r, context)
+ };
+ if res == ffi::CS_OK {
+ Ok(context)
+ } else {
+ Err(CsError::from_c(res))
+ }
+}
+
+/// Set the current 'context' value for this handle.
+/// The context value is an arbitrary value that is always passed
+/// back to callbacks to help identify the source.
+/// Normally this is set in [initialize], but this allows it to be changed
+pub fn context_set(handle: Handle, context: u64) -> Result<()> {
+ let res = unsafe {
+ let c_context = context as *mut c_void;
+ ffi::cpg_context_set(handle.cpg_handle, c_context)
+ };
+ if res == ffi::CS_OK {
+ Ok(())
+ } else {
+ Err(CsError::from_c(res))
+ }
+}
+
+/// Get the flow control state of corosync CPG
+pub fn flow_control_state_get(handle: Handle) -> Result<bool> {
+ let mut fc_state: u32 = 0;
+ let res = unsafe { ffi::cpg_flow_control_state_get(handle.cpg_handle, &mut fc_state) };
+ if res == ffi::CS_OK {
+ if fc_state == 1 {
+ Ok(true)
+ } else {
+ Ok(false)
+ }
+ } else {
+ Err(CsError::from_c(res))
+ }
+}
+
+/// Send a message to the currently joined CPG group
+pub fn mcast_joined(handle: Handle, guarantee: Guarantee, msg: &[u8]) -> Result<()> {
+ let c_iovec = ffi::iovec {
+ iov_base: msg.as_ptr() as *mut c_void,
+ iov_len: msg.len(),
+ };
+ let res = unsafe { ffi::cpg_mcast_joined(handle.cpg_handle, guarantee.to_c(), &c_iovec, 1) };
+ if res == ffi::CS_OK {
+ Ok(())
+ } else {
+ Err(CsError::from_c(res))
+ }
+}
+
+/// Type of iteration for [CpgIterStart]
+#[derive(Copy, Clone)]
+pub enum CpgIterType {
+ NameOnly = 1,
+ OneGroup = 2,
+ All = 3,
+}
+
+// Iterator based on information on this page. thank you!
+// https://stackoverflow.com/questions/30218886/how-to-implement-iterator-and-intoiterator-for-a-simple-struct
+// Object to iterate over
+/// An object to iterate over a list of CPG groups, create one of these and then use 'for' over it
+pub struct CpgIterStart {
+ iter_handle: u64,
+}
+
+/// struct returned from iterating over a [CpgIterStart]
+pub struct CpgIter {
+ pub group: String,
+ pub nodeid: NodeId,
+ pub pid: u32,
+}
+
+pub struct CpgIntoIter {
+ iter_handle: u64,
+}
+
+impl fmt::Debug for CpgIter {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ write!(
+ f,
+ "[group: {}, nodeid: {}, pid: {}]",
+ self.group, self.nodeid, self.pid
+ )
+ }
+}
+
+impl Iterator for CpgIntoIter {
+ type Item = CpgIter;
+
+ fn next(&mut self) -> Option<CpgIter> {
+ let mut c_iter_description = ffi::cpg_iteration_description_t {
+ nodeid: 0,
+ pid: 0,
+ group: ffi::cpg_name {
+ length: 0_u32,
+ value: [0; CPG_NAMELEN_MAX],
+ },
+ };
+ let res = unsafe { ffi::cpg_iteration_next(self.iter_handle, &mut c_iter_description) };
+
+ if res == ffi::CS_OK {
+ let r_group =
+ match string_from_bytes(c_iter_description.group.value.as_ptr(), CPG_NAMELEN_MAX) {
+ Ok(groupname) => groupname,
+ Err(_) => return None,
+ };
+ Some(CpgIter {
+ group: r_group,
+ nodeid: NodeId::from(c_iter_description.nodeid),
+ pid: c_iter_description.pid,
+ })
+ } else if res == ffi::CS_ERR_NO_SECTIONS {
+ // End of list
+ unsafe {
+ // Yeah, we don't check this return code. There's nowhere to report it.
+ ffi::cpg_iteration_finalize(self.iter_handle)
+ };
+ None
+ } else {
+ None
+ }
+ }
+}
+
+impl CpgIterStart {
+ /// Create a new [CpgIterStart] object for iterating over a list of active CPG groups
+ pub fn new(cpg_handle: Handle, group: &str, iter_type: CpgIterType) -> Result<CpgIterStart> {
+ let mut iter_handle: u64 = 0;
+ let res = unsafe {
+ let mut c_group = string_to_cpg_name(group)?;
+ let c_itertype = iter_type as u32;
+ // IterType 'All' requires that the group pointer is passed in as NULL
+ let c_group_ptr = {
+ match iter_type {
+ CpgIterType::All => std::ptr::null_mut(),
+ _ => &mut c_group,
+ }
+ };
+ ffi::cpg_iteration_initialize(
+ cpg_handle.cpg_handle,
+ c_itertype,
+ c_group_ptr,
+ &mut iter_handle,
+ )
+ };
+ if res == ffi::CS_OK {
+ Ok(CpgIterStart { iter_handle })
+ } else {
+ Err(CsError::from_c(res))
+ }
+ }
+}
+
+impl IntoIterator for CpgIterStart {
+ type Item = CpgIter;
+ type IntoIter = CpgIntoIter;
+
+ fn into_iter(self) -> Self::IntoIter {
+ CpgIntoIter {
+ iter_handle: self.iter_handle,
+ }
+ }
+}
diff --git a/bindings/rust/src/lib.rs b/bindings/rust/src/lib.rs
new file mode 100644
index 0000000..dbf34fc
--- /dev/null
+++ b/bindings/rust/src/lib.rs
@@ -0,0 +1,296 @@
+//! This crate provides access to the corosync libraries cpg, cfg, cmap, quorum & votequorum
+//! from Rust. They are a fairly thin layer around the actual API calls but with Rust data types
+//! and iterators.
+//!
+//! Corosync is a low-level provider of cluster services for high-availability clusters,
+//! for more information about corosync see <https://corosync.github.io/corosync/>
+//!
+//! No more information about corosync itself will be provided here, it is expected that if
+//! you feel you need access to the Corosync API calls, you know what they do :)
+//!
+//! # Example
+//! ```
+//! extern crate rust_corosync as corosync;
+//! use corosync::cmap;
+//!
+//! fn main()
+//! {
+//! // Open connection to corosync libcmap
+//! let handle =
+//! match cmap::initialize(cmap::Map::Icmap) {
+//! Ok(h) => {
+//! println!("cmap initialized.");
+//! h
+//! }
+//! Err(e) => {
+//! println!("Error in CMAP (Icmap) init: {}", e);
+//! return;
+//! }
+//! };
+//!
+//! // Set a numeric value (this is a generic fn)
+//! match cmap::set_number(handle, "test.test_uint32", 456)
+//! {
+//! Ok(_) => {}
+//! Err(e) => {
+//! println!("Error in CMAP set_u32: {}", e);
+//! return;
+//! }
+//! };
+//!
+//! // Get a value - this will be a Data struct
+//! match cmap::get(handle, "test.test_uint32")
+//! {
+//! Ok(v) => {
+//! println!("GOT value {}", v);
+//! }
+//! Err(e) => {
+//! println!("Error in CMAP get: {}", e);
+//! return;
+//! }
+//! };
+//!
+//! // Use an iterator
+//! match cmap::CmapIterStart::new(handle, "totem.") {
+//! Ok(cmap_iter) => {
+//! for i in cmap_iter {
+//! println!("ITER: {:?}", i);
+//! }
+//! println!("");
+//! }
+//! Err(e) => {
+//! println!("Error in CMAP iter start: {}", e);
+//! }
+//! }
+//!
+//! // Close this connection
+//! match cmap::finalize(handle)
+//! {
+//! Ok(_) => {}
+//! Err(e) => {
+//! println!("Error in CMAP get: {}", e);
+//! return;
+//! }
+//! };
+//! }
+
+#[macro_use]
+extern crate lazy_static;
+#[macro_use]
+extern crate bitflags;
+
+/// cfg is the internal configuration and information library for corosync, it is
+/// mainly used by internal tools but may also contain API calls useful to some applications
+/// that need detailed information about or control of the operation of corosync and the cluster.
+pub mod cfg;
+/// cmap is the internal 'database' of corosync - though it is NOT replicated. Mostly it contains
+/// a copy of the corosync.conf file and information about the running state of the daemon.
+/// The cmap API provides two 'maps'. Icmap, which is as above, and Stats, which contains very detailed
+/// statistics on the running system, this includes network and IPC calls.
+pub mod cmap;
+/// cpg is the Control Process Groups subsystem of corosync and is usually used for sending
+/// messages around the cluster. All processes using CPG belong to a named group (whose members
+/// they can query) and all messages are sent with delivery guarantees.
+pub mod cpg;
+/// Quorum provides basic information about the quorate state of the cluster with callbacks
+/// when nodelists change.
+pub mod quorum;
+///votequorum is the main quorum provider for corosync, using this API, users can query the state
+/// of nodes in the cluster, request callbacks when the nodelists change, and set up a quorum device.
+pub mod votequorum;
+
+mod sys;
+
+use num_enum::TryFromPrimitive;
+use std::convert::TryFrom;
+use std::error::Error;
+use std::ffi::CString;
+use std::fmt;
+use std::ptr::copy_nonoverlapping;
+
+// This needs to be kept up-to-date!
+/// Error codes returned from the corosync libraries
+#[derive(Debug, Eq, PartialEq, Copy, Clone, TryFromPrimitive)]
+#[repr(u32)]
+pub enum CsError {
+ CsOk = 1,
+ CsErrLibrary = 2,
+ CsErrVersion = 3,
+ CsErrInit = 4,
+ CsErrTimeout = 5,
+ CsErrTryAgain = 6,
+ CsErrInvalidParam = 7,
+ CsErrNoMemory = 8,
+ CsErrBadHandle = 9,
+ CsErrBusy = 10,
+ CsErrAccess = 11,
+ CsErrNotExist = 12,
+ CsErrNameTooLong = 13,
+ CsErrExist = 14,
+ CsErrNoSpace = 15,
+ CsErrInterrupt = 16,
+ CsErrNameNotFound = 17,
+ CsErrNoResources = 18,
+ CsErrNotSupported = 19,
+ CsErrBadOperation = 20,
+ CsErrFailedOperation = 21,
+ CsErrMessageError = 22,
+ CsErrQueueFull = 23,
+ CsErrQueueNotAvailable = 24,
+ CsErrBadFlags = 25,
+ CsErrTooBig = 26,
+ CsErrNoSection = 27,
+ CsErrContextNotFound = 28,
+ CsErrTooManyGroups = 30,
+ CsErrSecurity = 100,
+ #[num_enum(default)]
+ CsErrRustCompat = 998, // Set if we get a unknown return from corosync
+ CsErrRustString = 999, // Set if we get a string conversion error
+}
+
+/// Result type returned from most corosync library calls.
+/// Contains a [CsError] and possibly other data as required
+pub type Result<T> = ::std::result::Result<T, CsError>;
+
+impl fmt::Display for CsError {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ match self {
+ CsError::CsOk => write!(f, "OK"),
+ CsError::CsErrLibrary => write!(f, "ErrLibrary"),
+ CsError::CsErrVersion => write!(f, "ErrVersion"),
+ CsError::CsErrInit => write!(f, "ErrInit"),
+ CsError::CsErrTimeout => write!(f, "ErrTimeout"),
+ CsError::CsErrTryAgain => write!(f, "ErrTryAgain"),
+ CsError::CsErrInvalidParam => write!(f, "ErrInvalidParam"),
+ CsError::CsErrNoMemory => write!(f, "ErrNoMemory"),
+ CsError::CsErrBadHandle => write!(f, "ErrbadHandle"),
+ CsError::CsErrBusy => write!(f, "ErrBusy"),
+ CsError::CsErrAccess => write!(f, "ErrAccess"),
+ CsError::CsErrNotExist => write!(f, "ErrNotExist"),
+ CsError::CsErrNameTooLong => write!(f, "ErrNameTooLong"),
+ CsError::CsErrExist => write!(f, "ErrExist"),
+ CsError::CsErrNoSpace => write!(f, "ErrNoSpace"),
+ CsError::CsErrInterrupt => write!(f, "ErrInterrupt"),
+ CsError::CsErrNameNotFound => write!(f, "ErrNameNotFound"),
+ CsError::CsErrNoResources => write!(f, "ErrNoResources"),
+ CsError::CsErrNotSupported => write!(f, "ErrNotSupported"),
+ CsError::CsErrBadOperation => write!(f, "ErrBadOperation"),
+ CsError::CsErrFailedOperation => write!(f, "ErrFailedOperation"),
+ CsError::CsErrMessageError => write!(f, "ErrMEssageError"),
+ CsError::CsErrQueueFull => write!(f, "ErrQueueFull"),
+ CsError::CsErrQueueNotAvailable => write!(f, "ErrQueueNotAvailable"),
+ CsError::CsErrBadFlags => write!(f, "ErrBadFlags"),
+ CsError::CsErrTooBig => write!(f, "ErrTooBig"),
+ CsError::CsErrNoSection => write!(f, "ErrNoSection"),
+ CsError::CsErrContextNotFound => write!(f, "ErrContextNotFound"),
+ CsError::CsErrTooManyGroups => write!(f, "ErrTooManyGroups"),
+ CsError::CsErrSecurity => write!(f, "ErrSecurity"),
+ CsError::CsErrRustCompat => write!(f, "ErrRustCompat"),
+ CsError::CsErrRustString => write!(f, "ErrRustString"),
+ }
+ }
+}
+
+impl Error for CsError {}
+
+// This is dependant on the num_enum crate, converts a C cs_error_t into the Rust enum
+// There seems to be some debate as to whether this should be part of the language:
+// https://internals.rust-lang.org/t/pre-rfc-enum-from-integer/6348/25
+impl CsError {
+ fn from_c(cserr: u32) -> CsError {
+ match CsError::try_from(cserr) {
+ Ok(e) => e,
+ Err(_) => CsError::CsErrRustCompat,
+ }
+ }
+}
+
+/// Flags to use with dispatch functions, eg [cpg::dispatch]
+/// One will dispatch a single callback (blocking) and return.
+/// All will loop trying to dispatch all possible callbacks.
+/// Blocking is like All but will block between callbacks.
+/// OneNonBlocking will dispatch a single callback only if one is available,
+/// otherwise it will return even if no callback is available.
+#[derive(Copy, Clone)]
+// The numbers match the C enum, of course.
+pub enum DispatchFlags {
+ One = 1,
+ All = 2,
+ Blocking = 3,
+ OneNonblocking = 4,
+}
+
+/// Flags to use with (most) tracking API calls
+#[derive(Copy, Clone)]
+// Same here
+pub enum TrackFlags {
+ Current = 1,
+ Changes = 2,
+ ChangesOnly = 4,
+}
+
+/// A corosync nodeid
+#[derive(Copy, Clone, Debug, PartialEq, Eq)]
+pub struct NodeId {
+ id: u32,
+}
+
+impl fmt::Display for NodeId {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ write!(f, "{}", self.id)
+ }
+}
+
+// Conversion from a NodeId to and from u32
+impl From<u32> for NodeId {
+ fn from(id: u32) -> NodeId {
+ NodeId { id }
+ }
+}
+
+impl From<NodeId> for u32 {
+ fn from(nodeid: NodeId) -> u32 {
+ nodeid.id
+ }
+}
+
+// General internal routine to copy bytes from a C array into a Rust String
+fn string_from_bytes(bytes: *const ::std::os::raw::c_char, max_length: usize) -> Result<String> {
+ let mut newbytes = vec![0u8; max_length];
+
+ // Get length of the string in old-fashioned style
+ let mut length: usize = 0;
+ let mut count = 0;
+ let mut tmpbytes = bytes;
+ while count < max_length || length == 0 {
+ if unsafe { *tmpbytes } == 0 && length == 0 {
+ length = count;
+ break;
+ }
+ count += 1;
+ tmpbytes = unsafe { tmpbytes.offset(1) }
+ }
+
+ // Cope with an empty string
+ if length == 0 {
+ return Ok(String::new());
+ }
+
+ unsafe {
+ // We need to fully copy it, not shallow copy it.
+ // Messy casting on both parts of the copy here to get it to work on both signed
+ // and unsigned char machines
+ copy_nonoverlapping(bytes as *mut i8, newbytes.as_mut_ptr() as *mut i8, length);
+ }
+
+ let cs = match CString::new(&newbytes[0..length]) {
+ Ok(c1) => c1,
+ Err(_) => return Err(CsError::CsErrRustString),
+ };
+
+ // This is just to convert the error type
+ match cs.into_string() {
+ Ok(s) => Ok(s),
+ Err(_) => Err(CsError::CsErrRustString),
+ }
+}
diff --git a/bindings/rust/src/quorum.rs b/bindings/rust/src/quorum.rs
new file mode 100644
index 0000000..25c2fe6
--- /dev/null
+++ b/bindings/rust/src/quorum.rs
@@ -0,0 +1,298 @@
+// libquorum interface for Rust
+// Copyright (c) 2021 Red Hat, Inc.
+//
+// All rights reserved.
+//
+// Author: Christine Caulfield (ccaulfi@redhat.com)
+//
+
+#![allow(clippy::type_complexity)]
+#![allow(clippy::needless_range_loop)]
+#![allow(clippy::single_match)]
+
+// For the code generated by bindgen
+use crate::sys::quorum as ffi;
+
+use crate::{CsError, DispatchFlags, NodeId, Result, TrackFlags};
+use std::collections::HashMap;
+use std::os::raw::{c_int, c_void};
+use std::slice;
+use std::sync::Mutex;
+
+/// Data for model1 [initialize]
+#[derive(Copy, Clone)]
+pub enum ModelData {
+ ModelNone,
+ ModelV1(Model1Data),
+}
+
+/// Value returned from [initialize]. Indicates whether quorum is currently active on this cluster.
+pub enum QuorumType {
+ Free,
+ Set,
+}
+
+/// Flags for [initialize], none currently supported
+#[derive(Copy, Clone)]
+pub enum Model1Flags {
+ None,
+}
+
+/// RingId returned in quorum_notification_fn
+pub struct RingId {
+ pub nodeid: NodeId,
+ pub seq: u64,
+}
+
+// Used to convert a QUORUM handle into one of ours
+lazy_static! {
+ static ref HANDLE_HASH: Mutex<HashMap<u64, Handle>> = Mutex::new(HashMap::new());
+}
+
+fn list_to_vec(list_entries: u32, list: *const u32) -> Vec<NodeId> {
+ let mut r_member_list = Vec::<NodeId>::new();
+ let temp_members: &[u32] = unsafe { slice::from_raw_parts(list, list_entries as usize) };
+ for i in 0..list_entries as usize {
+ r_member_list.push(NodeId::from(temp_members[i]));
+ }
+ r_member_list
+}
+
+// Called from quorum callback function - munge params back to Rust from C
+extern "C" fn rust_quorum_notification_fn(
+ handle: ffi::quorum_handle_t,
+ quorate: u32,
+ ring_id: ffi::quorum_ring_id,
+ member_list_entries: u32,
+ member_list: *const u32,
+) {
+ if let Some(h) = HANDLE_HASH.lock().unwrap().get(&handle) {
+ let r_ring_id = RingId {
+ nodeid: NodeId::from(ring_id.nodeid),
+ seq: ring_id.seq,
+ };
+ let r_member_list = list_to_vec(member_list_entries, member_list);
+ let r_quorate = match quorate {
+ 0 => false,
+ 1 => true,
+ _ => false,
+ };
+ match &h.model_data {
+ ModelData::ModelV1(md) => {
+ if let Some(cb) = md.quorum_notification_fn {
+ (cb)(h, r_quorate, r_ring_id, r_member_list);
+ }
+ }
+ _ => {}
+ }
+ }
+}
+
+extern "C" fn rust_nodelist_notification_fn(
+ handle: ffi::quorum_handle_t,
+ ring_id: ffi::quorum_ring_id,
+ member_list_entries: u32,
+ member_list: *const u32,
+ joined_list_entries: u32,
+ joined_list: *const u32,
+ left_list_entries: u32,
+ left_list: *const u32,
+) {
+ if let Some(h) = HANDLE_HASH.lock().unwrap().get(&handle) {
+ let r_ring_id = RingId {
+ nodeid: NodeId::from(ring_id.nodeid),
+ seq: ring_id.seq,
+ };
+
+ let r_member_list = list_to_vec(member_list_entries, member_list);
+ let r_joined_list = list_to_vec(joined_list_entries, joined_list);
+ let r_left_list = list_to_vec(left_list_entries, left_list);
+
+ match &h.model_data {
+ ModelData::ModelV1(md) => {
+ if let Some(cb) = md.nodelist_notification_fn {
+ (cb)(h, r_ring_id, r_member_list, r_joined_list, r_left_list);
+ }
+ }
+ _ => {}
+ }
+ }
+}
+
+#[derive(Copy, Clone)]
+/// Data for model1 [initialize]
+pub struct Model1Data {
+ pub flags: Model1Flags,
+ pub quorum_notification_fn:
+ Option<fn(hande: &Handle, quorate: bool, ring_id: RingId, member_list: Vec<NodeId>)>,
+ pub nodelist_notification_fn: Option<
+ fn(
+ hande: &Handle,
+ ring_id: RingId,
+ member_list: Vec<NodeId>,
+ joined_list: Vec<NodeId>,
+ left_list: Vec<NodeId>,
+ ),
+ >,
+}
+
+/// A handle into the quorum library. Returned from [initialize] and needed for all other calls
+#[derive(Copy, Clone)]
+pub struct Handle {
+ quorum_handle: u64,
+ model_data: ModelData,
+}
+
+/// Initialize a connection to the quorum library. You must call this before doing anything
+/// else and use the passed back [Handle].
+/// Remember to free the handle using [finalize] when finished.
+pub fn initialize(model_data: &ModelData, context: u64) -> Result<(Handle, QuorumType)> {
+ let mut handle: ffi::quorum_handle_t = 0;
+ let mut quorum_type: u32 = 0;
+
+ let mut m = match model_data {
+ ModelData::ModelV1(_v1) => ffi::quorum_model_v1_data_t {
+ model: ffi::QUORUM_MODEL_V1,
+ quorum_notify_fn: Some(rust_quorum_notification_fn),
+ nodelist_notify_fn: Some(rust_nodelist_notification_fn),
+ },
+ // Only V1 supported. No point in doing legacy stuff in a new binding
+ _ => return Err(CsError::CsErrInvalidParam),
+ };
+
+ handle = unsafe {
+ let c_context: *mut c_void = &mut &context as *mut _ as *mut c_void;
+ let c_model: *mut ffi::quorum_model_data_t =
+ &mut m as *mut _ as *mut ffi::quorum_model_data_t;
+ let res = ffi::quorum_model_initialize(
+ &mut handle,
+ m.model,
+ c_model,
+ &mut quorum_type,
+ c_context,
+ );
+
+ if res == ffi::CS_OK {
+ handle
+ } else {
+ return Err(CsError::from_c(res));
+ }
+ };
+
+ let quorum_type = match quorum_type {
+ 0 => QuorumType::Free,
+ 1 => QuorumType::Set,
+ _ => QuorumType::Set,
+ };
+ let rhandle = Handle {
+ quorum_handle: handle,
+ model_data: *model_data,
+ };
+ HANDLE_HASH.lock().unwrap().insert(handle, rhandle);
+ Ok((rhandle, quorum_type))
+}
+
+/// Finish with a connection to corosync
+pub fn finalize(handle: Handle) -> Result<()> {
+ let res = unsafe { ffi::quorum_finalize(handle.quorum_handle) };
+ if res == ffi::CS_OK {
+ HANDLE_HASH.lock().unwrap().remove(&handle.quorum_handle);
+ Ok(())
+ } else {
+ Err(CsError::from_c(res))
+ }
+}
+
+// Not sure if an FD is the right thing to return here, but it will do for now.
+/// Return a file descriptor to use for poll/select on the QUORUM handle
+pub fn fd_get(handle: Handle) -> Result<i32> {
+ let c_fd: *mut c_int = &mut 0 as *mut _ as *mut c_int;
+ let res = unsafe { ffi::quorum_fd_get(handle.quorum_handle, c_fd) };
+ if res == ffi::CS_OK {
+ Ok(c_fd as i32)
+ } else {
+ Err(CsError::from_c(res))
+ }
+}
+
+/// Display any/all active QUORUM callbacks for this [Handle], see [DispatchFlags] for details
+pub fn dispatch(handle: Handle, flags: DispatchFlags) -> Result<()> {
+ let res = unsafe { ffi::quorum_dispatch(handle.quorum_handle, flags as u32) };
+ if res == ffi::CS_OK {
+ Ok(())
+ } else {
+ Err(CsError::from_c(res))
+ }
+}
+
+/// Return the quorate status of the cluster
+pub fn getquorate(handle: Handle) -> Result<bool> {
+ let c_quorate: *mut c_int = &mut 0 as *mut _ as *mut c_int;
+ let (res, r_quorate) = unsafe {
+ let res = ffi::quorum_getquorate(handle.quorum_handle, c_quorate);
+ let r_quorate: i32 = *c_quorate;
+ (res, r_quorate)
+ };
+ if res == ffi::CS_OK {
+ match r_quorate {
+ 0 => Ok(false),
+ 1 => Ok(true),
+ _ => Err(CsError::CsErrLibrary),
+ }
+ } else {
+ Err(CsError::from_c(res))
+ }
+}
+
+/// Track node and quorum changes
+pub fn trackstart(handle: Handle, flags: TrackFlags) -> Result<()> {
+ let res = unsafe { ffi::quorum_trackstart(handle.quorum_handle, flags as u32) };
+ if res == ffi::CS_OK {
+ Ok(())
+ } else {
+ Err(CsError::from_c(res))
+ }
+}
+
+/// Stop tracking node and quorum changes
+pub fn trackstop(handle: Handle) -> Result<()> {
+ let res = unsafe { ffi::quorum_trackstop(handle.quorum_handle) };
+ if res == ffi::CS_OK {
+ Ok(())
+ } else {
+ Err(CsError::from_c(res))
+ }
+}
+
+/// Get the current 'context' value for this handle.
+/// The context value is an arbitrary value that is always passed
+/// back to callbacks to help identify the source
+pub fn context_get(handle: Handle) -> Result<u64> {
+ let (res, context) = unsafe {
+ let mut context: u64 = 0;
+ let c_context: *mut c_void = &mut context as *mut _ as *mut c_void;
+ let r = ffi::quorum_context_get(handle.quorum_handle, c_context as *mut *const c_void);
+ (r, context)
+ };
+ if res == ffi::CS_OK {
+ Ok(context)
+ } else {
+ Err(CsError::from_c(res))
+ }
+}
+
+/// Set the current 'context' value for this handle.
+/// The context value is an arbitrary value that is always passed
+/// back to callbacks to help identify the source.
+/// Normally this is set in [initialize], but this allows it to be changed
+pub fn context_set(handle: Handle, context: u64) -> Result<()> {
+ let res = unsafe {
+ let c_context = context as *mut c_void;
+ ffi::quorum_context_set(handle.quorum_handle, c_context)
+ };
+ if res == ffi::CS_OK {
+ Ok(())
+ } else {
+ Err(CsError::from_c(res))
+ }
+}
diff --git a/bindings/rust/src/sys/mod.rs b/bindings/rust/src/sys/mod.rs
new file mode 100644
index 0000000..03dfec2
--- /dev/null
+++ b/bindings/rust/src/sys/mod.rs
@@ -0,0 +1,7 @@
+#![allow(non_camel_case_types, non_snake_case, dead_code, improper_ctypes)]
+
+pub mod cfg;
+pub mod cmap;
+pub mod cpg;
+pub mod quorum;
+pub mod votequorum;
diff --git a/bindings/rust/src/votequorum.rs b/bindings/rust/src/votequorum.rs
new file mode 100644
index 0000000..4718b58
--- /dev/null
+++ b/bindings/rust/src/votequorum.rs
@@ -0,0 +1,501 @@
+// libvotequorum interface for Rust
+// Copyright (c) 2021 Red Hat, Inc.
+//
+// All rights reserved.
+//
+// Author: Christine Caulfield (ccaulfi@redhat.com)
+//
+
+#![allow(clippy::type_complexity)]
+#![allow(clippy::needless_range_loop)]
+#![allow(clippy::single_match)]
+
+// For the code generated by bindgen
+use crate::sys::votequorum as ffi;
+
+use std::collections::HashMap;
+use std::ffi::CString;
+use std::fmt;
+use std::os::raw::{c_int, c_void};
+use std::slice;
+use std::sync::Mutex;
+
+use crate::string_from_bytes;
+use crate::{CsError, DispatchFlags, NodeId, Result, TrackFlags};
+
+/// RingId returned by votequorum_notification_fn
+pub struct RingId {
+ pub nodeid: NodeId,
+ pub seq: u64,
+}
+
+// Used to convert a VOTEQUORUM handle into one of ours
+lazy_static! {
+ static ref HANDLE_HASH: Mutex<HashMap<u64, Handle>> = Mutex::new(HashMap::new());
+}
+
+/// Current state of a node in the cluster, part of the [NodeInfo] and [Node] structs
+pub enum NodeState {
+ Member,
+ Dead,
+ Leaving,
+ Unknown,
+}
+impl NodeState {
+ pub fn new(state: u32) -> NodeState {
+ match state {
+ 1 => NodeState::Member,
+ 2 => NodeState::Dead,
+ 3 => NodeState::Leaving,
+ _ => NodeState::Unknown,
+ }
+ }
+}
+impl fmt::Debug for NodeState {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ match self {
+ NodeState::Member => write!(f, "Member"),
+ NodeState::Dead => write!(f, "Dead"),
+ NodeState::Leaving => write!(f, "Leaving"),
+ _ => write!(f, "Unknown"),
+ }
+ }
+}
+
+/// Basic information about a node in the cluster. Contains [NodeId], and [NodeState]
+pub struct Node {
+ nodeid: NodeId,
+ state: NodeState,
+}
+impl fmt::Debug for Node {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ write!(f, "nodeid: {}, state: {:?}", self.nodeid, self.state)
+ }
+}
+
+bitflags! {
+/// Flags in the [NodeInfo] struct
+ pub struct NodeInfoFlags: u32
+ {
+ const VOTEQUORUM_INFO_TWONODE = 1;
+ const VOTEQUORUM_INFO_QUORATE = 2;
+ const VOTEQUORUM_INFO_WAIT_FOR_ALL = 4;
+ const VOTEQUORUM_INFO_LAST_MAN_STANDING = 8;
+ const VOTEQUORUM_INFO_AUTO_TIE_BREAKER = 16;
+ const VOTEQUORUM_INFO_ALLOW_DOWNSCALE = 32;
+ const VOTEQUORUM_INFO_QDEVICE_REGISTERED = 64;
+ const VOTEQUORUM_INFO_QDEVICE_ALIVE = 128;
+ const VOTEQUORUM_INFO_QDEVICE_CAST_VOTE = 256;
+ const VOTEQUORUM_INFO_QDEVICE_MASTER_WINS = 512;
+ }
+}
+
+/// Detailed information about a node in the cluster, returned from [get_info]
+pub struct NodeInfo {
+ pub node_id: NodeId,
+ pub node_state: NodeState,
+ pub node_votes: u32,
+ pub node_expected_votes: u32,
+ pub highest_expected: u32,
+ pub quorum: u32,
+ pub flags: NodeInfoFlags,
+ pub qdevice_votes: u32,
+ pub qdevice_name: String,
+}
+
+// Turn a C nodeID list into a vec of NodeIds
+fn list_to_vec(list_entries: u32, list: *const u32) -> Vec<NodeId> {
+ let mut r_member_list = Vec::<NodeId>::new();
+ let temp_members: &[u32] = unsafe { slice::from_raw_parts(list, list_entries as usize) };
+ for i in 0..list_entries as usize {
+ r_member_list.push(NodeId::from(temp_members[i]));
+ }
+ r_member_list
+}
+
+// Called from votequorum callback function - munge params back to Rust from C
+extern "C" fn rust_expectedvotes_notification_fn(
+ handle: ffi::votequorum_handle_t,
+ context: u64,
+ expected_votes: u32,
+) {
+ if let Some(h) = HANDLE_HASH.lock().unwrap().get(&handle) {
+ if let Some(cb) = h.callbacks.expectedvotes_notification_fn {
+ (cb)(h, context, expected_votes);
+ }
+ }
+}
+
+// Called from votequorum callback function - munge params back to Rust from C
+extern "C" fn rust_quorum_notification_fn(
+ handle: ffi::votequorum_handle_t,
+ context: u64,
+ quorate: u32,
+ node_list_entries: u32,
+ node_list: *mut ffi::votequorum_node_t,
+) {
+ if let Some(h) = HANDLE_HASH.lock().unwrap().get(&handle) {
+ let r_quorate = match quorate {
+ 0 => false,
+ 1 => true,
+ _ => false,
+ };
+ let mut r_node_list = Vec::<Node>::new();
+ let temp_members: &[ffi::votequorum_node_t] =
+ unsafe { slice::from_raw_parts(node_list, node_list_entries as usize) };
+ for i in 0..node_list_entries as usize {
+ r_node_list.push(Node {
+ nodeid: NodeId::from(temp_members[i].nodeid),
+ state: NodeState::new(temp_members[i].state),
+ });
+ }
+ if let Some(cb) = h.callbacks.quorum_notification_fn {
+ (cb)(h, context, r_quorate, r_node_list);
+ }
+ }
+}
+
+// Called from votequorum callback function - munge params back to Rust from C
+extern "C" fn rust_nodelist_notification_fn(
+ handle: ffi::votequorum_handle_t,
+ context: u64,
+ ring_id: ffi::votequorum_ring_id_t,
+ node_list_entries: u32,
+ node_list: *mut u32,
+) {
+ if let Some(h) = HANDLE_HASH.lock().unwrap().get(&handle) {
+ let r_ring_id = RingId {
+ nodeid: NodeId::from(ring_id.nodeid),
+ seq: ring_id.seq,
+ };
+
+ let r_node_list = list_to_vec(node_list_entries, node_list);
+
+ if let Some(cb) = h.callbacks.nodelist_notification_fn {
+ (cb)(h, context, r_ring_id, r_node_list);
+ }
+ }
+}
+
+/// Callbacks that can be called from votequorum, pass these in to [initialize]
+#[derive(Copy, Clone)]
+pub struct Callbacks {
+ pub quorum_notification_fn:
+ Option<fn(hande: &Handle, context: u64, quorate: bool, node_list: Vec<Node>)>,
+ pub nodelist_notification_fn:
+ Option<fn(hande: &Handle, context: u64, ring_id: RingId, node_list: Vec<NodeId>)>,
+ pub expectedvotes_notification_fn:
+ Option<fn(handle: &Handle, context: u64, expected_votes: u32)>,
+}
+
+/// A handle into the votequorum library. Returned from [initialize] and needed for all other calls
+#[derive(Copy, Clone)]
+pub struct Handle {
+ votequorum_handle: u64,
+ callbacks: Callbacks,
+}
+
+/// Initialize a connection to the votequorum library. You must call this before doing anything
+/// else and use the passed back [Handle].
+/// Remember to free the handle using [finalize] when finished.
+pub fn initialize(callbacks: &Callbacks) -> Result<Handle> {
+ let mut handle: ffi::votequorum_handle_t = 0;
+
+ let mut c_callbacks = ffi::votequorum_callbacks_t {
+ votequorum_quorum_notify_fn: Some(rust_quorum_notification_fn),
+ votequorum_nodelist_notify_fn: Some(rust_nodelist_notification_fn),
+ votequorum_expectedvotes_notify_fn: Some(rust_expectedvotes_notification_fn),
+ };
+
+ unsafe {
+ let res = ffi::votequorum_initialize(&mut handle, &mut c_callbacks);
+ if res == ffi::CS_OK {
+ let rhandle = Handle {
+ votequorum_handle: handle,
+ callbacks: *callbacks,
+ };
+ HANDLE_HASH.lock().unwrap().insert(handle, rhandle);
+ Ok(rhandle)
+ } else {
+ Err(CsError::from_c(res))
+ }
+ }
+}
+
+/// Finish with a connection to corosync
+pub fn finalize(handle: Handle) -> Result<()> {
+ let res = unsafe { ffi::votequorum_finalize(handle.votequorum_handle) };
+ if res == ffi::CS_OK {
+ HANDLE_HASH
+ .lock()
+ .unwrap()
+ .remove(&handle.votequorum_handle);
+ Ok(())
+ } else {
+ Err(CsError::from_c(res))
+ }
+}
+
+// Not sure if an FD is the right thing to return here, but it will do for now.
+/// Return a file descriptor to use for poll/select on the VOTEQUORUM handle
+pub fn fd_get(handle: Handle) -> Result<i32> {
+ let c_fd: *mut c_int = &mut 0 as *mut _ as *mut c_int;
+ let res = unsafe { ffi::votequorum_fd_get(handle.votequorum_handle, c_fd) };
+ if res == ffi::CS_OK {
+ Ok(c_fd as i32)
+ } else {
+ Err(CsError::from_c(res))
+ }
+}
+
+const VOTEQUORUM_QDEVICE_MAX_NAME_LEN: usize = 255;
+
+/// Returns detailed information about a node in a [NodeInfo] structure
+pub fn get_info(handle: Handle, nodeid: NodeId) -> Result<NodeInfo> {
+ let mut c_info = ffi::votequorum_info {
+ node_id: 0,
+ node_state: 0,
+ node_votes: 0,
+ node_expected_votes: 0,
+ highest_expected: 0,
+ total_votes: 0,
+ quorum: 0,
+ flags: 0,
+ qdevice_votes: 0,
+ qdevice_name: [0; 255usize],
+ };
+ let res = unsafe {
+ ffi::votequorum_getinfo(handle.votequorum_handle, u32::from(nodeid), &mut c_info)
+ };
+
+ if res == ffi::CS_OK {
+ let info = NodeInfo {
+ node_id: NodeId::from(c_info.node_id),
+ node_state: NodeState::new(c_info.node_state),
+ node_votes: c_info.node_votes,
+ node_expected_votes: c_info.node_expected_votes,
+ highest_expected: c_info.highest_expected,
+ quorum: c_info.quorum,
+ flags: NodeInfoFlags { bits: c_info.flags },
+ qdevice_votes: c_info.qdevice_votes,
+ qdevice_name: match string_from_bytes(
+ c_info.qdevice_name.as_ptr(),
+ VOTEQUORUM_QDEVICE_MAX_NAME_LEN,
+ ) {
+ Ok(s) => s,
+ Err(_) => String::new(),
+ },
+ };
+ Ok(info)
+ } else {
+ Err(CsError::from_c(res))
+ }
+}
+
+/// Call any/all active votequorum callbacks for this [Handle]. see [DispatchFlags] for details
+pub fn dispatch(handle: Handle, flags: DispatchFlags) -> Result<()> {
+ let res = unsafe { ffi::votequorum_dispatch(handle.votequorum_handle, flags as u32) };
+ if res == ffi::CS_OK {
+ Ok(())
+ } else {
+ Err(CsError::from_c(res))
+ }
+}
+
+/// Track node and votequorum changes
+pub fn trackstart(handle: Handle, context: u64, flags: TrackFlags) -> Result<()> {
+ let res =
+ unsafe { ffi::votequorum_trackstart(handle.votequorum_handle, context, flags as u32) };
+ if res == ffi::CS_OK {
+ Ok(())
+ } else {
+ Err(CsError::from_c(res))
+ }
+}
+
+/// Stop tracking node and votequorum changes
+pub fn trackstop(handle: Handle) -> Result<()> {
+ let res = unsafe { ffi::votequorum_trackstop(handle.votequorum_handle) };
+ if res == ffi::CS_OK {
+ Ok(())
+ } else {
+ Err(CsError::from_c(res))
+ }
+}
+
+/// Get the current 'context' value for this handle.
+/// The context value is an arbitrary value that is always passed
+/// back to callbacks to help identify the source
+pub fn context_get(handle: Handle) -> Result<u64> {
+ let (res, context) = unsafe {
+ let mut c_context: *mut c_void = &mut 0u64 as *mut _ as *mut c_void;
+ let r = ffi::votequorum_context_get(handle.votequorum_handle, &mut c_context);
+ let context: u64 = c_context as u64;
+ (r, context)
+ };
+ if res == ffi::CS_OK {
+ Ok(context)
+ } else {
+ Err(CsError::from_c(res))
+ }
+}
+
+/// Set the current 'context' value for this handle.
+/// The context value is an arbitrary value that is always passed
+/// back to callbacks to help identify the source.
+/// Normally this is set in [trackstart], but this allows it to be changed
+pub fn context_set(handle: Handle, context: u64) -> Result<()> {
+ let res = unsafe {
+ let c_context = context as *mut c_void;
+ ffi::votequorum_context_set(handle.votequorum_handle, c_context)
+ };
+ if res == ffi::CS_OK {
+ Ok(())
+ } else {
+ Err(CsError::from_c(res))
+ }
+}
+
+/// Set the current expected_votes for the cluster, this value must
+/// be valid and not result in an inquorate cluster.
+pub fn set_expected(handle: Handle, expected_votes: u32) -> Result<()> {
+ let res = unsafe { ffi::votequorum_setexpected(handle.votequorum_handle, expected_votes) };
+ if res == ffi::CS_OK {
+ Ok(())
+ } else {
+ Err(CsError::from_c(res))
+ }
+}
+
+/// Set the current votes for a node
+pub fn set_votes(handle: Handle, nodeid: NodeId, votes: u32) -> Result<()> {
+ let res =
+ unsafe { ffi::votequorum_setvotes(handle.votequorum_handle, u32::from(nodeid), votes) };
+ if res == ffi::CS_OK {
+ Ok(())
+ } else {
+ Err(CsError::from_c(res))
+ }
+}
+
+/// Register a quorum device
+pub fn qdevice_register(handle: Handle, name: &str) -> Result<()> {
+ let c_string = {
+ match CString::new(name) {
+ Ok(cs) => cs,
+ Err(_) => return Err(CsError::CsErrInvalidParam),
+ }
+ };
+
+ let res =
+ unsafe { ffi::votequorum_qdevice_register(handle.votequorum_handle, c_string.as_ptr()) };
+ if res == ffi::CS_OK {
+ Ok(())
+ } else {
+ Err(CsError::from_c(res))
+ }
+}
+
+/// Unregister a quorum device
+pub fn qdevice_unregister(handle: Handle, name: &str) -> Result<()> {
+ let c_string = {
+ match CString::new(name) {
+ Ok(cs) => cs,
+ Err(_) => return Err(CsError::CsErrInvalidParam),
+ }
+ };
+
+ let res =
+ unsafe { ffi::votequorum_qdevice_unregister(handle.votequorum_handle, c_string.as_ptr()) };
+ if res == ffi::CS_OK {
+ Ok(())
+ } else {
+ Err(CsError::from_c(res))
+ }
+}
+
+/// Update the name of a quorum device
+pub fn qdevice_update(handle: Handle, oldname: &str, newname: &str) -> Result<()> {
+ let on_string = {
+ match CString::new(oldname) {
+ Ok(cs) => cs,
+ Err(_) => return Err(CsError::CsErrInvalidParam),
+ }
+ };
+ let nn_string = {
+ match CString::new(newname) {
+ Ok(cs) => cs,
+ Err(_) => return Err(CsError::CsErrInvalidParam),
+ }
+ };
+
+ let res = unsafe {
+ ffi::votequorum_qdevice_update(
+ handle.votequorum_handle,
+ on_string.as_ptr(),
+ nn_string.as_ptr(),
+ )
+ };
+ if res == ffi::CS_OK {
+ Ok(())
+ } else {
+ Err(CsError::from_c(res))
+ }
+}
+
+/// Poll a quorum device
+/// This must be done more often than the qdevice timeout (default 10s) while the device is active
+/// and the [RingId] must match the current value returned from the callbacks for it to be accepted.
+pub fn qdevice_poll(handle: Handle, name: &str, cast_vote: bool, ring_id: &RingId) -> Result<()> {
+ let c_string = {
+ match CString::new(name) {
+ Ok(cs) => cs,
+ Err(_) => return Err(CsError::CsErrInvalidParam),
+ }
+ };
+
+ let c_cast_vote: u32 = u32::from(cast_vote);
+ let c_ring_id = ffi::votequorum_ring_id_t {
+ nodeid: u32::from(ring_id.nodeid),
+ seq: ring_id.seq,
+ };
+
+ let res = unsafe {
+ ffi::votequorum_qdevice_poll(
+ handle.votequorum_handle,
+ c_string.as_ptr(),
+ c_cast_vote,
+ c_ring_id,
+ )
+ };
+ if res == ffi::CS_OK {
+ Ok(())
+ } else {
+ Err(CsError::from_c(res))
+ }
+}
+
+/// Allow qdevice to tell votequorum if master_wins can be enabled or not
+pub fn qdevice_master_wins(handle: Handle, name: &str, master_wins: bool) -> Result<()> {
+ let c_string = {
+ match CString::new(name) {
+ Ok(cs) => cs,
+ Err(_) => return Err(CsError::CsErrInvalidParam),
+ }
+ };
+
+ let c_master_wins: u32 = u32::from(master_wins);
+
+ let res = unsafe {
+ ffi::votequorum_qdevice_master_wins(
+ handle.votequorum_handle,
+ c_string.as_ptr(),
+ c_master_wins,
+ )
+ };
+ if res == ffi::CS_OK {
+ Ok(())
+ } else {
+ Err(CsError::from_c(res))
+ }
+}
diff --git a/bindings/rust/tests/Cargo.toml.in b/bindings/rust/tests/Cargo.toml.in
new file mode 100644
index 0000000..1d8fabf
--- /dev/null
+++ b/bindings/rust/tests/Cargo.toml.in
@@ -0,0 +1,36 @@
+[package]
+name = "rust-corosync-tests"
+version = "@corosyncrustver@"
+authors = ["Christine Caulfield <ccaulfie@redhat.com>"]
+edition = "2021"
+
+[dependencies]
+rust-corosync = { path = ".." }
+
+[build-dependencies]
+pkg-config = "0.3"
+
+[[bin]]
+name = "cpg-test"
+test = false
+bench = false
+
+[[bin]]
+name = "quorum-test"
+test = false
+bench = false
+
+[[bin]]
+name = "votequorum-test"
+test = false
+bench = false
+
+[[bin]]
+name = "cfg-test"
+test = false
+bench = false
+
+[[bin]]
+name = "cmap-test"
+test = false
+bench = false
diff --git a/bindings/rust/tests/Makefile.am b/bindings/rust/tests/Makefile.am
new file mode 100644
index 0000000..a8ac087
--- /dev/null
+++ b/bindings/rust/tests/Makefile.am
@@ -0,0 +1,26 @@
+#
+# Copyright (C) 2022-2023 Red Hat, Inc. All rights reserved.
+#
+# Author: Christine Caulfield <ccaulfie@redhat.com>
+#
+# This software licensed under GPL-2.0+
+#
+
+MAINTAINERCLEANFILES = Makefile.in
+
+include $(top_srcdir)/build-aux/rust.mk
+
+EXTRA_DIST = \
+ $(RUST_COMMON) \
+ $(RUST_SHIP_SRCS)
+
+RUST_SHIP_SRCS = src/bin/cpg-test.rs \
+ src/bin/cfg-test.rs \
+ src/bin/cmap-test.rs \
+ src/bin/quorum-test.rs \
+ src/bin/votequorum-test.rs
+
+# This will build all of the tests
+noinst_SCRIPTS = target/$(RUST_TARGET_DIR)/cpg-test
+
+clean-local: cargo-clean
diff --git a/bindings/rust/tests/Makefile.in b/bindings/rust/tests/Makefile.in
new file mode 100644
index 0000000..36cc52a
--- /dev/null
+++ b/bindings/rust/tests/Makefile.in
@@ -0,0 +1,625 @@
+# Makefile.in generated by automake 1.13.4 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+#
+# Copyright (C) 2022-2023 Red Hat, Inc. All rights reserved.
+#
+# Author: Christine Caulfield <ccaulfie@redhat.com>
+#
+# This software licensed under GPL-2.0+
+#
+
+#
+# Copyright (C) 2021-2022 Red Hat, Inc. All rights reserved.
+#
+# Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+#
+# This software licensed under GPL-2.0+
+#
+
+VPATH = @srcdir@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+DIST_COMMON = $(top_srcdir)/build-aux/rust.mk $(srcdir)/Makefile.in \
+ $(srcdir)/Makefile.am $(srcdir)/Cargo.toml.in
+subdir = bindings/rust/tests
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/lib/libcfg.verso $(top_srcdir)/lib/libcpg.verso \
+ $(top_srcdir)/lib/libquorum.verso \
+ $(top_srcdir)/lib/libsam.verso \
+ $(top_srcdir)/lib/libvotequorum.verso \
+ $(top_srcdir)/lib/libcmap.verso $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/include/corosync/config.h
+CONFIG_CLEAN_FILES = Cargo.toml
+CONFIG_CLEAN_VPATH_FILES =
+SCRIPTS = $(noinst_SCRIPTS)
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+SOURCES =
+DIST_SOURCES =
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALLOCA = @ALLOCA@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUGTOOL = @AUGTOOL@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BASHPATH = @BASHPATH@
+BINDGEN = @BINDGEN@
+CARGO = @CARGO@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFG_SONAME = @CFG_SONAME@
+CFLAGS = @CFLAGS@
+CLIPPY = @CLIPPY@
+CMAP_SONAME = @CMAP_SONAME@
+COROSYSCONFDIR = @COROSYSCONFDIR@
+CPG_SONAME = @CPG_SONAME@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DBUS_CFLAGS = @DBUS_CFLAGS@
+DBUS_LIBS = @DBUS_LIBS@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DOT = @DOT@
+DOXYGEN = @DOXYGEN@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GREP = @GREP@
+GROFF = @GROFF@
+INITCONFIGDIR = @INITCONFIGDIR@
+INITDDIR = @INITDDIR@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBQB_CFLAGS = @LIBQB_CFLAGS@
+LIBQB_LIBS = @LIBQB_LIBS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LINT_FLAGS = @LINT_FLAGS@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LOGDIR = @LOGDIR@
+LOGROTATEDIR = @LOGROTATEDIR@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+QUORUM_SONAME = @QUORUM_SONAME@
+RANLIB = @RANLIB@
+RUSTC = @RUSTC@
+RUSTDOC = @RUSTDOC@
+RUSTFMT = @RUSTFMT@
+RUST_FLAGS = @RUST_FLAGS@
+RUST_TARGET_DIR = @RUST_TARGET_DIR@
+SAM_SONAME = @SAM_SONAME@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SNMPCONFIG = @SNMPCONFIG@
+SNMP_LIBS = @SNMP_LIBS@
+SOMAJOR = @SOMAJOR@
+SOMICRO = @SOMICRO@
+SOMINOR = @SOMINOR@
+SONAME = @SONAME@
+STRIP = @STRIP@
+SYSTEMDDIR = @SYSTEMDDIR@
+VERSCRIPT_LDFLAGS = @VERSCRIPT_LDFLAGS@
+VERSION = @VERSION@
+VOTEQUORUM_SONAME = @VOTEQUORUM_SONAME@
+WITH_LIST = @WITH_LIST@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+corosyncrustver = @corosyncrustver@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+knet_CFLAGS = @knet_CFLAGS@
+knet_LIBS = @knet_LIBS@
+libdir = @libdir@
+libexecdir = @libexecdir@
+libsystemd_CFLAGS = @libsystemd_CFLAGS@
+libsystemd_LIBS = @libsystemd_LIBS@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+nozzle_CFLAGS = @nozzle_CFLAGS@
+nozzle_LIBS = @nozzle_LIBS@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+statgrab_CFLAGS = @statgrab_CFLAGS@
+statgrab_LIBS = @statgrab_LIBS@
+statgrabge090_CFLAGS = @statgrabge090_CFLAGS@
+statgrabge090_LIBS = @statgrabge090_LIBS@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+MAINTAINERCLEANFILES = Makefile.in
+RUST_COMMON = \
+ build.rs.in
+
+RUST_SRCS = $(RUST_SHIP_SRCS) $(RUST_BUILT_SRCS)
+EXTRA_DIST = \
+ $(RUST_COMMON) \
+ $(RUST_SHIP_SRCS)
+
+RUST_SHIP_SRCS = src/bin/cpg-test.rs \
+ src/bin/cfg-test.rs \
+ src/bin/cmap-test.rs \
+ src/bin/quorum-test.rs \
+ src/bin/votequorum-test.rs
+
+
+# This will build all of the tests
+noinst_SCRIPTS = target/$(RUST_TARGET_DIR)/cpg-test
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(top_srcdir)/build-aux/rust.mk $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign bindings/rust/tests/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign bindings/rust/tests/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+$(top_srcdir)/build-aux/rust.mk:
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+Cargo.toml: $(top_builddir)/config.status $(srcdir)/Cargo.toml.in
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+tags TAGS:
+
+ctags CTAGS:
+
+cscope cscopelist:
+
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) check-local
+check: check-am
+all-am: Makefile $(SCRIPTS)
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+ -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-local mostlyclean-am
+
+distclean: distclean-am
+ -rm -f Makefile
+distclean-am: clean-am distclean-generic
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: check-am install-am install-strip
+
+.PHONY: all all-am check check-am check-local clean clean-generic \
+ clean-libtool clean-local cscopelist-am ctags-am distclean \
+ distclean-generic distclean-libtool distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-dvi install-dvi-am install-exec \
+ install-exec-am install-html install-html-am install-info \
+ install-info-am install-man install-pdf install-pdf-am \
+ install-ps install-ps-am install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-generic \
+ mostlyclean-libtool pdf pdf-am ps ps-am tags-am uninstall \
+ uninstall-am
+
+
+%.rlib: $(RUST_SRCS) Cargo.toml build.rs
+ PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) $(CARGO) build $(RUST_FLAGS)
+
+%-test: $(RUST_SRCS) Cargo.toml build.rs
+ PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) $(CARGO) build $(RUST_FLAGS)
+
+build.rs: build.rs.in
+ rm -f $@ $@-t
+ cat $^ | sed \
+ -e 's#@ABSTOPLEVELSRC@#$(abs_top_srcdir)#g' \
+ -e 's#@ABSTOPLEVELBUILD@#$(abs_top_builddir)#g' \
+ -e 's#@LIBQBLIBS@#$(LIBQB_LIBS)#g' \
+ > $@-t
+ chmod a-w $@-t
+ mv $@-t $@
+ rm -f $@-t
+
+cargo-tree-prep:
+ if [ "${abs_builddir}" != "${abs_srcdir}" ]; then \
+ echo "Generating builddir out-of-tree rust symlinks"; \
+ src_realpath=$(shell realpath ${abs_srcdir}); \
+ for i in `find "$$src_realpath/" -type d | \
+ grep -v "${abs_builddir}" | \
+ sed -e 's#^'$$src_realpath'/##g'`; do \
+ $(MKDIR_P) ${abs_builddir}/$${i}; \
+ done; \
+ find "$$src_realpath/" -type f | { while read src; do \
+ process=no; \
+ copy=no; \
+ case $$src in \
+ ${abs_builddir}*) \
+ ;; \
+ *Makefile.*|*.in) \
+ ;; \
+ *) \
+ process=yes; \
+ ;; \
+ esac ; \
+ dst=`echo $$src | sed -e 's#^'$$src_realpath'/##g'`; \
+ if [ $${process} == yes ]; then \
+ rm -f ${abs_builddir}/$$dst; \
+ $(LN_S) $$src ${abs_builddir}/$$dst; \
+ fi; \
+ if [ $${copy} == yes ]; then \
+ rm -f ${abs_builddir}/$$dst; \
+ cp $$src ${abs_builddir}/$$dst; \
+ chmod u+w ${abs_builddir}/$$dst; \
+ fi; \
+ done; }; \
+ fi
+
+cargo-clean:
+ -$(CARGO) clean
+ rm -rf Cargo.lock $(RUST_BUILT_SRCS) build.rs target/
+ if [ "${abs_builddir}" != "${abs_srcdir}" ]; then \
+ echo "Cleaning out-of-tree rust symlinks" ; \
+ find "${abs_builddir}/" -type l -delete; \
+ find "${abs_builddir}/" -type d -empty -delete; \
+ fi
+
+clippy-check:
+ $(CARGO) clippy --verbose --all-features -- -D warnings
+
+format-check:
+ if [ "${abs_builddir}" = "${abs_srcdir}" ]; then \
+ $(CARGO) fmt --all --check; \
+ else \
+ echo "!!!!! WARNING: skipping format check !!!!!"; \
+ fi
+
+doc-check:
+ $(CARGO) doc --verbose --all-features
+
+publish-check:
+ if [ -f "${abs_srcdir}/README.md" ]; then \
+ $(CARGO) publish --dry-run; \
+ fi
+
+crates-publish:
+ if [ -f "${abs_srcdir}/README.md" ]; then \
+ bindingname=`cat Cargo.toml | grep ^name | sed -e 's#.*= ##g' -e 's#"##g'` && \
+ cratesver=`cargo search $$bindingname | grep "^$$bindingname " | sed -e 's#.*= ##g' -e 's#"##g' -e 's/\+.*//g'` && \
+ testver=`echo $(localver) | sed -e 's/\+.*//g'` && \
+ if [ "$$cratesver" != "$$testver" ]; then \
+ $(CARGO) publish; \
+ fi; \
+ fi
+
+crates-check:
+ if [ -f "${abs_srcdir}/README.md" ]; then \
+ bindingname=`cat Cargo.toml | grep ^name | sed -e 's#.*= ##g' -e 's#"##g'` && \
+ cratesver=`cargo search $$bindingname | grep "^$$bindingname " | sed -e 's#.*= ##g' -e 's#"##g' -e 's/\+.*//g'` && \
+ testver=`echo $(localver) | sed -e 's/\+.*//g'` && \
+ if [ "$$cratesver" != "$$testver" ]; then \
+ echo "!!!!! WARNING !!!!!"; \
+ echo "!!!!! WARNING: $$bindingname local version ($$testver) is higher than the current published one on crates.io ($$cratesver)"; \
+ echo "!!!!! WARNING !!!!!"; \
+ fi; \
+ fi
+
+check-local: clippy-check format-check doc-check crates-check publish-check
+
+clean-local: cargo-clean
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/bindings/rust/tests/build.rs.in b/bindings/rust/tests/build.rs.in
new file mode 100644
index 0000000..39a97ba
--- /dev/null
+++ b/bindings/rust/tests/build.rs.in
@@ -0,0 +1,22 @@
+// Copyright (C) 2021-2023 Red Hat, Inc.
+//
+// All rights reserved.
+//
+// Author: Christine Caulfield (ccaulfi@redhat.com)
+//
+
+extern crate pkg_config;
+
+fn main() {
+ // Tell the compiler to use the build-tree libs & headers for compiling
+ println!("cargo:rustc-link-search=native=../../../lib/.libs/");
+ println!("cargo:rustc-link-search=native=../../../common_lib/.libs/");
+ println!("cargo:rustc-flags=@LIBQBLIBS@");
+ println!("cargo:rustc-link-lib=cpg");
+ println!("cargo:rustc-link-lib=cfg");
+ println!("cargo:rustc-link-lib=cmap");
+ println!("cargo:rustc-link-lib=quorum");
+ println!("cargo:rustc-link-lib=votequorum");
+ println!("cargo:rustc-link-lib=corosync_common");
+ println!("cargo:rustc-link-lib=qb");
+}
diff --git a/bindings/rust/tests/src/bin/cfg-test.rs b/bindings/rust/tests/src/bin/cfg-test.rs
new file mode 100644
index 0000000..cd70d38
--- /dev/null
+++ b/bindings/rust/tests/src/bin/cfg-test.rs
@@ -0,0 +1,135 @@
+// Test the CFG library. Requires that corosync is running and that we are root.
+
+extern crate rust_corosync as corosync;
+use corosync::{cfg, NodeId};
+
+use std::thread::spawn;
+
+fn dispatch_thread(handle: cfg::Handle) {
+ loop {
+ if cfg::dispatch(handle, corosync::DispatchFlags::One).is_err() {
+ return;
+ }
+ }
+}
+
+// Test the shutdown callback
+fn shutdown_check_fn(handle: &cfg::Handle, _flags: u32) {
+ println!("in shutdown callback");
+
+ // DON'T shutdown corosync - we're just testing
+ if let Err(e) = cfg::reply_to_shutdown(*handle, cfg::ShutdownReply::No) {
+ println!("Error in CFG replyto_shutdown: {e}");
+ }
+}
+
+fn main() {
+ // Initialise the callbacks data
+ let cb = cfg::Callbacks {
+ corosync_cfg_shutdown_callback_fn: Some(shutdown_check_fn),
+ };
+
+ let handle = match cfg::initialize(&cb) {
+ Ok(h) => {
+ println!("cfg initialized.");
+ h
+ }
+ Err(e) => {
+ println!("Error in CFG init: {e}");
+ return;
+ }
+ };
+
+ // Open two handles to CFG so that the second one can refuse shutdown
+ let handle2 = match cfg::initialize(&cb) {
+ Ok(h) => {
+ println!("cfg2 initialized.");
+ h
+ }
+ Err(e) => {
+ println!("Error in CFG init: {e}");
+ return;
+ }
+ };
+
+ match cfg::track_start(handle2, cfg::TrackFlags::None) {
+ Ok(_) => {
+ // Run handle2 dispatch in its own thread
+ spawn(move || dispatch_thread(handle2));
+ }
+ Err(e) => {
+ println!("Error in CFG track_start: {e}");
+ }
+ };
+
+ let local_nodeid = {
+ match cfg::local_get(handle) {
+ Ok(n) => {
+ println!("Local nodeid is {n}");
+ Some(n)
+ }
+ Err(e) => {
+ println!("Error in CFG local_get: {e}");
+ None
+ }
+ }
+ };
+
+ // Test node_status_get.
+ // node status for the local node looks odd (cos it's the loopback connection), so
+ // we try for a node ID one less or more than us just to get output that looks
+ // sensible to the user.
+ if let Some(our_nodeid) = local_nodeid {
+ let us_plus1 = NodeId::from(u32::from(our_nodeid) + 1);
+ let us_less1 = NodeId::from(u32::from(our_nodeid) - 1);
+ let mut res = cfg::node_status_get(handle, us_plus1, cfg::NodeStatusVersion::V1);
+ if let Err(e) = res {
+ println!("Error from node_status_get on nodeid {us_plus1}: {e}");
+ res = cfg::node_status_get(handle, us_less1, cfg::NodeStatusVersion::V1);
+ };
+ match res {
+ Ok(ns) => {
+ println!("Node Status for nodeid {}", ns.nodeid);
+ println!(" reachable: {}", ns.reachable);
+ println!(" remote: {}", ns.remote);
+ println!(" onwire_min: {}", ns.onwire_min);
+ println!(" onwire_max: {}", ns.onwire_max);
+ println!(" onwire_ver: {}", ns.onwire_ver);
+ for (ls_num, ls) in ns.link_status.iter().enumerate() {
+ if ls.enabled {
+ println!(" Link {ls_num}");
+ println!(" connected: {}", ls.connected);
+ println!(" mtu: {}", ls.mtu);
+ println!(" src: {}", ls.src_ipaddr);
+ println!(" dst: {}", ls.dst_ipaddr);
+ }
+ }
+ }
+ Err(e) => {
+ println!(
+ "Error in CFG node_status get: {e} (tried nodeids {us_plus1} & {us_less1})"
+ );
+ }
+ }
+ }
+
+ // This should not shutdown corosync because the callback on handle2 will refuse it.
+ match cfg::try_shutdown(handle, cfg::ShutdownFlags::Request) {
+ Ok(_) => {
+ println!("CFG try_shutdown suceeded, should return busy");
+ }
+ Err(e) => {
+ if e != corosync::CsError::CsErrBusy {
+ println!("Error in CFG try_shutdown: {e}");
+ }
+ }
+ }
+
+ // Wait for events
+ loop {
+ if cfg::dispatch(handle, corosync::DispatchFlags::One).is_err() {
+ break;
+ }
+ }
+ println!("ERROR: Corosync quit");
+}
diff --git a/bindings/rust/tests/src/bin/cmap-test.rs b/bindings/rust/tests/src/bin/cmap-test.rs
new file mode 100644
index 0000000..f435653
--- /dev/null
+++ b/bindings/rust/tests/src/bin/cmap-test.rs
@@ -0,0 +1,195 @@
+// Test the CMAP library. Requires that corosync is running and that we are root.
+
+extern crate rust_corosync as corosync;
+use corosync::cmap;
+
+fn track_notify_fn(
+ _handle: &cmap::Handle,
+ _track_handle: &cmap::TrackHandle,
+ event: cmap::TrackType,
+ key_name: &str,
+ old_value: &cmap::Data,
+ new_value: &cmap::Data,
+ user_data: u64,
+) {
+ println!("Track notify callback");
+ println!("Key: {key_name}, event: {event}, user_data: {user_data}");
+ println!(" Old value: {old_value}");
+ println!(" New value: {new_value}");
+}
+
+fn main() {
+ let handle = match cmap::initialize(cmap::Map::Icmap) {
+ Ok(h) => {
+ println!("cmap initialized.");
+ h
+ }
+ Err(e) => {
+ println!("Error in CMAP (Icmap) init: {e}");
+ return;
+ }
+ };
+
+ // Test some SETs
+ if let Err(e) = cmap::set_u32(handle, "test.test_uint32", 456) {
+ println!("Error in CMAP set_u32: {e}");
+ return;
+ };
+
+ if let Err(e) = cmap::set_i16(handle, "test.test_int16", -789) {
+ println!("Error in CMAP set_i16: {e}");
+ return;
+ };
+
+ if let Err(e) = cmap::set_number(handle, "test.test_num_1", 6809u32) {
+ println!("Error in CMAP set_number(u32): {e}");
+ return;
+ };
+
+ // NOT PI (just to avoid clippy whingeing)
+ if let Err(e) = cmap::set_number(handle, "test.test_num_2", 3.24159265) {
+ println!("Error in CMAP set_number(f32): {e}");
+ return;
+ };
+
+ if let Err(e) = cmap::set_string(handle, "test.test_string", "Hello from Rust") {
+ println!("Error in CMAP set_string: {e}");
+ return;
+ };
+
+ let test_d = cmap::Data::UInt64(0xdeadbeefbacecafe);
+ if let Err(e) = cmap::set(handle, "test.test_data", &test_d) {
+ println!("Error in CMAP set_data: {e}");
+ return;
+ };
+
+ // let test_d2 = cmap::Data::UInt32(6809);
+ let test_d2 = cmap::Data::String("Test string in data 12345".to_string());
+ if let Err(e) = cmap::set(handle, "test.test_again", &test_d2) {
+ println!("Error in CMAP set_data2: {e}");
+ return;
+ };
+
+ // get them back again
+ match cmap::get(handle, "test.test_uint32") {
+ Ok(v) => {
+ println!("GOT uint32 {v}");
+ }
+
+ Err(e) => {
+ println!("Error in CMAP get: {e}");
+ return;
+ }
+ };
+ match cmap::get(handle, "test.test_int16") {
+ Ok(v) => {
+ println!("GOT uint16 {v}");
+ }
+
+ Err(e) => {
+ println!("Error in CMAP get: {e}");
+ return;
+ }
+ };
+
+ match cmap::get(handle, "test.test_num_1") {
+ Ok(v) => {
+ println!("GOT num {v}");
+ }
+
+ Err(e) => {
+ println!("Error in CMAP get: {e}");
+ return;
+ }
+ };
+ match cmap::get(handle, "test.test_num_2") {
+ Ok(v) => {
+ println!("GOT num {v}");
+ }
+
+ Err(e) => {
+ println!("Error in CMAP get: {e}");
+ return;
+ }
+ };
+ match cmap::get(handle, "test.test_string") {
+ Ok(v) => {
+ println!("GOT string {v}");
+ }
+
+ Err(e) => {
+ println!("Error in CMAP get: {e}");
+ return;
+ }
+ };
+
+ match cmap::get(handle, "test.test_data") {
+ Ok(v) => match v {
+ cmap::Data::UInt64(u) => println!("GOT data value {u:x}"),
+ _ => println!("ERROR type was not UInt64, got {v}"),
+ },
+
+ Err(e) => {
+ println!("Error in CMAP get: {e}");
+ return;
+ }
+ };
+
+ // Test an iterator
+ match cmap::CmapIterStart::new(handle, "totem.") {
+ Ok(cmap_iter) => {
+ for i in cmap_iter {
+ println!("ITER: {i:?}");
+ }
+ println!();
+ }
+ Err(e) => {
+ println!("Error in CMAP iter start: {e}");
+ }
+ }
+
+ // Close this handle
+ if let Err(e) = cmap::finalize(handle) {
+ println!("Error in CMAP get: {e}");
+ return;
+ };
+
+ // Test notifications on the stats map
+ let handle = match cmap::initialize(cmap::Map::Stats) {
+ Ok(h) => h,
+ Err(e) => {
+ println!("Error in CMAP (Stats) init: {e}");
+ return;
+ }
+ };
+
+ let cb = cmap::NotifyCallback {
+ notify_fn: Some(track_notify_fn),
+ };
+ let _track_handle = match cmap::track_add(
+ handle,
+ "stats.srp.memb_merge_detect_tx",
+ cmap::TrackType::MODIFY | cmap::TrackType::ADD | cmap::TrackType::DELETE,
+ &cb,
+ 997u64,
+ ) {
+ Ok(th) => th,
+ Err(e) => {
+ println!("Error in CMAP track_add {e}");
+ return;
+ }
+ };
+
+ // Wait for events
+ let mut event_num = 0;
+ loop {
+ if let Err(e) = cmap::dispatch(handle, corosync::DispatchFlags::One) {
+ println!("Error from CMAP dispatch: {e}");
+ }
+ // Just do 5
+ event_num += 1;
+ if event_num > 5 {
+ break;
+ }
+ }
+}
diff --git a/bindings/rust/tests/src/bin/cpg-test.rs b/bindings/rust/tests/src/bin/cpg-test.rs
new file mode 100644
index 0000000..df83c2d
--- /dev/null
+++ b/bindings/rust/tests/src/bin/cpg-test.rs
@@ -0,0 +1,142 @@
+// Test the CPG library. Requires that corosync is running and that we are root.
+
+extern crate rust_corosync as corosync;
+use corosync::{cpg, NodeId};
+use std::str;
+
+fn deliver_fn(
+ _handle: &cpg::Handle,
+ group_name: String,
+ nodeid: NodeId,
+ pid: u32,
+ msg: &[u8],
+ msg_len: usize,
+) {
+ println!(
+ "TEST deliver_fn called for {group_name}, from nodeid/pid {nodeid}/{pid}. len={msg_len}"
+ );
+
+ // Print as text if it's valid UTF8
+ match str::from_utf8(msg) {
+ Ok(s) => println!(" {s}"),
+ Err(_) => {
+ for i in msg {
+ print!("{i:02x} ");
+ }
+ println!();
+ }
+ }
+}
+
+fn confchg_fn(
+ _handle: &cpg::Handle,
+ group_name: &str,
+ member_list: Vec<cpg::Address>,
+ left_list: Vec<cpg::Address>,
+ joined_list: Vec<cpg::Address>,
+) {
+ println!("TEST confchg_fn called for {group_name}");
+ println!(" members: {member_list:?}");
+ println!(" left: {left_list:?}");
+ println!(" joined: {joined_list:?}");
+}
+
+fn totem_confchg_fn(_handle: &cpg::Handle, ring_id: cpg::RingId, member_list: Vec<NodeId>) {
+ println!(
+ "TEST totem_confchg_fn called for {}/{}",
+ ring_id.nodeid, ring_id.seq
+ );
+ println!(" members: {member_list:?}");
+}
+
+fn main() {
+ // Initialise the model data
+ let md = cpg::ModelData::ModelV1(cpg::Model1Data {
+ flags: cpg::Model1Flags::None,
+ deliver_fn: Some(deliver_fn),
+ confchg_fn: Some(confchg_fn),
+ totem_confchg_fn: Some(totem_confchg_fn),
+ });
+
+ let handle = match cpg::initialize(&md, 99_u64) {
+ Ok(h) => h,
+ Err(e) => {
+ println!("Error in CPG init: {e}");
+ return;
+ }
+ };
+
+ if let Err(e) = cpg::join(handle, "TEST") {
+ println!("Error in CPG join: {e}");
+ return;
+ }
+
+ match cpg::local_get(handle) {
+ Ok(n) => {
+ println!("Local nodeid is {n}");
+ }
+ Err(e) => {
+ println!("Error in CPG local_get: {e}");
+ }
+ }
+
+ // Test membership_get()
+ match cpg::membership_get(handle, "TEST") {
+ Ok(m) => {
+ println!(" members: {m:?}");
+ println!();
+ }
+ Err(e) => {
+ println!("Error in CPG membership_get: {e}");
+ }
+ }
+
+ // Test context APIs
+ let set_context: u64 = 0xabcdbeefcafe;
+ if let Err(e) = cpg::context_set(handle, set_context) {
+ println!("Error in CPG context_set: {e}");
+ return;
+ }
+
+ // NOTE This will fail on 32 bit systems because void* is not u64
+ match cpg::context_get(handle) {
+ Ok(c) => {
+ if c != set_context {
+ println!("Error: context_get() returned {c:x}, context should be {set_context:x}");
+ }
+ }
+ Err(e) => {
+ println!("Error in CPG context_get: {e}");
+ }
+ }
+
+ // Test iterator
+ match cpg::CpgIterStart::new(handle, "", cpg::CpgIterType::All) {
+ Ok(cpg_iter) => {
+ for i in cpg_iter {
+ println!("ITER: {i:?}");
+ }
+ println!();
+ }
+ Err(e) => {
+ println!("Error in CPG iter start: {e}");
+ }
+ }
+
+ // We should receive our own message (at least) in the event loop
+ if let Err(e) = cpg::mcast_joined(
+ handle,
+ cpg::Guarantee::TypeAgreed,
+ &"This is a test".to_string().into_bytes(),
+ ) {
+ println!("Error in CPG mcast_joined: {e}");
+ }
+
+ // Wait for events
+ loop {
+ if cpg::dispatch(handle, corosync::DispatchFlags::One).is_err() {
+ break;
+ }
+ }
+ println!("ERROR: Corosync quit");
+}
diff --git a/bindings/rust/tests/src/bin/quorum-test.rs b/bindings/rust/tests/src/bin/quorum-test.rs
new file mode 100644
index 0000000..5797b7d
--- /dev/null
+++ b/bindings/rust/tests/src/bin/quorum-test.rs
@@ -0,0 +1,83 @@
+// Test the QUORUM library. Requires that corosync is running and that we are root.
+
+extern crate rust_corosync as corosync;
+use corosync::{quorum, NodeId};
+
+fn quorum_fn(
+ _handle: &quorum::Handle,
+ quorate: bool,
+ ring_id: quorum::RingId,
+ member_list: Vec<NodeId>,
+) {
+ println!("TEST quorum_fn called. quorate = {quorate}");
+ println!(" ring_id: {}/{}", ring_id.nodeid, ring_id.seq);
+ println!(" members: {member_list:?}");
+}
+
+fn nodelist_fn(
+ _handle: &quorum::Handle,
+ ring_id: quorum::RingId,
+ member_list: Vec<NodeId>,
+ joined_list: Vec<NodeId>,
+ left_list: Vec<NodeId>,
+) {
+ println!(
+ "TEST nodelist_fn called for {}/{}",
+ ring_id.nodeid, ring_id.seq
+ );
+ println!(" members: {member_list:?}");
+ println!(" joined: {joined_list:?}");
+ println!(" left: {left_list:?}");
+}
+
+fn main() {
+ // Initialise the model data
+ let md = quorum::ModelData::ModelV1(quorum::Model1Data {
+ flags: quorum::Model1Flags::None,
+ quorum_notification_fn: Some(quorum_fn),
+ nodelist_notification_fn: Some(nodelist_fn),
+ });
+
+ let handle = match quorum::initialize(&md, 99_u64) {
+ Ok((h, t)) => {
+ println!("Quorum initialized; type = {}", t as u32);
+ h
+ }
+ Err(e) => {
+ println!("Error in QUORUM init: {e}");
+ return;
+ }
+ };
+
+ // Test context APIs
+ let set_context: u64 = 0xabcdbeefcafe;
+ if let Err(e) = quorum::context_set(handle, set_context) {
+ println!("Error in QUORUM context_set: {e}");
+ return;
+ }
+
+ // NOTE This will fail on 32 bit systems because void* is not u64
+ match quorum::context_get(handle) {
+ Ok(c) => {
+ if c != set_context {
+ println!("Error: context_get() returned {c:x}, context should be {set_context:x}");
+ }
+ }
+ Err(e) => {
+ println!("Error in QUORUM context_get: {e}");
+ }
+ }
+
+ if let Err(e) = quorum::trackstart(handle, corosync::TrackFlags::Changes) {
+ println!("Error in QUORUM trackstart: {e}");
+ return;
+ }
+
+ // Wait for events
+ loop {
+ if quorum::dispatch(handle, corosync::DispatchFlags::One).is_err() {
+ break;
+ }
+ }
+ println!("ERROR: Corosync quit");
+}
diff --git a/bindings/rust/tests/src/bin/votequorum-test.rs b/bindings/rust/tests/src/bin/votequorum-test.rs
new file mode 100644
index 0000000..cf9746b
--- /dev/null
+++ b/bindings/rust/tests/src/bin/votequorum-test.rs
@@ -0,0 +1,117 @@
+// Test the VOTEQUORUM library. Requires that corosync is running and that we are root.
+
+extern crate rust_corosync as corosync;
+use corosync::votequorum;
+
+fn quorum_fn(
+ _handle: &votequorum::Handle,
+ _context: u64,
+ quorate: bool,
+ member_list: Vec<votequorum::Node>,
+) {
+ println!("TEST votequorum_quorum_fn called. quorate = {quorate}");
+ println!(" members: {member_list:?}");
+}
+
+fn nodelist_fn(
+ _handle: &votequorum::Handle,
+ _context: u64,
+ ring_id: votequorum::RingId,
+ member_list: Vec<corosync::NodeId>,
+) {
+ println!(
+ "TEST nodelist_fn called for {}/{}",
+ ring_id.nodeid, ring_id.seq
+ );
+ println!(" members: {member_list:?}");
+}
+
+fn expectedvotes_fn(_handle: &votequorum::Handle, _context: u64, expected_votes: u32) {
+ println!("TEST expected_votes_fn called: value is {expected_votes}");
+}
+
+fn main() {
+ // Initialise the model data
+ let cb = votequorum::Callbacks {
+ quorum_notification_fn: Some(quorum_fn),
+ nodelist_notification_fn: Some(nodelist_fn),
+ expectedvotes_notification_fn: Some(expectedvotes_fn),
+ };
+
+ let handle = match votequorum::initialize(&cb) {
+ Ok(h) => {
+ println!("Votequorum initialized.");
+ h
+ }
+ Err(e) => {
+ println!("Error in VOTEQUORUM init: {e}");
+ return;
+ }
+ };
+
+ // Test context APIs
+ let set_context: u64 = 0xabcdbeefcafe;
+ if let Err(e) = votequorum::context_set(handle, set_context) {
+ println!("Error in VOTEQUORUM context_set: {e}");
+ }
+
+ // NOTE This will fail on 32 bit systems because void* is not u64
+ match votequorum::context_get(handle) {
+ Ok(c) => {
+ if c != set_context {
+ println!("Error: context_get() returned {c:x}, context should be {set_context:x}");
+ }
+ }
+ Err(e) => {
+ println!("Error in VOTEQUORUM context_get: {e}");
+ }
+ }
+
+ const QDEVICE_NAME: &str = "RustQdevice";
+
+ if let Err(e) = votequorum::qdevice_register(handle, QDEVICE_NAME) {
+ println!("Error in VOTEQUORUM qdevice_register: {e}");
+ }
+
+ match votequorum::get_info(handle, corosync::NodeId::from(1u32)) {
+ Ok(i) => {
+ println!("Node info for nodeid 1");
+ println!(" nodeid: {}", i.node_id);
+ println!(" node_state: {:?}", i.node_state);
+ println!(" node_votes: {}", i.node_votes);
+ println!(" node_expected: {}", i.node_expected_votes);
+ println!(" highest_expected: {}", i.highest_expected);
+ println!(" quorum: {}", i.quorum);
+ println!(" flags: {:x}", i.flags);
+ println!(" qdevice_votes: {}", i.qdevice_votes);
+ println!(" qdevice_name: {}", i.qdevice_name);
+
+ if i.qdevice_name != QDEVICE_NAME {
+ println!(
+ "qdevice names do not match: s/b: \"{}\" is: \"{}\"",
+ QDEVICE_NAME, i.qdevice_name
+ );
+ }
+ }
+ Err(e) => {
+ println!("Error in VOTEQUORUM get_info: {e} (check nodeid 1 has been online)");
+ }
+ }
+
+ if let Err(e) = votequorum::qdevice_unregister(handle, QDEVICE_NAME) {
+ println!("Error in VOTEQUORUM qdevice_unregister: {e}");
+ }
+
+ if let Err(e) = votequorum::trackstart(handle, 99_u64, corosync::TrackFlags::Changes) {
+ println!("Error in VOTEQUORUM trackstart: {e}");
+ return;
+ }
+
+ // Wait for events
+ loop {
+ if votequorum::dispatch(handle, corosync::DispatchFlags::One).is_err() {
+ break;
+ }
+ }
+ println!("ERROR: Corosync quit");
+}
diff --git a/build-aux/git-version-gen b/build-aux/git-version-gen
new file mode 100755
index 0000000..ff0c534
--- /dev/null
+++ b/build-aux/git-version-gen
@@ -0,0 +1,265 @@
+#!/bin/sh
+# Print a version string.
+scriptversion=2018-08-31.20; # UTC
+
+# Copyright (C) 2012-2020 Red Hat, Inc.
+# Copyright (C) 2007-2016 Free Software Foundation, Inc.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 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, see <http://www.gnu.org/licenses/>.
+
+# This script is derived from GIT-VERSION-GEN from GIT: http://git.or.cz/.
+# It may be run two ways:
+# - from a git repository in which the "git describe" command below
+# produces useful output (thus requiring at least one signed tag)
+# - from a non-git-repo directory containing a .tarball-version file, which
+# presumes this script is invoked like "./git-version-gen .tarball-version".
+
+# In order to use intra-version strings in your project, you will need two
+# separate generated version string files:
+#
+# .tarball-version - present only in a distribution tarball, and not in
+# a checked-out repository. Created with contents that were learned at
+# the last time autoconf was run, and used by git-version-gen. Must not
+# be present in either $(srcdir) or $(builddir) for git-version-gen to
+# give accurate answers during normal development with a checked out tree,
+# but must be present in a tarball when there is no version control system.
+# Therefore, it cannot be used in any dependencies. GNUmakefile has
+# hooks to force a reconfigure at distribution time to get the value
+# correct, without penalizing normal development with extra reconfigures.
+#
+# .version - present in a checked-out repository and in a distribution
+# tarball. Usable in dependencies, particularly for files that don't
+# want to depend on config.h but do want to track version changes.
+# Delete this file prior to any autoconf run where you want to rebuild
+# files to pick up a version string change; and leave it stale to
+# minimize rebuild time after unrelated changes to configure sources.
+#
+# As with any generated file in a VC'd directory, you should add
+# /.version to .gitignore, so that you don't accidentally commit it.
+# .tarball-version is never generated in a VC'd directory, so needn't
+# be listed there.
+#
+# In order to use git archive versions another two files has to be presented:
+#
+# .gitarchive-version - present in checked-out repository and git
+# archive tarball, but not in the distribution tarball. Used as a last
+# option for version. File must contain special string $Format:%d$,
+# which is substitued by git on archive operation.
+#
+# .gitattributes - present in checked-out repository and git archive
+# tarball, but not in the distribution tarball. Must set export-subst
+# attribute for .gitarchive-version file.
+#
+# Use the following line in your configure.ac, so that $(VERSION) will
+# automatically be up-to-date each time configure is run (and note that
+# since configure.ac no longer includes a version string, Makefile rules
+# should not depend on configure.ac for version updates).
+#
+# AC_INIT([GNU project],
+# m4_esyscmd([build-aux/git-version-gen .tarball-version]),
+# [bug-project@example])
+#
+# Then use the following lines in your Makefile.am, so that .version
+# will be present for dependencies, and so that .version and
+# .tarball-version will exist in distribution tarballs.
+#
+# EXTRA_DIST = $(top_srcdir)/.version
+# BUILT_SOURCES = $(top_srcdir)/.version
+# $(top_srcdir)/.version:
+# echo $(VERSION) > $@-t && mv $@-t $@
+# dist-hook:
+# echo $(VERSION) > $(distdir)/.tarball-version
+
+
+me=$0
+
+version="git-version-gen $scriptversion
+
+Copyright 2011 Free Software Foundation, Inc.
+There is NO warranty. You may redistribute this software
+under the terms of the GNU General Public License.
+For more information about these matters, see the files named COPYING."
+
+usage="\
+Usage: $me [OPTION]... \$srcdir/.tarball-version [\$srcdir/.gitarchive-version] [TAG-NORMALIZATION-SED-SCRIPT]
+Print a version string.
+
+Options:
+
+ --prefix PREFIX prefix of git tags (default 'v')
+ --fallback VERSION
+ fallback version to use if \"git --version\" fails
+
+ --help display this help and exit
+ --version output version information and exit
+
+Running without arguments will suffice in most cases."
+
+prefix=v
+fallback=
+
+while test $# -gt 0; do
+ case $1 in
+ --help) echo "$usage"; exit 0;;
+ --version) echo "$version"; exit 0;;
+ --prefix) shift; prefix="$1";;
+ --fallback) shift; fallback="$1";;
+ -*)
+ echo "$0: Unknown option '$1'." >&2
+ echo "$0: Try '--help' for more information." >&2
+ exit 1;;
+ *)
+ if test "x$tarball_version_file" = x; then
+ tarball_version_file="$1"
+ elif test "x$gitarchive_version_file" = x; then
+ gitarchive_version_file="$1"
+ elif test "x$tag_sed_script" = x; then
+ tag_sed_script="$1"
+ else
+ echo "$0: extra non-option argument '$1'." >&2
+ exit 1
+ fi;;
+ esac
+ shift
+done
+
+if test "x$tarball_version_file" = x; then
+ echo "$usage"
+ exit 1
+fi
+
+tag_sed_script="${tag_sed_script:-s/x/x/}"
+
+nl='
+'
+
+# Avoid meddling by environment variable of the same name.
+v=
+v_from_git=
+
+# First see if there is a tarball-only version file.
+# then try "git describe", then default.
+if test -f $tarball_version_file
+then
+ v=`cat $tarball_version_file` || v=
+ case $v in
+ *$nl*) v= ;; # reject multi-line output
+ [0-9]*) ;;
+ *) v= ;;
+ esac
+ test "x$v" = x \
+ && echo "$0: WARNING: $tarball_version_file is missing or damaged" 1>&2
+fi
+
+if test "x$v" != x
+then
+ : # use $v
+# Otherwise, if there is at least one git commit involving the working
+# directory, and "git describe" output looks sensible, use that to
+# derive a version string.
+elif test "`git log -1 --pretty=format:x . 2>&1`" = x \
+ && v=`git describe --abbrev=4 --match="$prefix*" HEAD 2>/dev/null \
+ || git describe --abbrev=4 HEAD 2>/dev/null` \
+ && v=`printf '%s\n' "$v" | sed "$tag_sed_script"` \
+ && case $v in
+ $prefix[0-9]*) ;;
+ *) (exit 1) ;;
+ esac
+then
+ # Is this a new git that lists number of commits since the last
+ # tag or the previous older version that did not?
+ # Newer: v6.10-77-g0f8faeb
+ # Older: v6.10-g0f8faeb
+ case $v in
+ *-*-*) : git describe is okay three part flavor ;;
+ *-*)
+ : git describe is older two part flavor
+ # Recreate the number of commits and rewrite such that the
+ # result is the same as if we were using the newer version
+ # of git describe.
+ vtag=`echo "$v" | sed 's/-.*//'`
+ commit_list=`git rev-list "$vtag"..HEAD 2>/dev/null` \
+ || { commit_list=failed;
+ echo "$0: WARNING: git rev-list failed" 1>&2; }
+ numcommits=`echo "$commit_list" | wc -l`
+ v=`echo "$v" | sed "s/\(.*\)-\(.*\)/\1-$numcommits-\2/"`;
+ test "$commit_list" = failed && v=UNKNOWN
+ ;;
+ esac
+
+ # Change the first '-' to a '.', so version-comparing tools work properly.
+ # Remove the "g" in git describe's output string, to save a byte.
+ v=`echo "$v" | sed 's/-/./;s/\(.*\)-g/\1-/'`;
+ v_from_git=1
+elif test "x$fallback" = x || git --version >/dev/null 2>&1; then
+ if test -f $gitarchive_version_file
+ then
+ v=`sed "s/^.*tag: \($prefix[0-9)][^,)]*\).*\$/\1/" $gitarchive_version_file \
+ | sed "$tag_sed_script"` || exit 1
+ case $v in
+ *$nl*) v= ;; # reject multi-line output
+ $prefix[0-9]*) ;;
+ *) v= ;;
+ esac
+
+ test -z "$v" \
+ && echo "$0: WARNING: $gitarchive_version_file doesn't contain valid version tag" 1>&2 \
+ && v=UNKNOWN
+ elif test "x$fallback" = x; then
+ v=UNKNOWN
+ else
+ v=$fallback
+ fi
+else
+ v=$fallback
+fi
+
+if test "x$fallback" = x -a "$v" = "UNKNOWN"
+then
+ echo "$0: ERROR: Can't find valid version. Please use valid git repository," \
+ "released tarball or version tagged archive" 1>&2
+
+ exit 1
+fi
+
+v=`echo "$v" |sed "s/^$prefix//"`
+
+# Test whether to append the "-dirty" suffix only if the version
+# string we're using came from git. I.e., skip the test if it's "UNKNOWN"
+# or if it came from .tarball-version.
+if test "x$v_from_git" != x; then
+ # Don't declare a version "dirty" merely because a time stamp has changed.
+ git update-index --refresh > /dev/null 2>&1
+
+ dirty=`exec 2>/dev/null;git diff-index --name-only HEAD` || dirty=
+ case "$dirty" in
+ '') ;;
+ *) # Append the suffix only if there isn't one already.
+ case $v in
+ *-dirty) ;;
+ *) v="$v-dirty" ;;
+ esac ;;
+ esac
+fi
+
+# Omit the trailing newline, so that m4_esyscmd can use the result directly.
+printf %s "$v"
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC0"
+# time-stamp-end: "; # UTC"
+# End:
diff --git a/build-aux/gitlog-to-changelog b/build-aux/gitlog-to-changelog
new file mode 100755
index 0000000..7660af5
--- /dev/null
+++ b/build-aux/gitlog-to-changelog
@@ -0,0 +1,191 @@
+eval '(exit $?0)' && eval 'exec perl -wS "$0" ${1+"$@"}'
+ & eval 'exec perl -wS "$0" $argv:q'
+ if 0;
+# Convert git log output to ChangeLog format.
+
+my $VERSION = '2009-10-30 13:46'; # UTC
+# The definition above must lie within the first 8 lines in order
+# for the Emacs time-stamp write hook (at end) to update it.
+# If you change this file with Emacs, please let the write hook
+# do its job. Otherwise, update this string manually.
+
+# Copyright (C) 2008-2010 Free Software Foundation, Inc.
+
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 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, see <http://www.gnu.org/licenses/>.
+
+# Written by Jim Meyering
+
+use strict;
+use warnings;
+use Getopt::Long;
+use POSIX qw(strftime);
+
+(my $ME = $0) =~ s|.*/||;
+
+# use File::Coda; # http://meyering.net/code/Coda/
+END {
+ defined fileno STDOUT or return;
+ close STDOUT and return;
+ warn "$ME: failed to close standard output: $!\n";
+ $? ||= 1;
+}
+
+sub usage ($)
+{
+ my ($exit_code) = @_;
+ my $STREAM = ($exit_code == 0 ? *STDOUT : *STDERR);
+ if ($exit_code != 0)
+ {
+ print $STREAM "Try `$ME --help' for more information.\n";
+ }
+ else
+ {
+ print $STREAM <<EOF;
+Usage: $ME [OPTIONS] [ARGS]
+
+Convert git log output to ChangeLog format. If present, any ARGS
+are passed to "git log". To avoid ARGS being parsed as options to
+$ME, they may be preceded by '--'.
+
+OPTIONS:
+
+ --since=DATE convert only the logs since DATE;
+ the default is to convert all log entries.
+ --format=FMT set format string for commit subject and body;
+ see 'man git-log' for the list of format metacharacters;
+ the default is '%s%n%b%n'
+
+ --help display this help and exit
+ --version output version information and exit
+
+EXAMPLE:
+
+ $ME --since=2008-01-01 > ChangeLog
+ $ME -- -n 5 foo > last-5-commits-to-branch-foo
+
+EOF
+ }
+ exit $exit_code;
+}
+
+# If the string $S is a well-behaved file name, simply return it.
+# If it contains white space, quotes, etc., quote it, and return the new string.
+sub shell_quote($)
+{
+ my ($s) = @_;
+ if ($s =~ m![^\w+/.,-]!)
+ {
+ # Convert each single quote to '\''
+ $s =~ s/\'/\'\\\'\'/g;
+ # Then single quote the string.
+ $s = "'$s'";
+ }
+ return $s;
+}
+
+sub quoted_cmd(@)
+{
+ return join (' ', map {shell_quote $_} @_);
+}
+
+{
+ my $since_date = '1970-01-01 UTC';
+ my $format_string = '%s%n%b%n';
+ GetOptions
+ (
+ help => sub { usage 0 },
+ version => sub { print "$ME version $VERSION\n"; exit },
+ 'since=s' => \$since_date,
+ 'format=s' => \$format_string,
+ ) or usage 1;
+
+ my @cmd = (qw (git log --log-size), "--since=$since_date",
+ '--pretty=format:%ct %an <%ae>%n%n'.$format_string, @ARGV);
+ open PIPE, '-|', @cmd
+ or die ("$ME: failed to run `". quoted_cmd (@cmd) ."': $!\n"
+ . "(Is your Git too old? Version 1.5.1 or later is required.)\n");
+
+ my $prev_date_line = '';
+ while (1)
+ {
+ defined (my $in = <PIPE>)
+ or last;
+ $in =~ /^log size (\d+)$/
+ or die "$ME:$.: Invalid line (expected log size):\n$in";
+ my $log_nbytes = $1;
+
+ my $log;
+ my $n_read = read PIPE, $log, $log_nbytes;
+ $n_read == $log_nbytes
+ or die "$ME:$.: unexpected EOF\n";
+
+ my @line = split "\n", $log;
+ my $author_line = shift @line;
+ defined $author_line
+ or die "$ME:$.: unexpected EOF\n";
+ $author_line =~ /^(\d+) (.*>)$/
+ or die "$ME:$.: Invalid line "
+ . "(expected date/author/email):\n$author_line\n";
+
+ my $date_line = sprintf "%s $2\n", strftime ("%F", localtime ($1));
+ # If this line would be the same as the previous date/name/email
+ # line, then arrange not to print it.
+ if ($date_line ne $prev_date_line)
+ {
+ $prev_date_line eq ''
+ or print "\n";
+ print $date_line;
+ }
+ $prev_date_line = $date_line;
+
+ # Omit "Signed-off-by..." lines.
+ @line = grep !/^Signed-off-by: .*>$/, @line;
+
+ # If there were any lines
+ if (@line == 0)
+ {
+ warn "$ME: warning: empty commit message:\n $date_line\n";
+ }
+ else
+ {
+ # Remove leading and trailing blank lines.
+ while ($line[0] =~ /^\s*$/) { shift @line; }
+ while ($line[$#line] =~ /^\s*$/) { pop @line; }
+
+ # Prefix each non-empty line with a TAB.
+ @line = map { length $_ ? "\t$_" : '' } @line;
+
+ print "\n", join ("\n", @line), "\n";
+ }
+
+ defined ($in = <PIPE>)
+ or last;
+ $in ne "\n"
+ and die "$ME:$.: unexpected line:\n$in";
+ }
+
+ close PIPE
+ or die "$ME: error closing pipe from " . quoted_cmd (@cmd) . "\n";
+ # FIXME-someday: include $PROCESS_STATUS in the diagnostic
+}
+
+# Local Variables:
+# mode: perl
+# indent-tabs-mode: nil
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "my $VERSION = '"
+# time-stamp-format: "%:y-%02m-%02d %02H:%02M"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "'; # UTC"
+# End:
diff --git a/build-aux/release.mk b/build-aux/release.mk
new file mode 100644
index 0000000..6837d8d
--- /dev/null
+++ b/build-aux/release.mk
@@ -0,0 +1,75 @@
+# to build official release tarballs, handle tagging and publish.
+
+# signing key
+gpgsignkey=
+
+project=corosync
+
+all: checks setup tag tarballs sha256 sign
+
+checks:
+ifeq (,$(version))
+ @echo ERROR: need to define version=
+ @exit 1
+endif
+ @if [ ! -d .git ]; then \
+ echo This script needs to be executed from top level cluster git tree; \
+ exit 1; \
+ fi
+
+setup: checks
+ ./autogen.sh
+ ./configure
+ make maintainer-clean
+
+tag: setup ./tag-$(version)
+
+tag-$(version):
+ifeq (,$(release))
+ @echo Building test release $(version), no tagging
+else
+ git tag -a -m "v$(version) release" v$(version) HEAD
+ @touch $@
+endif
+
+tarballs: tag
+ ./autogen.sh
+ ./configure
+ make distcheck
+
+sha256: tarballs $(project)-$(version).sha256
+
+$(project)-$(version).sha256:
+ifeq (,$(release))
+ @echo Building test release $(version), no sha256
+else
+ sha256sum $(project)-$(version)*tar* | sort -k2 > $@
+endif
+
+sign: sha256 $(project)-$(version).sha256.asc
+
+$(project)-$(version).sha256.asc: $(project)-$(version).sha256
+ifeq (,$(gpgsignkey))
+ @echo No GPG signing key defined
+else
+ifeq (,$(release))
+ @echo Building test release $(version), no sign
+else
+ gpg --default-key $(gpgsignkey) \
+ --detach-sign \
+ --armor \
+ $<
+endif
+endif
+
+publish:
+ifeq (,$(release))
+ @echo Building test release $(version), no publishing!
+else
+ @echo CHANGEME git push --tags origin
+ @echo CHANGEME scp $(project)-$(version).* \
+ fedorahosted.org:$(project)
+endif
+
+clean:
+ rm -rf $(project)-* tag-*
diff --git a/build-aux/rust-regen.sh b/build-aux/rust-regen.sh
new file mode 100755
index 0000000..9508199
--- /dev/null
+++ b/build-aux/rust-regen.sh
@@ -0,0 +1,28 @@
+#!/bin/sh
+#
+# Copyright (C) 2021-2023 Red Hat, Inc. All rights reserved.
+#
+# Authors: Christine Caulfield <ccaulfie@redhat.com>
+# Fabio M. Di Nitto <fabbione@kronosnet.org>
+#
+# This software licensed under GPL-2.0+
+#
+#
+# Regerate the FFI bindings in src/sys from the current headers
+#
+
+srcheader="$1"
+dstrs="$2"
+filter="$3"
+shift; shift; shift
+
+bindgen \
+ --no-prepend-enum-name \
+ --no-layout-tests \
+ --no-doc-comments \
+ --generate functions,types \
+ --fit-macro-constant-types \
+ --allowlist-var=$filter.* \
+ --allowlist-type=.* \
+ --allowlist-function=.* \
+ $srcheader -o $dstrs "$@"
diff --git a/build-aux/rust.mk b/build-aux/rust.mk
new file mode 100644
index 0000000..00beb1f
--- /dev/null
+++ b/build-aux/rust.mk
@@ -0,0 +1,114 @@
+#
+# Copyright (C) 2021-2022 Red Hat, Inc. All rights reserved.
+#
+# Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+#
+# This software licensed under GPL-2.0+
+#
+
+RUST_COMMON = \
+ build.rs.in
+
+RUST_SRCS = $(RUST_SHIP_SRCS) $(RUST_BUILT_SRCS)
+
+%.rlib: $(RUST_SRCS) Cargo.toml build.rs
+ PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) $(CARGO) build $(RUST_FLAGS)
+
+%-test: $(RUST_SRCS) Cargo.toml build.rs
+ PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) $(CARGO) build $(RUST_FLAGS)
+
+build.rs: build.rs.in
+ rm -f $@ $@-t
+ cat $^ | sed \
+ -e 's#@ABSTOPLEVELSRC@#$(abs_top_srcdir)#g' \
+ -e 's#@ABSTOPLEVELBUILD@#$(abs_top_builddir)#g' \
+ -e 's#@LIBQBLIBS@#$(LIBQB_LIBS)#g' \
+ > $@-t
+ chmod a-w $@-t
+ mv $@-t $@
+ rm -f $@-t
+
+cargo-tree-prep:
+ if [ "${abs_builddir}" != "${abs_srcdir}" ]; then \
+ echo "Generating builddir out-of-tree rust symlinks"; \
+ src_realpath=$(shell realpath ${abs_srcdir}); \
+ for i in `find "$$src_realpath/" -type d | \
+ grep -v "${abs_builddir}" | \
+ sed -e 's#^'$$src_realpath'/##g'`; do \
+ $(MKDIR_P) ${abs_builddir}/$${i}; \
+ done; \
+ find "$$src_realpath/" -type f | { while read src; do \
+ process=no; \
+ copy=no; \
+ case $$src in \
+ ${abs_builddir}*) \
+ ;; \
+ *Makefile.*|*.in) \
+ ;; \
+ *) \
+ process=yes; \
+ ;; \
+ esac ; \
+ dst=`echo $$src | sed -e 's#^'$$src_realpath'/##g'`; \
+ if [ $${process} == yes ]; then \
+ rm -f ${abs_builddir}/$$dst; \
+ $(LN_S) $$src ${abs_builddir}/$$dst; \
+ fi; \
+ if [ $${copy} == yes ]; then \
+ rm -f ${abs_builddir}/$$dst; \
+ cp $$src ${abs_builddir}/$$dst; \
+ chmod u+w ${abs_builddir}/$$dst; \
+ fi; \
+ done; }; \
+ fi
+
+cargo-clean:
+ -$(CARGO) clean
+ rm -rf Cargo.lock $(RUST_BUILT_SRCS) build.rs target/
+ if [ "${abs_builddir}" != "${abs_srcdir}" ]; then \
+ echo "Cleaning out-of-tree rust symlinks" ; \
+ find "${abs_builddir}/" -type l -delete; \
+ find "${abs_builddir}/" -type d -empty -delete; \
+ fi
+
+clippy-check:
+ $(CARGO) clippy --verbose --all-features -- -D warnings
+
+format-check:
+ if [ "${abs_builddir}" = "${abs_srcdir}" ]; then \
+ $(CARGO) fmt --all --check; \
+ else \
+ echo "!!!!! WARNING: skipping format check !!!!!"; \
+ fi
+
+doc-check:
+ $(CARGO) doc --verbose --all-features
+
+publish-check:
+ if [ -f "${abs_srcdir}/README.md" ]; then \
+ $(CARGO) publish --dry-run; \
+ fi
+
+crates-publish:
+ if [ -f "${abs_srcdir}/README.md" ]; then \
+ bindingname=`cat Cargo.toml | grep ^name | sed -e 's#.*= ##g' -e 's#"##g'` && \
+ cratesver=`cargo search $$bindingname | grep "^$$bindingname " | sed -e 's#.*= ##g' -e 's#"##g' -e 's/\+.*//g'` && \
+ testver=`echo $(localver) | sed -e 's/\+.*//g'` && \
+ if [ "$$cratesver" != "$$testver" ]; then \
+ $(CARGO) publish; \
+ fi; \
+ fi
+
+crates-check:
+ if [ -f "${abs_srcdir}/README.md" ]; then \
+ bindingname=`cat Cargo.toml | grep ^name | sed -e 's#.*= ##g' -e 's#"##g'` && \
+ cratesver=`cargo search $$bindingname | grep "^$$bindingname " | sed -e 's#.*= ##g' -e 's#"##g' -e 's/\+.*//g'` && \
+ testver=`echo $(localver) | sed -e 's/\+.*//g'` && \
+ if [ "$$cratesver" != "$$testver" ]; then \
+ echo "!!!!! WARNING !!!!!"; \
+ echo "!!!!! WARNING: $$bindingname local version ($$testver) is higher than the current published one on crates.io ($$cratesver)"; \
+ echo "!!!!! WARNING !!!!!"; \
+ fi; \
+ fi
+
+check-local: clippy-check format-check doc-check crates-check publish-check
diff --git a/common_lib/Makefile.am b/common_lib/Makefile.am
new file mode 100644
index 0000000..7045c3c
--- /dev/null
+++ b/common_lib/Makefile.am
@@ -0,0 +1,38 @@
+#
+# Copyright (c) 2012 Red Hat, Inc.
+#
+# Authors: Angus Salkeld
+#
+# This software licensed under BSD license, the text of which follows:
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# - Redistributions of source code must retain the above copyright notice,
+# this list of conditions and the following disclaimer.
+# - Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+# - Neither the name of the MontaVista Software, Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from this
+# software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+# THE POSSIBILITY OF SUCH DAMAGE.
+
+MAINTAINERCLEANFILES = Makefile.in
+
+lib_LTLIBRARIES = libcorosync_common.la
+
+libcorosync_common_la_SOURCES = error_conversion.c
+
+libcorosync_common_la_LDFLAGS = -version-number 4:0:0
diff --git a/common_lib/Makefile.in b/common_lib/Makefile.in
new file mode 100644
index 0000000..be3cceb
--- /dev/null
+++ b/common_lib/Makefile.in
@@ -0,0 +1,720 @@
+# Makefile.in generated by automake 1.13.4 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+#
+# Copyright (c) 2012 Red Hat, Inc.
+#
+# Authors: Angus Salkeld
+#
+# This software licensed under BSD license, the text of which follows:
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# - Redistributions of source code must retain the above copyright notice,
+# this list of conditions and the following disclaimer.
+# - Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+# - Neither the name of the MontaVista Software, Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from this
+# software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+# THE POSSIBILITY OF SUCH DAMAGE.
+
+VPATH = @srcdir@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = common_lib
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+ $(top_srcdir)/depcomp
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/lib/libcfg.verso $(top_srcdir)/lib/libcpg.verso \
+ $(top_srcdir)/lib/libquorum.verso \
+ $(top_srcdir)/lib/libsam.verso \
+ $(top_srcdir)/lib/libvotequorum.verso \
+ $(top_srcdir)/lib/libcmap.verso $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/include/corosync/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+am__installdirs = "$(DESTDIR)$(libdir)"
+LTLIBRARIES = $(lib_LTLIBRARIES)
+libcorosync_common_la_LIBADD =
+am_libcorosync_common_la_OBJECTS = error_conversion.lo
+libcorosync_common_la_OBJECTS = $(am_libcorosync_common_la_OBJECTS)
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 =
+libcorosync_common_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(AM_CFLAGS) $(CFLAGS) $(libcorosync_common_la_LDFLAGS) \
+ $(LDFLAGS) -o $@
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/corosync
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo " CC " $@;
+am__v_CC_1 =
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo " CCLD " $@;
+am__v_CCLD_1 =
+SOURCES = $(libcorosync_common_la_SOURCES)
+DIST_SOURCES = $(libcorosync_common_la_SOURCES)
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALLOCA = @ALLOCA@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUGTOOL = @AUGTOOL@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BASHPATH = @BASHPATH@
+BINDGEN = @BINDGEN@
+CARGO = @CARGO@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFG_SONAME = @CFG_SONAME@
+CFLAGS = @CFLAGS@
+CLIPPY = @CLIPPY@
+CMAP_SONAME = @CMAP_SONAME@
+COROSYSCONFDIR = @COROSYSCONFDIR@
+CPG_SONAME = @CPG_SONAME@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DBUS_CFLAGS = @DBUS_CFLAGS@
+DBUS_LIBS = @DBUS_LIBS@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DOT = @DOT@
+DOXYGEN = @DOXYGEN@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GREP = @GREP@
+GROFF = @GROFF@
+INITCONFIGDIR = @INITCONFIGDIR@
+INITDDIR = @INITDDIR@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBQB_CFLAGS = @LIBQB_CFLAGS@
+LIBQB_LIBS = @LIBQB_LIBS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LINT_FLAGS = @LINT_FLAGS@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LOGDIR = @LOGDIR@
+LOGROTATEDIR = @LOGROTATEDIR@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+QUORUM_SONAME = @QUORUM_SONAME@
+RANLIB = @RANLIB@
+RUSTC = @RUSTC@
+RUSTDOC = @RUSTDOC@
+RUSTFMT = @RUSTFMT@
+RUST_FLAGS = @RUST_FLAGS@
+RUST_TARGET_DIR = @RUST_TARGET_DIR@
+SAM_SONAME = @SAM_SONAME@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SNMPCONFIG = @SNMPCONFIG@
+SNMP_LIBS = @SNMP_LIBS@
+SOMAJOR = @SOMAJOR@
+SOMICRO = @SOMICRO@
+SOMINOR = @SOMINOR@
+SONAME = @SONAME@
+STRIP = @STRIP@
+SYSTEMDDIR = @SYSTEMDDIR@
+VERSCRIPT_LDFLAGS = @VERSCRIPT_LDFLAGS@
+VERSION = @VERSION@
+VOTEQUORUM_SONAME = @VOTEQUORUM_SONAME@
+WITH_LIST = @WITH_LIST@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+corosyncrustver = @corosyncrustver@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+knet_CFLAGS = @knet_CFLAGS@
+knet_LIBS = @knet_LIBS@
+libdir = @libdir@
+libexecdir = @libexecdir@
+libsystemd_CFLAGS = @libsystemd_CFLAGS@
+libsystemd_LIBS = @libsystemd_LIBS@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+nozzle_CFLAGS = @nozzle_CFLAGS@
+nozzle_LIBS = @nozzle_LIBS@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+statgrab_CFLAGS = @statgrab_CFLAGS@
+statgrab_LIBS = @statgrab_LIBS@
+statgrabge090_CFLAGS = @statgrabge090_CFLAGS@
+statgrabge090_LIBS = @statgrabge090_LIBS@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+MAINTAINERCLEANFILES = Makefile.in
+lib_LTLIBRARIES = libcorosync_common.la
+libcorosync_common_la_SOURCES = error_conversion.c
+libcorosync_common_la_LDFLAGS = -version-number 4:0:0
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign common_lib/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign common_lib/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+install-libLTLIBRARIES: $(lib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
+ list2=; for p in $$list; do \
+ if test -f $$p; then \
+ list2="$$list2 $$p"; \
+ else :; fi; \
+ done; \
+ test -z "$$list2" || { \
+ echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \
+ }
+
+uninstall-libLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \
+ done
+
+clean-libLTLIBRARIES:
+ -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
+ @list='$(lib_LTLIBRARIES)'; \
+ locs=`for p in $$list; do echo $$p; done | \
+ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+ sort -u`; \
+ test -z "$$locs" || { \
+ echo rm -f $${locs}; \
+ rm -f $${locs}; \
+ }
+
+libcorosync_common.la: $(libcorosync_common_la_OBJECTS) $(libcorosync_common_la_DEPENDENCIES) $(EXTRA_libcorosync_common_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(libcorosync_common_la_LINK) -rpath $(libdir) $(libcorosync_common_la_OBJECTS) $(libcorosync_common_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/error_conversion.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LTLIBRARIES)
+installdirs:
+ for dir in "$(DESTDIR)$(libdir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+ -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+clean: clean-am
+
+clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am: install-libLTLIBRARIES
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-libLTLIBRARIES
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
+ clean-libLTLIBRARIES clean-libtool cscopelist-am ctags \
+ ctags-am distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-dvi install-dvi-am install-exec \
+ install-exec-am install-html install-html-am install-info \
+ install-info-am install-libLTLIBRARIES install-man install-pdf \
+ install-pdf-am install-ps install-ps-am install-strip \
+ installcheck installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags tags-am uninstall uninstall-am uninstall-libLTLIBRARIES
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/common_lib/error_conversion.c b/common_lib/error_conversion.c
new file mode 100644
index 0000000..591fd29
--- /dev/null
+++ b/common_lib/error_conversion.c
@@ -0,0 +1,234 @@
+/*
+ * Copyright (c) 2008 Allied Telesis Labs.
+ * Copyright (c) 2012 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Author: Angus Salkeld (asalkeld@redhat.com)
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of the MontaVista Software, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <config.h>
+#include <corosync/corotypes.h>
+
+cs_error_t qb_to_cs_error (int result)
+{
+ int32_t res;
+ cs_error_t err = CS_ERR_LIBRARY;
+
+ if (result >= 0) {
+ return CS_OK;
+ }
+ res = -result;
+
+ switch (res) {
+ case EBADF:
+ err = CS_ERR_BAD_HANDLE;
+ break;
+ case ENOMEM:
+ err = CS_ERR_NO_MEMORY;
+ break;
+ case ENOMSG:
+ case ENOBUFS:
+ case ETIMEDOUT:
+ case EAGAIN:
+ err = CS_ERR_TRY_AGAIN;
+ break;
+#ifdef EBADE
+ case EBADE:
+ err = CS_ERR_FAILED_OPERATION;
+ break;
+#endif
+#ifdef ETIME
+ case ETIME:
+ err = CS_ERR_TIMEOUT;
+ break;
+#endif
+ case EINVAL:
+ err = CS_ERR_INVALID_PARAM;
+ break;
+ case EBUSY:
+ err = CS_ERR_BUSY;
+ break;
+ case EACCES:
+ err = CS_ERR_ACCESS;
+ break;
+ case EOVERFLOW:
+ err = CS_ERR_NAME_TOO_LONG;
+ break;
+ case EEXIST:
+ err = CS_ERR_EXIST;
+ break;
+ case ENOSPC:
+ err = CS_ERR_NO_SPACE;
+ break;
+ case EINTR:
+ err = CS_ERR_INTERRUPT;
+ break;
+ case ENOENT:
+ case ENODEV:
+ err = CS_ERR_NOT_EXIST;
+ break;
+ case ENOSYS:
+ case ENOTSUP:
+ err = CS_ERR_NOT_SUPPORTED;
+ break;
+#ifdef EBADMSG
+ case EBADMSG:
+ err = CS_ERR_MESSAGE_ERROR;
+ break;
+#endif
+ case EMSGSIZE:
+ case E2BIG:
+ err = CS_ERR_TOO_BIG;
+ break;
+ case ECONNREFUSED:
+ case ENOTCONN:
+ default:
+ err = CS_ERR_LIBRARY;
+ break;
+ }
+
+ return err;
+}
+
+cs_error_t hdb_error_to_cs (int res)
+{
+ if (res == 0) {
+ return (CS_OK);
+ } else {
+ if (res == -EBADF) {
+ return (CS_ERR_BAD_HANDLE);
+ } else if (res == -ENOMEM) {
+ return (CS_ERR_NO_MEMORY);
+ } else if (res == -EMFILE) {
+ return (CS_ERR_NO_RESOURCES);
+ } else if (res == -EACCES) {
+ return (CS_ERR_ACCESS);
+ }
+ return (CS_ERR_LIBRARY);
+ }
+}
+
+const char * cs_strerror(cs_error_t err)
+{
+ switch (err) {
+ case CS_OK:
+ return "success";
+
+ case CS_ERR_LIBRARY:
+ return "CS_ERR_LIBRARY";
+
+ case CS_ERR_VERSION:
+ return "CS_ERR_VERSION";
+
+ case CS_ERR_INIT:
+ return "CS_ERR_INIT";
+
+ case CS_ERR_NO_MEMORY:
+ return "CS_ERR_NO_MEMORY";
+
+ case CS_ERR_NAME_TOO_LONG :
+ return "CS_ERR_NAME_TOO_LONG";
+
+ case CS_ERR_TIMEOUT:
+ return "CS_ERR_TIMEOUT";
+
+ case CS_ERR_TRY_AGAIN:
+ return "CS_ERR_TRY_AGAIN";
+
+ case CS_ERR_INVALID_PARAM:
+ return "CS_ERR_INVALID_PARAM";
+
+ case CS_ERR_BAD_HANDLE:
+ return "CS_ERR_BAD_HANDLE";
+
+ case CS_ERR_BUSY :
+ return "CS_ERR_BUSY";
+
+ case CS_ERR_ACCESS :
+ return "CS_ERR_ACCESS";
+
+ case CS_ERR_NOT_EXIST :
+ return "CS_ERR_NOT_EXIST";
+
+ case CS_ERR_EXIST :
+ return "CS_ERR_EXIST";
+
+ case CS_ERR_NO_SPACE :
+ return "CS_ERR_NO_SPACE";
+
+ case CS_ERR_INTERRUPT :
+ return "CS_ERR_INTERRUPT";
+
+ case CS_ERR_NAME_NOT_FOUND :
+ return "CS_ERR_NAME_NOT_FOUND";
+
+ case CS_ERR_NO_RESOURCES :
+ return "CS_ERR_NO_RESOURCES";
+
+ case CS_ERR_NOT_SUPPORTED :
+ return "CS_ERR_NOT_SUPPORTED";
+
+ case CS_ERR_BAD_OPERATION :
+ return "CS_ERR_BAD_OPERATION";
+
+ case CS_ERR_FAILED_OPERATION :
+ return "CS_ERR_FAILED_OPERATION";
+
+ case CS_ERR_MESSAGE_ERROR :
+ return "CS_ERR_MESSAGE_ERROR";
+
+ case CS_ERR_QUEUE_FULL :
+ return "CS_ERR_QUEUE_FULL";
+
+ case CS_ERR_QUEUE_NOT_AVAILABLE :
+ return "CS_ERR_QUEUE_NOT_AVAILABLE";
+
+ case CS_ERR_BAD_FLAGS :
+ return "CS_ERR_BAD_FLAGS";
+
+ case CS_ERR_TOO_BIG :
+ return "CS_ERR_TOO_BIG";
+
+ case CS_ERR_NO_SECTIONS :
+ return "CS_ERR_NO_SECTIONS";
+
+ case CS_ERR_CONTEXT_NOT_FOUND :
+ return "CS_ERR_CONTEXT_NOT_FOUND";
+
+ case CS_ERR_TOO_MANY_GROUPS :
+ return "CS_ERR_TOO_MANY_GROUPS";
+
+ case CS_ERR_SECURITY :
+ return "CS_ERR_SECURITY";
+
+ default:
+ return "unknown error";
+ }
+}
diff --git a/conf/COROSYNC-MIB.txt b/conf/COROSYNC-MIB.txt
new file mode 100644
index 0000000..2ceca98
--- /dev/null
+++ b/conf/COROSYNC-MIB.txt
@@ -0,0 +1,239 @@
+COROSYNC-MIB DEFINITIONS ::= BEGIN
+
+--
+-- MIB objects for Corosync
+--
+
+IMPORTS
+ MODULE-IDENTITY,NOTIFICATION-TYPE,
+ Integer32,enterprises,OBJECT-TYPE,
+ Counter64 FROM SNMPv2-SMI
+ MODULE-COMPLIANCE, OBJECT-GROUP,
+ NOTIFICATION-GROUP FROM SNMPv2-CONF
+;
+
+corosync MODULE-IDENTITY
+ LAST-UPDATED "201801121241Z"
+ ORGANIZATION "www.corosync.org"
+ CONTACT-INFO "name: Yuki Sato
+ email: users@clusterlabs.org"
+ DESCRIPTION "*RRP* related staff has changed to *Link* staff"
+ REVISION "201801121241Z"
+ DESCRIPTION "Add cluster quorum traps, fix smilint errors, and fix notification block ID"
+ REVISION "201101211300Z"
+ DESCRIPTION "MIB objects for Corosync"
+ REVISION "201003251209Z"
+ DESCRIPTION "First draft"
+ REVISION "200911061318Z"
+ DESCRIPTION
+ "Private Enterprise Number has been assigned."
+ ::= { enterprises 35488 }
+
+--
+-- top level structure
+--
+corosyncNotices OBJECT IDENTIFIER ::= { corosync 0 }
+corosyncObjects OBJECT IDENTIFIER ::= { corosync 1 }
+corosyncConformance OBJECT IDENTIFIER ::= { corosync 200 }
+
+--
+-- Corosync MIB entries
+--
+
+--
+-- Node Information
+--
+corosyncObjectsNodeName OBJECT-TYPE
+ SYNTAX OCTET STRING (SIZE(1..64))
+ MAX-ACCESS accessible-for-notify
+ STATUS current
+ DESCRIPTION "Hostname of the cluster node."
+::= { corosyncObjects 1 }
+
+corosyncObjectsNodeID OBJECT-TYPE
+ SYNTAX Unsigned32
+ MAX-ACCESS accessible-for-notify
+ STATUS current
+ DESCRIPTION "The unique integer of the node."
+::= { corosyncObjects 2 }
+
+corosyncObjectsNodeStatus OBJECT-TYPE
+ SYNTAX OCTET STRING
+ MAX-ACCESS accessible-for-notify
+ STATUS current
+ DESCRIPTION
+ "The status of the node."
+::= { corosyncObjects 3 }
+
+corosyncObjectsNodeAddress OBJECT-TYPE
+ SYNTAX OCTET STRING
+ MAX-ACCESS accessible-for-notify
+ STATUS current
+ DESCRIPTION "The address of the node."
+::= { corosyncObjects 4 }
+
+corosyncObjectsLocalNodeID OBJECT-TYPE
+ SYNTAX Unsigned32
+ MAX-ACCESS accessible-for-notify
+ STATUS current
+ DESCRIPTION "The unique integer of local node."
+::= { corosyncObjects 5 }
+
+--
+-- Quorum Information
+--
+--
+
+-- not currently used, but here for future use
+corosyncObjectsRingSeq OBJECT-TYPE
+ SYNTAX Counter64
+ MAX-ACCESS accessible-for-notify
+ STATUS current
+ DESCRIPTION
+ "Ring ID Sequence number"
+::= { corosyncObjects 20 }
+
+corosyncObjectsQuorumStatus OBJECT-TYPE
+ SYNTAX OCTET STRING
+ MAX-ACCESS accessible-for-notify
+ STATUS current
+ DESCRIPTION
+ "Quorum Status"
+::= { corosyncObjects 21 }
+
+--
+-- Link Information
+---
+
+corosyncObjectsIfaceNo OBJECT-TYPE
+ SYNTAX Integer32
+ MAX-ACCESS accessible-for-notify
+ STATUS current
+ DESCRIPTION "The integer of interface."
+::= { corosyncObjects 60 }
+
+corosyncObjectsLinkStatus OBJECT-TYPE
+ SYNTAX OCTET STRING
+ MAX-ACCESS accessible-for-notify
+ STATUS current
+ DESCRIPTION
+ "Link Status"
+::= { corosyncObjects 61 }
+
+--
+-- Application Information
+--
+corosyncObjectsAppName OBJECT-TYPE
+ SYNTAX OCTET STRING
+ MAX-ACCESS accessible-for-notify
+ STATUS current
+ DESCRIPTION
+ "Application name"
+::= { corosyncObjects 40 }
+
+corosyncObjectsAppStatus OBJECT-TYPE
+ SYNTAX OCTET STRING
+ MAX-ACCESS accessible-for-notify
+ STATUS current
+ DESCRIPTION
+ "Application status"
+::= { corosyncObjects 41 }
+
+--
+-- Notification Information
+--
+corosyncNoticesNodeStatus NOTIFICATION-TYPE
+ OBJECTS { corosyncObjectsNodeName,
+ corosyncObjectsNodeID,
+ corosyncObjectsNodeAddress,
+ corosyncObjectsNodeStatus }
+ STATUS current
+ DESCRIPTION
+ "Produced when a node 'corosyncObjectsNodeName' joins or leaves
+ the cluster.
+
+ The notification includes the node name, nodeid, the node's
+ IP address and the status (either 'joined' or 'left')."
+::= { corosyncNotices 1 }
+
+corosyncNoticesQuorumStatus NOTIFICATION-TYPE
+ OBJECTS { corosyncObjectsNodeName,
+ corosyncObjectsNodeID,
+ corosyncObjectsQuorumStatus }
+ STATUS current
+ DESCRIPTION
+ "Produced when the quorum state changes.
+
+ The notification also includes the node name, nodeid
+ and the new state (either 'quorate' or 'NOT quorate')."
+::= { corosyncNotices 2 }
+
+corosyncNoticesAppStatus NOTIFICATION-TYPE
+ OBJECTS { corosyncObjectsNodeName,
+ corosyncObjectsNodeID,
+ corosyncObjectsAppName,
+ corosyncObjectsAppStatus }
+ STATUS current
+ DESCRIPTION
+ "Produced when a client application 'corosyncObjectsAppName' connects or
+ disconnects from Corosync.
+
+ The notification also includes the node name, nodeid, the application
+ name and the new state (either 'connected' or 'disconnected')."
+::= { corosyncNotices 3 }
+
+corosyncNoticesLinkStatus NOTIFICATION-TYPE
+ OBJECTS { corosyncObjectsNodeName,
+ corosyncObjectsLocalNodeID,
+ corosyncObjectsNodeID,
+ corosyncObjectsIfaceNo,
+ corosyncObjectsLinkStatus }
+ STATUS current
+ DESCRIPTION
+ "Produced when the interface of Link is marked failed or operational.
+
+ The notification also includes the node name, nodeid, iface number
+ and the new state (either 'failed' or 'operational')."
+::= { corosyncNotices 4 }
+
+--
+-- Compliance Information
+--
+corosyncCompliances OBJECT IDENTIFIER ::= { corosyncConformance 1 }
+
+corosyncConformanceGroups OBJECT IDENTIFIER ::= { corosyncConformance 2 }
+
+corosyncCompliance MODULE-COMPLIANCE
+ STATUS current
+ DESCRIPTION "Corosync compliance information"
+ MODULE -- this module
+ MANDATORY-GROUPS { corosyncObjectGroup, corosyncNotificationGroup }
+::= { corosyncCompliances 1 }
+
+corosyncObjectGroup OBJECT-GROUP
+ OBJECTS { corosyncObjectsNodeName,
+ corosyncObjectsNodeID,
+ corosyncObjectsNodeStatus,
+ corosyncObjectsNodeAddress,
+ corosyncObjectsRingSeq,
+ corosyncObjectsQuorumStatus,
+ corosyncObjectsAppName,
+ corosyncObjectsAppStatus,
+ corosyncObjectsIfaceNo,
+ corosyncObjectsLinkStatus
+ }
+ STATUS current
+ DESCRIPTION "Corosync Object Conformance Group"
+::= { corosyncConformanceGroups 1 }
+
+corosyncNotificationGroup NOTIFICATION-GROUP
+ NOTIFICATIONS { corosyncNoticesNodeStatus,
+ corosyncNoticesQuorumStatus,
+ corosyncNoticesAppStatus,
+ corosyncNoticesLinkStatus
+ }
+ STATUS current
+ DESCRIPTION "Corosync Notification Conformance Group"
+::= { corosyncConformanceGroups 2 }
+
+END
diff --git a/conf/Makefile.am b/conf/Makefile.am
new file mode 100644
index 0000000..44581eb
--- /dev/null
+++ b/conf/Makefile.am
@@ -0,0 +1,67 @@
+# Copyright (c) 2009 Red Hat, Inc.
+#
+# Authors: Andrew Beekhof
+# Steven Dake (sdake@redhat.com)
+#
+# This software licensed under BSD license, the text of which follows:
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# - Redistributions of source code must retain the above copyright notice,
+# this list of conditions and the following disclaimer.
+# - Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+# - Neither the name of the MontaVista Software, Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from this
+# software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+# THE POSSIBILITY OF SUCH DAMAGE.
+
+MAINTAINERCLEANFILES = Makefile.in
+
+EXTRA_DIST = COROSYNC-MIB.txt corosync-signals.conf \
+ corosync.conf.example \
+ xml2conf.xsl \
+ lenses/corosync.aug \
+ lenses/tests/test_corosync.aug
+
+corosysconfdir = ${COROSYSCONFDIR}
+
+corosysconf_DATA = corosync.conf.example
+
+if INSTALL_AUGEAS
+corolensdir = ${datadir}/augeas/lenses
+corolens_DATA = lenses/corosync.aug
+
+corolenstestdir = ${corolensdir}/tests
+corolenstest_DATA = lenses/tests/test_corosync.aug
+endif
+
+if INSTALL_XMLCONF
+corosysxmlxsltdir = ${datadir}/corosync
+corosysxmlxslt_DATA = xml2conf.xsl
+endif
+
+if INSTALL_MIB
+mibdir = $(datadir)/snmp/mibs
+mib_DATA = COROSYNC-MIB.txt
+endif
+
+if INSTALL_DBUSCONF
+dbusdir = $(sysconfdir)/dbus-1/system.d
+dbus_DATA = corosync-signals.conf
+endif
+
+SUBDIRS = logrotate
diff --git a/conf/Makefile.in b/conf/Makefile.in
new file mode 100644
index 0000000..0d2ebe8
--- /dev/null
+++ b/conf/Makefile.in
@@ -0,0 +1,883 @@
+# Makefile.in generated by automake 1.13.4 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+# Copyright (c) 2009 Red Hat, Inc.
+#
+# Authors: Andrew Beekhof
+# Steven Dake (sdake@redhat.com)
+#
+# This software licensed under BSD license, the text of which follows:
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# - Redistributions of source code must retain the above copyright notice,
+# this list of conditions and the following disclaimer.
+# - Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+# - Neither the name of the MontaVista Software, Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from this
+# software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+# THE POSSIBILITY OF SUCH DAMAGE.
+
+VPATH = @srcdir@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = conf
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/lib/libcfg.verso $(top_srcdir)/lib/libcpg.verso \
+ $(top_srcdir)/lib/libquorum.verso \
+ $(top_srcdir)/lib/libsam.verso \
+ $(top_srcdir)/lib/libvotequorum.verso \
+ $(top_srcdir)/lib/libcmap.verso $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/include/corosync/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+SOURCES =
+DIST_SOURCES =
+RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \
+ ctags-recursive dvi-recursive html-recursive info-recursive \
+ install-data-recursive install-dvi-recursive \
+ install-exec-recursive install-html-recursive \
+ install-info-recursive install-pdf-recursive \
+ install-ps-recursive install-recursive installcheck-recursive \
+ installdirs-recursive pdf-recursive ps-recursive \
+ tags-recursive uninstall-recursive
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+am__installdirs = "$(DESTDIR)$(corolensdir)" \
+ "$(DESTDIR)$(corolenstestdir)" "$(DESTDIR)$(corosysconfdir)" \
+ "$(DESTDIR)$(corosysxmlxsltdir)" "$(DESTDIR)$(dbusdir)" \
+ "$(DESTDIR)$(mibdir)"
+DATA = $(corolens_DATA) $(corolenstest_DATA) $(corosysconf_DATA) \
+ $(corosysxmlxslt_DATA) $(dbus_DATA) $(mib_DATA)
+RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
+ distclean-recursive maintainer-clean-recursive
+am__recursive_targets = \
+ $(RECURSIVE_TARGETS) \
+ $(RECURSIVE_CLEAN_TARGETS) \
+ $(am__extra_recursive_targets)
+AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \
+ distdir
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+DIST_SUBDIRS = $(SUBDIRS)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+am__relativize = \
+ dir0=`pwd`; \
+ sed_first='s,^\([^/]*\)/.*$$,\1,'; \
+ sed_rest='s,^[^/]*/*,,'; \
+ sed_last='s,^.*/\([^/]*\)$$,\1,'; \
+ sed_butlast='s,/*[^/]*$$,,'; \
+ while test -n "$$dir1"; do \
+ first=`echo "$$dir1" | sed -e "$$sed_first"`; \
+ if test "$$first" != "."; then \
+ if test "$$first" = ".."; then \
+ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
+ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
+ else \
+ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
+ if test "$$first2" = "$$first"; then \
+ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
+ else \
+ dir2="../$$dir2"; \
+ fi; \
+ dir0="$$dir0"/"$$first"; \
+ fi; \
+ fi; \
+ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
+ done; \
+ reldir="$$dir2"
+ACLOCAL = @ACLOCAL@
+ALLOCA = @ALLOCA@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUGTOOL = @AUGTOOL@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BASHPATH = @BASHPATH@
+BINDGEN = @BINDGEN@
+CARGO = @CARGO@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFG_SONAME = @CFG_SONAME@
+CFLAGS = @CFLAGS@
+CLIPPY = @CLIPPY@
+CMAP_SONAME = @CMAP_SONAME@
+COROSYSCONFDIR = @COROSYSCONFDIR@
+CPG_SONAME = @CPG_SONAME@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DBUS_CFLAGS = @DBUS_CFLAGS@
+DBUS_LIBS = @DBUS_LIBS@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DOT = @DOT@
+DOXYGEN = @DOXYGEN@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GREP = @GREP@
+GROFF = @GROFF@
+INITCONFIGDIR = @INITCONFIGDIR@
+INITDDIR = @INITDDIR@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBQB_CFLAGS = @LIBQB_CFLAGS@
+LIBQB_LIBS = @LIBQB_LIBS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LINT_FLAGS = @LINT_FLAGS@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LOGDIR = @LOGDIR@
+LOGROTATEDIR = @LOGROTATEDIR@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+QUORUM_SONAME = @QUORUM_SONAME@
+RANLIB = @RANLIB@
+RUSTC = @RUSTC@
+RUSTDOC = @RUSTDOC@
+RUSTFMT = @RUSTFMT@
+RUST_FLAGS = @RUST_FLAGS@
+RUST_TARGET_DIR = @RUST_TARGET_DIR@
+SAM_SONAME = @SAM_SONAME@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SNMPCONFIG = @SNMPCONFIG@
+SNMP_LIBS = @SNMP_LIBS@
+SOMAJOR = @SOMAJOR@
+SOMICRO = @SOMICRO@
+SOMINOR = @SOMINOR@
+SONAME = @SONAME@
+STRIP = @STRIP@
+SYSTEMDDIR = @SYSTEMDDIR@
+VERSCRIPT_LDFLAGS = @VERSCRIPT_LDFLAGS@
+VERSION = @VERSION@
+VOTEQUORUM_SONAME = @VOTEQUORUM_SONAME@
+WITH_LIST = @WITH_LIST@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+corosyncrustver = @corosyncrustver@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+knet_CFLAGS = @knet_CFLAGS@
+knet_LIBS = @knet_LIBS@
+libdir = @libdir@
+libexecdir = @libexecdir@
+libsystemd_CFLAGS = @libsystemd_CFLAGS@
+libsystemd_LIBS = @libsystemd_LIBS@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+nozzle_CFLAGS = @nozzle_CFLAGS@
+nozzle_LIBS = @nozzle_LIBS@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+statgrab_CFLAGS = @statgrab_CFLAGS@
+statgrab_LIBS = @statgrab_LIBS@
+statgrabge090_CFLAGS = @statgrabge090_CFLAGS@
+statgrabge090_LIBS = @statgrabge090_LIBS@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+MAINTAINERCLEANFILES = Makefile.in
+EXTRA_DIST = COROSYNC-MIB.txt corosync-signals.conf \
+ corosync.conf.example \
+ xml2conf.xsl \
+ lenses/corosync.aug \
+ lenses/tests/test_corosync.aug
+
+corosysconfdir = ${COROSYSCONFDIR}
+corosysconf_DATA = corosync.conf.example
+@INSTALL_AUGEAS_TRUE@corolensdir = ${datadir}/augeas/lenses
+@INSTALL_AUGEAS_TRUE@corolens_DATA = lenses/corosync.aug
+@INSTALL_AUGEAS_TRUE@corolenstestdir = ${corolensdir}/tests
+@INSTALL_AUGEAS_TRUE@corolenstest_DATA = lenses/tests/test_corosync.aug
+@INSTALL_XMLCONF_TRUE@corosysxmlxsltdir = ${datadir}/corosync
+@INSTALL_XMLCONF_TRUE@corosysxmlxslt_DATA = xml2conf.xsl
+@INSTALL_MIB_TRUE@mibdir = $(datadir)/snmp/mibs
+@INSTALL_MIB_TRUE@mib_DATA = COROSYNC-MIB.txt
+@INSTALL_DBUSCONF_TRUE@dbusdir = $(sysconfdir)/dbus-1/system.d
+@INSTALL_DBUSCONF_TRUE@dbus_DATA = corosync-signals.conf
+SUBDIRS = logrotate
+all: all-recursive
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign conf/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign conf/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+install-corolensDATA: $(corolens_DATA)
+ @$(NORMAL_INSTALL)
+ @list='$(corolens_DATA)'; test -n "$(corolensdir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(corolensdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(corolensdir)" || exit 1; \
+ fi; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(corolensdir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(corolensdir)" || exit $$?; \
+ done
+
+uninstall-corolensDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(corolens_DATA)'; test -n "$(corolensdir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ dir='$(DESTDIR)$(corolensdir)'; $(am__uninstall_files_from_dir)
+install-corolenstestDATA: $(corolenstest_DATA)
+ @$(NORMAL_INSTALL)
+ @list='$(corolenstest_DATA)'; test -n "$(corolenstestdir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(corolenstestdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(corolenstestdir)" || exit 1; \
+ fi; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(corolenstestdir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(corolenstestdir)" || exit $$?; \
+ done
+
+uninstall-corolenstestDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(corolenstest_DATA)'; test -n "$(corolenstestdir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ dir='$(DESTDIR)$(corolenstestdir)'; $(am__uninstall_files_from_dir)
+install-corosysconfDATA: $(corosysconf_DATA)
+ @$(NORMAL_INSTALL)
+ @list='$(corosysconf_DATA)'; test -n "$(corosysconfdir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(corosysconfdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(corosysconfdir)" || exit 1; \
+ fi; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(corosysconfdir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(corosysconfdir)" || exit $$?; \
+ done
+
+uninstall-corosysconfDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(corosysconf_DATA)'; test -n "$(corosysconfdir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ dir='$(DESTDIR)$(corosysconfdir)'; $(am__uninstall_files_from_dir)
+install-corosysxmlxsltDATA: $(corosysxmlxslt_DATA)
+ @$(NORMAL_INSTALL)
+ @list='$(corosysxmlxslt_DATA)'; test -n "$(corosysxmlxsltdir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(corosysxmlxsltdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(corosysxmlxsltdir)" || exit 1; \
+ fi; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(corosysxmlxsltdir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(corosysxmlxsltdir)" || exit $$?; \
+ done
+
+uninstall-corosysxmlxsltDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(corosysxmlxslt_DATA)'; test -n "$(corosysxmlxsltdir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ dir='$(DESTDIR)$(corosysxmlxsltdir)'; $(am__uninstall_files_from_dir)
+install-dbusDATA: $(dbus_DATA)
+ @$(NORMAL_INSTALL)
+ @list='$(dbus_DATA)'; test -n "$(dbusdir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(dbusdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(dbusdir)" || exit 1; \
+ fi; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(dbusdir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(dbusdir)" || exit $$?; \
+ done
+
+uninstall-dbusDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(dbus_DATA)'; test -n "$(dbusdir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ dir='$(DESTDIR)$(dbusdir)'; $(am__uninstall_files_from_dir)
+install-mibDATA: $(mib_DATA)
+ @$(NORMAL_INSTALL)
+ @list='$(mib_DATA)'; test -n "$(mibdir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(mibdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(mibdir)" || exit 1; \
+ fi; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(mibdir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(mibdir)" || exit $$?; \
+ done
+
+uninstall-mibDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(mib_DATA)'; test -n "$(mibdir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ dir='$(DESTDIR)$(mibdir)'; $(am__uninstall_files_from_dir)
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run 'make' without going through this Makefile.
+# To change the values of 'make' variables: instead of editing Makefiles,
+# (1) if the variable is set in 'config.status', edit 'config.status'
+# (which will cause the Makefiles to be regenerated when you run 'make');
+# (2) otherwise, pass the desired values on the 'make' command line.
+$(am__recursive_targets):
+ @fail=; \
+ if $(am__make_keepgoing); then \
+ failcom='fail=yes'; \
+ else \
+ failcom='exit 1'; \
+ fi; \
+ dot_seen=no; \
+ target=`echo $@ | sed s/-recursive//`; \
+ case "$@" in \
+ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+ *) list='$(SUBDIRS)' ;; \
+ esac; \
+ for subdir in $$list; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ dot_seen=yes; \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || eval $$failcom; \
+ done; \
+ if test "$$dot_seen" = "no"; then \
+ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+ fi; test -z "$$fail"
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-recursive
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
+ include_option=--etags-include; \
+ empty_fix=.; \
+ else \
+ include_option=--include; \
+ empty_fix=; \
+ fi; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test ! -f $$subdir/TAGS || \
+ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
+ fi; \
+ done; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-recursive
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-recursive
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+ @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ $(am__make_dryrun) \
+ || test -d "$(distdir)/$$subdir" \
+ || $(MKDIR_P) "$(distdir)/$$subdir" \
+ || exit 1; \
+ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
+ $(am__relativize); \
+ new_distdir=$$reldir; \
+ dir1=$$subdir; dir2="$(top_distdir)"; \
+ $(am__relativize); \
+ new_top_distdir=$$reldir; \
+ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
+ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
+ ($(am__cd) $$subdir && \
+ $(MAKE) $(AM_MAKEFLAGS) \
+ top_distdir="$$new_top_distdir" \
+ distdir="$$new_distdir" \
+ am__remove_distdir=: \
+ am__skip_length_check=: \
+ am__skip_mode_fix=: \
+ distdir) \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-recursive
+all-am: Makefile $(DATA)
+installdirs: installdirs-recursive
+installdirs-am:
+ for dir in "$(DESTDIR)$(corolensdir)" "$(DESTDIR)$(corolenstestdir)" "$(DESTDIR)$(corosysconfdir)" "$(DESTDIR)$(corosysxmlxsltdir)" "$(DESTDIR)$(dbusdir)" "$(DESTDIR)$(mibdir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-recursive
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+ -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+clean: clean-recursive
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-recursive
+ -rm -f Makefile
+distclean-am: clean-am distclean-generic distclean-tags
+
+dvi: dvi-recursive
+
+dvi-am:
+
+html: html-recursive
+
+html-am:
+
+info: info-recursive
+
+info-am:
+
+install-data-am: install-corolensDATA install-corolenstestDATA \
+ install-corosysconfDATA install-corosysxmlxsltDATA \
+ install-dbusDATA install-mibDATA
+
+install-dvi: install-dvi-recursive
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-recursive
+
+install-html-am:
+
+install-info: install-info-recursive
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-recursive
+
+install-pdf-am:
+
+install-ps: install-ps-recursive
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-recursive
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-recursive
+
+pdf-am:
+
+ps: ps-recursive
+
+ps-am:
+
+uninstall-am: uninstall-corolensDATA uninstall-corolenstestDATA \
+ uninstall-corosysconfDATA uninstall-corosysxmlxsltDATA \
+ uninstall-dbusDATA uninstall-mibDATA
+
+.MAKE: $(am__recursive_targets) install-am install-strip
+
+.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \
+ check-am clean clean-generic clean-libtool cscopelist-am ctags \
+ ctags-am distclean distclean-generic distclean-libtool \
+ distclean-tags distdir dvi dvi-am html html-am info info-am \
+ install install-am install-corolensDATA \
+ install-corolenstestDATA install-corosysconfDATA \
+ install-corosysxmlxsltDATA install-data install-data-am \
+ install-dbusDATA install-dvi install-dvi-am install-exec \
+ install-exec-am install-html install-html-am install-info \
+ install-info-am install-man install-mibDATA install-pdf \
+ install-pdf-am install-ps install-ps-am install-strip \
+ installcheck installcheck-am installdirs installdirs-am \
+ maintainer-clean maintainer-clean-generic mostlyclean \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags tags-am uninstall uninstall-am uninstall-corolensDATA \
+ uninstall-corolenstestDATA uninstall-corosysconfDATA \
+ uninstall-corosysxmlxsltDATA uninstall-dbusDATA \
+ uninstall-mibDATA
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/conf/corosync-signals.conf b/conf/corosync-signals.conf
new file mode 100644
index 0000000..4112d0c
--- /dev/null
+++ b/conf/corosync-signals.conf
@@ -0,0 +1,26 @@
+<!DOCTYPE busconfig PUBLIC
+ "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
+ "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
+<busconfig>
+
+ <!-- Only root can own the corosync service. -->
+ <policy user="root">
+ <allow own="org.corosync"/>
+ </policy>
+
+ <policy context="default">
+ <allow send_destination="org.corosync"
+ send_path="/org/corosync"
+ send_interface="org.corosync"
+ send_member="NodeStateChange"/>
+ <allow send_destination="org.corosync"
+ send_path="/org/corosync"
+ send_interface="org.corosync"
+ send_member="ConnectionStateChange"/>
+ <allow send_destination="org.corosync"
+ send_path="/org/corosync"
+ send_interface="org.corosync"
+ send_member="QuorumStateChange"/>
+ </policy>
+
+</busconfig>
diff --git a/conf/corosync.conf.example b/conf/corosync.conf.example
new file mode 100644
index 0000000..4658a86
--- /dev/null
+++ b/conf/corosync.conf.example
@@ -0,0 +1,71 @@
+# Please read the corosync.conf.5 manual page
+totem {
+ version: 2
+
+ # Set name of the cluster
+ cluster_name: ExampleCluster
+
+ # crypto_cipher and crypto_hash: Used for mutual node authentication.
+ # If you choose to enable this, then do remember to create a shared
+ # secret with "corosync-keygen".
+ # enabling crypto_cipher, requires also enabling of crypto_hash.
+ # crypto works only with knet transport
+ crypto_cipher: none
+ crypto_hash: none
+}
+
+logging {
+ # Log the source file and line where messages are being
+ # generated. When in doubt, leave off. Potentially useful for
+ # debugging.
+ fileline: off
+ # Log to standard error. When in doubt, set to yes. Useful when
+ # running in the foreground (when invoking "corosync -f")
+ to_stderr: yes
+ # Log to a log file. When set to "no", the "logfile" option
+ # must not be set.
+ to_logfile: yes
+ logfile: /var/log/cluster/corosync.log
+ # Log to the system log daemon. When in doubt, set to yes.
+ to_syslog: yes
+ # Log debug messages (very verbose). When in doubt, leave off.
+ debug: off
+ # Log messages with time stamps. When in doubt, set to hires (or on)
+ #timestamp: hires
+ logger_subsys {
+ subsys: QUORUM
+ debug: off
+ }
+}
+
+quorum {
+ # Enable and configure quorum subsystem (default: off)
+ # see also corosync.conf.5 and votequorum.5
+ #provider: corosync_votequorum
+}
+
+nodelist {
+ # Change/uncomment/add node sections to match cluster configuration
+
+ node {
+ # Hostname of the node
+ name: node1
+ # Cluster membership node identifier
+ nodeid: 1
+ # Address of first link
+ #ring0_addr: 192.168.0.1
+ # When knet transport is used it's possible to define up to 8 links
+ #ring1_addr: 192.168.1.1
+ }
+ node {
+ # Hostname of the node
+ name: node2
+ # Cluster membership node identifier
+ nodeid: 2
+ # Address of first link
+ #ring0_addr: 192.168.0.2
+ # When knet transport is used it's possible to define up to 8 links
+ #ring1_addr: 192.168.1.2
+ }
+ # ...
+}
diff --git a/conf/lenses/corosync.aug b/conf/lenses/corosync.aug
new file mode 100644
index 0000000..edeb4fb
--- /dev/null
+++ b/conf/lenses/corosync.aug
@@ -0,0 +1,184 @@
+(* Process /etc/corosync/corosync.conf *)
+(* The lens is based on the corosync.conf(5) man page *)
+module Corosync =
+
+autoload xfm
+
+let comment = Util.comment
+let empty = Util.empty
+let dels = Util.del_str
+let eol = Util.eol
+
+let ws = del /[ \t]+/ " "
+let wsc = del /:[ \t]+/ ": "
+let indent = del /[ \t]*/ ""
+(* We require that braces are always followed by a newline *)
+let obr = del /\{([ \t]*)\n/ "{\n"
+let cbr = del /[ \t]*}[ \t]*\n/ "}\n"
+
+let ikey (k:regexp) = indent . key k
+
+let section (n:regexp) (b:lens) =
+ [ ikey n . ws . obr . (b|empty|comment)* . cbr ]
+
+let kv (k:regexp) (v:regexp) =
+ [ ikey k . wsc . store v . eol ]
+
+(* FIXME: it would be much more concise to write *)
+(* [ key k . ws . (bare | quoted) ] *)
+(* but the typechecker trips over that *)
+let qstr (k:regexp) =
+ let delq = del /['"]/ "\"" in
+ let bare = del /["']?/ "" . store /[^"' \t\n]+/ . del /["']?/ "" in
+ let quoted = delq . store /.*[ \t].*/ . delq in
+ [ ikey k . wsc . bare . eol ]
+ |[ ikey k . wsc . quoted . eol ]
+
+(* A integer subsection *)
+let interface =
+ let setting =
+ kv "ringnumber" Rx.integer
+ |kv "mcastport" Rx.integer
+ |kv "ttl" Rx.integer
+ |kv "broadcast" /yes|no/
+ |qstr /bindnetaddr|mcastaddr/ in
+ section "interface" setting
+
+(* The totem section *)
+let totem =
+ let setting =
+ kv "clear_node_high_bit" /yes|no/
+ |kv "rrp_mode" /none|active|passive/
+ |kv "vsftype" /none|ykd/
+ |kv "secauth" /on|off/
+ |kv "crypto_model" /nss|openssl/
+ |kv "crypto_cipher" /none|nss|aes256|aes192|aes128/
+ |kv "crypto_hash" /none|md5|sha1|sha256|sha384|sha512/
+ |kv "transport" /udp|iba|udpu/
+ |kv "version" Rx.integer
+ |kv "nodeid" Rx.integer
+ |kv "threads" Rx.integer
+ |kv "netmtu" Rx.integer
+ |kv "token" Rx.integer
+ |kv "token_retransmit" Rx.integer
+ |kv "hold" Rx.integer
+ |kv "token_retransmits_before_loss_const" Rx.integer
+ |kv "join" Rx.integer
+ |kv "send_join" Rx.integer
+ |kv "consensus" Rx.integer
+ |kv "merge" Rx.integer
+ |kv "downcheck" Rx.integer
+ |kv "fail_to_recv_const" Rx.integer
+ |kv "seqno_unchanged_const" Rx.integer
+ |kv "heartbeat_failures_allowed" Rx.integer
+ |kv "max_network_delay" Rx.integer
+ |kv "max_messages" Rx.integer
+ |kv "window_size" Rx.integer
+ |kv "rrp_problem_count_timeout" Rx.integer
+ |kv "rrp_problem_count_threshold" Rx.integer
+ |kv "rrp_token_expired_timeout" Rx.integer
+ |qstr /cluster_name/
+ |interface in
+ section "totem" setting
+
+let common_logging =
+ kv "to_syslog" /yes|no|on|off/
+ |kv "to_stderr" /yes|no|on|off/
+ |kv "to_logfile" /yes|no|on|off/
+ |kv "debug" /yes|no|on|off|trace/
+ |kv "logfile_priority" /alert|crit|debug|emerg|err|info|notice|warning/
+ |kv "syslog_priority" /alert|crit|debug|emerg|err|info|notice|warning/
+ |kv "syslog_facility" /daemon|local0|local1|local2|local3|local4|local5|local6|local7/
+ |qstr /logfile|tags/
+
+(* A logger_subsys subsection *)
+let logger_subsys =
+ let setting =
+ qstr /subsys/
+ |common_logging in
+ section "logger_subsys" setting
+
+
+(* The logging section *)
+let logging =
+ let setting =
+ kv "fileline" /yes|no|on|off/
+ |kv "function_name" /yes|no|on|off/
+ |kv "timestamp" /yes|no|on|off/
+ |common_logging
+ |logger_subsys in
+ section "logging" setting
+
+
+(* The resource section *)
+let common_resource =
+ kv "max" Rx.decimal
+ |kv "poll_period" Rx.integer
+ |kv "recovery" /reboot|shutdown|watchdog|none/
+
+let memory_used =
+ let setting =
+ common_resource in
+ section "memory_used" setting
+
+
+let load_15min =
+ let setting =
+ common_resource in
+ section "load_15min" setting
+
+let system =
+ let setting =
+ load_15min
+ |memory_used in
+ section "system" setting
+
+(* The resources section *)
+let resources =
+ let setting =
+ system in
+ section "resources" setting
+
+(* The quorum section *)
+let quorum =
+ let setting =
+ qstr /provider/
+ |kv "expected_votes" Rx.integer
+ |kv "votes" Rx.integer
+ |kv "wait_for_all" Rx.integer
+ |kv "last_man_standing" Rx.integer
+ |kv "last_man_standing_window" Rx.integer
+ |kv "auto_tie_breaker" Rx.integer
+ |kv "two_node" Rx.integer in
+ section "quorum" setting
+
+(* The service section *)
+let service =
+ let setting =
+ qstr /name|ver/ in
+ section "service" setting
+
+(* The uidgid section *)
+let uidgid =
+ let setting =
+ qstr /uid|gid/ in
+ section "uidgid" setting
+
+(* The node section *)
+let node =
+ let setting =
+ qstr /ring[0-9]_addr/
+ |kv "nodeid" Rx.integer
+ |kv "name" Rx.hostname
+ |kv "quorum_votes" Rx.integer in
+ section "node" setting
+
+(* The nodelist section *)
+let nodelist =
+ let setting =
+ node in
+ section "nodelist" setting
+
+let lns = (comment|empty|totem|quorum|logging|resources|service|uidgid|nodelist)*
+
+let xfm = transform lns (incl "/etc/corosync/corosync.conf")
diff --git a/conf/lenses/tests/test_corosync.aug b/conf/lenses/tests/test_corosync.aug
new file mode 100644
index 0000000..cbc40a3
--- /dev/null
+++ b/conf/lenses/tests/test_corosync.aug
@@ -0,0 +1,167 @@
+module Test_corosync =
+
+ let conf = "# Please read the corosync.conf.5 manual page
+
+totem {
+ version: 2
+ secauth: off
+ crypto_cipher: none
+ crypto_hash: none
+ threads: 0
+ clear_node_high_bit: no
+ rrp_mode: none
+ transport: udp
+ token: 1000
+ interface {
+ ringnumber: 0
+ bindnetaddr: 192.168.122.1
+ mcastaddr: 226.94.1.1
+ ttl: 45
+ mcastport: 5405
+ }
+}
+
+logging {
+ fileline: off
+ function_name: on
+ to_stderr: yes
+ to_logfile: yes
+ to_syslog: yes
+ logfile: /tmp/corosync.log
+ debug: off
+ timestamp: on
+ logger_subsys {
+ to_syslog: no
+ subsys: CPG
+ debug: on
+ }
+ logger_subsys {
+ to_stderr: no
+ logfile: /tmp/corosync-msg.log
+ subsys: MSG
+ debug: on
+ tags: enter|trace4
+ }
+}
+
+quorum {
+ provider: corosync_votequorum
+ expected_votes: 5
+ votes: 2
+ two_node: 1
+ wait_for_all: 1
+ last_man_standing: 1
+ last_man_standing_window: 10000
+ auto_tie_breaker: 1
+}
+
+resources {
+ system {
+ memory_used {
+ recovery: reboot
+ max: 80
+ }
+ load_15min {
+ recovery: watchdog
+ max: 8.56
+ }
+ }
+}
+
+uidgid {
+ uid: 0
+ gid: 0
+}
+
+nodelist {
+ node {
+ ring0_addr: 192.168.122.1
+ nodeid: 1
+ name: balalaika
+ quorum_votes: 2
+ }
+
+ node {
+ ring0_addr: 192.168.122.2
+ ring1_addr: 192.168.123.1
+ nodeid: 2
+ name: cythara
+ }
+}\n"
+
+test Corosync.lns get conf =
+
+ { "#comment" = "Please read the corosync.conf.5 manual page" }
+ { }
+ { "totem"
+ { "version" = "2" }
+ { "secauth" = "off" }
+ { "crypto_cipher" = "none" }
+ { "crypto_hash" = "none" }
+ { "threads" = "0" }
+ { "clear_node_high_bit" = "no" }
+ { "rrp_mode" = "none" }
+ { "transport" = "udp" }
+ { "token" = "1000" }
+ { "interface"
+ { "ringnumber" = "0" }
+ { "bindnetaddr" = "192.168.122.1" }
+ { "mcastaddr" = "226.94.1.1" }
+ { "ttl" = "45" }
+ { "mcastport" = "5405" } } }
+ { }
+ { "logging"
+ { "fileline" = "off" }
+ { "function_name" = "on" }
+ { "to_stderr" = "yes" }
+ { "to_logfile" = "yes" }
+ { "to_syslog" = "yes" }
+ { "logfile" = "/tmp/corosync.log" }
+ { "debug" = "off" }
+ { "timestamp" = "on" }
+ { "logger_subsys"
+ { "to_syslog" = "no" }
+ { "subsys" = "CPG" }
+ { "debug" = "on" } }
+ { "logger_subsys"
+ { "to_stderr" = "no" }
+ { "logfile" = "/tmp/corosync-msg.log" }
+ { "subsys" = "MSG" }
+ { "debug" = "on" }
+ { "tags" = "enter|trace4" } } }
+ { }
+ { "quorum"
+ { "provider" = "corosync_votequorum" }
+ { "expected_votes" = "5" }
+ { "votes" = "2" }
+ { "two_node" = "1" }
+ { "wait_for_all" = "1" }
+ { "last_man_standing" = "1" }
+ { "last_man_standing_window" = "10000" }
+ { "auto_tie_breaker" = "1" } }
+ { }
+ { "resources"
+ { "system"
+ { "memory_used"
+ { "recovery" = "reboot" }
+ { "max" = "80" } }
+ { "load_15min"
+ { "recovery" = "watchdog" }
+ { "max" = "8.56" } } } }
+ { }
+ { "uidgid"
+ { "uid" = "0" }
+ { "gid" = "0" } }
+ { }
+ { "nodelist"
+ { "node"
+ { "ring0_addr" = "192.168.122.1" }
+ { "nodeid" = "1" }
+ { "name" = "balalaika" }
+ { "quorum_votes" = "2" } }
+ { }
+ { "node"
+ { "ring0_addr" = "192.168.122.2" }
+ { "ring1_addr" = "192.168.123.1" }
+ { "nodeid" = "2" }
+ { "name" = "cythara" } } }
diff --git a/conf/logrotate/Makefile.am b/conf/logrotate/Makefile.am
new file mode 100644
index 0000000..35efa2d
--- /dev/null
+++ b/conf/logrotate/Makefile.am
@@ -0,0 +1,45 @@
+# Copyright (c) 2009 Red Hat, Inc.
+#
+# Authors:Jan Friesse (jfriesse@redhat.com)
+# Andrew Beekhof
+# Steven Dake (sdake@redhat.com)
+#
+# This software licensed under BSD license, the text of which follows:
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# - Redistributions of source code must retain the above copyright notice,
+# this list of conditions and the following disclaimer.
+# - Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+# - Neither the name of the MontaVista Software, Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from this
+# software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+# THE POSSIBILITY OF SUCH DAMAGE.
+
+MAINTAINERCLEANFILES = Makefile.in
+
+EXTRA_DIST = corosync-reopen.in corosync-copytruncate.in
+
+corosync: corosync-copytruncate.in
+ $(SED) -e 's#@''LOGDIR@#${LOGDIR}#g' \
+ $< > $@
+
+logrotatecorosyncdir = ${LOGROTATEDIR}
+logrotatecorosync_DATA = corosync
+
+clean-local:
+ rm -f corosync
diff --git a/conf/logrotate/Makefile.in b/conf/logrotate/Makefile.in
new file mode 100644
index 0000000..8fea14b
--- /dev/null
+++ b/conf/logrotate/Makefile.in
@@ -0,0 +1,577 @@
+# Makefile.in generated by automake 1.13.4 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+# Copyright (c) 2009 Red Hat, Inc.
+#
+# Authors:Jan Friesse (jfriesse@redhat.com)
+# Andrew Beekhof
+# Steven Dake (sdake@redhat.com)
+#
+# This software licensed under BSD license, the text of which follows:
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# - Redistributions of source code must retain the above copyright notice,
+# this list of conditions and the following disclaimer.
+# - Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+# - Neither the name of the MontaVista Software, Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from this
+# software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+# THE POSSIBILITY OF SUCH DAMAGE.
+
+VPATH = @srcdir@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = conf/logrotate
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/lib/libcfg.verso $(top_srcdir)/lib/libcpg.verso \
+ $(top_srcdir)/lib/libquorum.verso \
+ $(top_srcdir)/lib/libsam.verso \
+ $(top_srcdir)/lib/libvotequorum.verso \
+ $(top_srcdir)/lib/libcmap.verso $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/include/corosync/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+SOURCES =
+DIST_SOURCES =
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+am__installdirs = "$(DESTDIR)$(logrotatecorosyncdir)"
+DATA = $(logrotatecorosync_DATA)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALLOCA = @ALLOCA@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUGTOOL = @AUGTOOL@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BASHPATH = @BASHPATH@
+BINDGEN = @BINDGEN@
+CARGO = @CARGO@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFG_SONAME = @CFG_SONAME@
+CFLAGS = @CFLAGS@
+CLIPPY = @CLIPPY@
+CMAP_SONAME = @CMAP_SONAME@
+COROSYSCONFDIR = @COROSYSCONFDIR@
+CPG_SONAME = @CPG_SONAME@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DBUS_CFLAGS = @DBUS_CFLAGS@
+DBUS_LIBS = @DBUS_LIBS@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DOT = @DOT@
+DOXYGEN = @DOXYGEN@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GREP = @GREP@
+GROFF = @GROFF@
+INITCONFIGDIR = @INITCONFIGDIR@
+INITDDIR = @INITDDIR@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBQB_CFLAGS = @LIBQB_CFLAGS@
+LIBQB_LIBS = @LIBQB_LIBS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LINT_FLAGS = @LINT_FLAGS@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LOGDIR = @LOGDIR@
+LOGROTATEDIR = @LOGROTATEDIR@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+QUORUM_SONAME = @QUORUM_SONAME@
+RANLIB = @RANLIB@
+RUSTC = @RUSTC@
+RUSTDOC = @RUSTDOC@
+RUSTFMT = @RUSTFMT@
+RUST_FLAGS = @RUST_FLAGS@
+RUST_TARGET_DIR = @RUST_TARGET_DIR@
+SAM_SONAME = @SAM_SONAME@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SNMPCONFIG = @SNMPCONFIG@
+SNMP_LIBS = @SNMP_LIBS@
+SOMAJOR = @SOMAJOR@
+SOMICRO = @SOMICRO@
+SOMINOR = @SOMINOR@
+SONAME = @SONAME@
+STRIP = @STRIP@
+SYSTEMDDIR = @SYSTEMDDIR@
+VERSCRIPT_LDFLAGS = @VERSCRIPT_LDFLAGS@
+VERSION = @VERSION@
+VOTEQUORUM_SONAME = @VOTEQUORUM_SONAME@
+WITH_LIST = @WITH_LIST@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+corosyncrustver = @corosyncrustver@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+knet_CFLAGS = @knet_CFLAGS@
+knet_LIBS = @knet_LIBS@
+libdir = @libdir@
+libexecdir = @libexecdir@
+libsystemd_CFLAGS = @libsystemd_CFLAGS@
+libsystemd_LIBS = @libsystemd_LIBS@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+nozzle_CFLAGS = @nozzle_CFLAGS@
+nozzle_LIBS = @nozzle_LIBS@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+statgrab_CFLAGS = @statgrab_CFLAGS@
+statgrab_LIBS = @statgrab_LIBS@
+statgrabge090_CFLAGS = @statgrabge090_CFLAGS@
+statgrabge090_LIBS = @statgrabge090_LIBS@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+MAINTAINERCLEANFILES = Makefile.in
+EXTRA_DIST = corosync-reopen.in corosync-copytruncate.in
+logrotatecorosyncdir = ${LOGROTATEDIR}
+logrotatecorosync_DATA = corosync
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign conf/logrotate/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign conf/logrotate/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+install-logrotatecorosyncDATA: $(logrotatecorosync_DATA)
+ @$(NORMAL_INSTALL)
+ @list='$(logrotatecorosync_DATA)'; test -n "$(logrotatecorosyncdir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(logrotatecorosyncdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(logrotatecorosyncdir)" || exit 1; \
+ fi; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(logrotatecorosyncdir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(logrotatecorosyncdir)" || exit $$?; \
+ done
+
+uninstall-logrotatecorosyncDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(logrotatecorosync_DATA)'; test -n "$(logrotatecorosyncdir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ dir='$(DESTDIR)$(logrotatecorosyncdir)'; $(am__uninstall_files_from_dir)
+tags TAGS:
+
+ctags CTAGS:
+
+cscope cscopelist:
+
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(DATA)
+installdirs:
+ for dir in "$(DESTDIR)$(logrotatecorosyncdir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+ -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-local mostlyclean-am
+
+distclean: distclean-am
+ -rm -f Makefile
+distclean-am: clean-am distclean-generic
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-logrotatecorosyncDATA
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-logrotatecorosyncDATA
+
+.MAKE: install-am install-strip
+
+.PHONY: all all-am check check-am clean clean-generic clean-libtool \
+ clean-local cscopelist-am ctags-am distclean distclean-generic \
+ distclean-libtool distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am \
+ install-logrotatecorosyncDATA install-man install-pdf \
+ install-pdf-am install-ps install-ps-am install-strip \
+ installcheck installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-generic \
+ mostlyclean-libtool pdf pdf-am ps ps-am tags-am uninstall \
+ uninstall-am uninstall-logrotatecorosyncDATA
+
+
+corosync: corosync-copytruncate.in
+ $(SED) -e 's#@''LOGDIR@#${LOGDIR}#g' \
+ $< > $@
+
+clean-local:
+ rm -f corosync
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/conf/logrotate/corosync-copytruncate.in b/conf/logrotate/corosync-copytruncate.in
new file mode 100644
index 0000000..cba17b0
--- /dev/null
+++ b/conf/logrotate/corosync-copytruncate.in
@@ -0,0 +1,9 @@
+@LOGDIR@/corosync.log {
+ missingok
+ compress
+ copytruncate
+ daily
+ rotate 31
+ minsize 2048
+ notifempty
+}
diff --git a/conf/logrotate/corosync-reopen.in b/conf/logrotate/corosync-reopen.in
new file mode 100644
index 0000000..730fb74
--- /dev/null
+++ b/conf/logrotate/corosync-reopen.in
@@ -0,0 +1,17 @@
+# This logrotate method has two main problems and it's kept only for reference:
+# 1. It does fail when corosync is not running (solvable by adding "|| true")
+# 2. If (for some reason) cfgtool -L fails, logrotate fails and corosync keeps
+# logging into old file. Added "|| true" makes situation even worse
+# because logrotate removes file but corosync keeps logging into it.
+@LOGDIR@/corosync.log {
+ missingok
+ compress
+ daily
+ rotate 31
+ minsize 2048
+ notifempty
+ nocreate
+ postrotate
+ @SBINDIR@/corosync-cfgtool -L
+ endscript
+}
diff --git a/conf/xml2conf.xsl b/conf/xml2conf.xsl
new file mode 100644
index 0000000..c140d68
--- /dev/null
+++ b/conf/xml2conf.xsl
@@ -0,0 +1,94 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+ Copyright (c) 2011 Red Hat, Inc.
+
+ All rights reserved.
+
+ Author: Jan Friesse (jfriesse@redhat.com)
+
+ This software licensed under BSD license, the text of which follows:
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ - Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ - Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+ - Neither the name of the Red Hat, Inc. nor the names of its
+ contributors may be used to endorse or promote products derived from this
+ software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ THE POSSIBILITY OF SUCH DAMAGE.
+-->
+
+<xsl:stylesheet version="1.0"
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:date="http://exslt.org/dates-and-times" extension-element-prefixes="date">
+
+<xsl:output method="text" />
+<xsl:strip-space elements="*" />
+<xsl:param name="inputfile"/>
+
+<xsl:variable name='newline'><xsl:text>
+</xsl:text></xsl:variable>
+
+<xsl:template match="/corosync">
+ <xsl:text># Corosync configuration file generated from </xsl:text>
+ <xsl:value-of select="$inputfile"/><xsl:text> at </xsl:text>
+ <xsl:value-of select="date:date-time()"/>
+
+ <xsl:apply-templates select="@*"/>
+ <xsl:apply-templates />
+ <xsl:value-of select="$newline" />
+</xsl:template>
+
+<xsl:template match="/corosync//*">
+ <xsl:value-of select="$newline" />
+ <xsl:value-of select="$newline" />
+ <xsl:call-template name="indent">
+ <xsl:with-param name="depth" select="count(ancestor::*) - 1"/>
+ </xsl:call-template>
+ <xsl:value-of select="name()"/> {<xsl:apply-templates select="@*"/>
+ <xsl:apply-templates />
+ <xsl:value-of select="$newline" />
+ <xsl:call-template name="indent">
+ <xsl:with-param name="depth" select="count(ancestor::*) - 1"/>
+ </xsl:call-template>
+ <xsl:text>}</xsl:text>
+</xsl:template>
+
+<xsl:template match="@*">
+ <xsl:value-of select="$newline" />
+ <xsl:call-template name="indent">
+ <xsl:with-param name="depth" select="count(ancestor::*) - 1"/>
+ </xsl:call-template>
+ <xsl:value-of select="name()"/><xsl:text>: </xsl:text><xsl:value-of select="."/>
+</xsl:template>
+
+<xsl:template match="text()">
+</xsl:template>
+
+<xsl:template name="indent">
+ <xsl:param name="depth"/>
+ <xsl:if test="$depth &gt; 0">
+ <xsl:text> </xsl:text>
+ <xsl:call-template name="indent">
+ <xsl:with-param name="depth" select="$depth - 1"/>
+ </xsl:call-template>
+ </xsl:if>
+</xsl:template>
+
+</xsl:stylesheet>
diff --git a/config.guess b/config.guess
new file mode 100755
index 0000000..b79252d
--- /dev/null
+++ b/config.guess
@@ -0,0 +1,1558 @@
+#! /bin/sh
+# Attempt to guess a canonical system name.
+# Copyright 1992-2013 Free Software Foundation, Inc.
+
+timestamp='2013-06-10'
+
+# This file 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 3 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, see <http://www.gnu.org/licenses/>.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that
+# program. This Exception is an additional permission under section 7
+# of the GNU General Public License, version 3 ("GPLv3").
+#
+# Originally written by Per Bothner.
+#
+# You can get the latest version of this script from:
+# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
+#
+# Please send patches with a ChangeLog entry to config-patches@gnu.org.
+
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION]
+
+Output the configuration name of the system \`$me' is run on.
+
+Operation modes:
+ -h, --help print this help, then exit
+ -t, --time-stamp print date of last modification, then exit
+ -v, --version print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.guess ($timestamp)
+
+Originally written by Per Bothner.
+Copyright 1992-2013 Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions. There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+ case $1 in
+ --time-stamp | --time* | -t )
+ echo "$timestamp" ; exit ;;
+ --version | -v )
+ echo "$version" ; exit ;;
+ --help | --h* | -h )
+ echo "$usage"; exit ;;
+ -- ) # Stop option processing
+ shift; break ;;
+ - ) # Use stdin as input.
+ break ;;
+ -* )
+ echo "$me: invalid option $1$help" >&2
+ exit 1 ;;
+ * )
+ break ;;
+ esac
+done
+
+if test $# != 0; then
+ echo "$me: too many arguments$help" >&2
+ exit 1
+fi
+
+trap 'exit 1' 1 2 15
+
+# CC_FOR_BUILD -- compiler used by this script. Note that the use of a
+# compiler to aid in system detection is discouraged as it requires
+# temporary files to be created and, as you can see below, it is a
+# headache to deal with in a portable fashion.
+
+# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
+# use `HOST_CC' if defined, but it is deprecated.
+
+# Portable tmp directory creation inspired by the Autoconf team.
+
+set_cc_for_build='
+trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
+trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
+: ${TMPDIR=/tmp} ;
+ { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
+ { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
+ { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } ||
+ { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
+dummy=$tmp/dummy ;
+tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
+case $CC_FOR_BUILD,$HOST_CC,$CC in
+ ,,) echo "int x;" > $dummy.c ;
+ for c in cc gcc c89 c99 ; do
+ if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then
+ CC_FOR_BUILD="$c"; break ;
+ fi ;
+ done ;
+ if test x"$CC_FOR_BUILD" = x ; then
+ CC_FOR_BUILD=no_compiler_found ;
+ fi
+ ;;
+ ,,*) CC_FOR_BUILD=$CC ;;
+ ,*,*) CC_FOR_BUILD=$HOST_CC ;;
+esac ; set_cc_for_build= ;'
+
+# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
+# (ghazi@noc.rutgers.edu 1994-08-24)
+if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
+ PATH=$PATH:/.attbin ; export PATH
+fi
+
+UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
+UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
+UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
+UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
+
+case "${UNAME_SYSTEM}" in
+Linux|GNU|GNU/*)
+ # If the system lacks a compiler, then just pick glibc.
+ # We could probably try harder.
+ LIBC=gnu
+
+ eval $set_cc_for_build
+ cat <<-EOF > $dummy.c
+ #include <features.h>
+ #if defined(__UCLIBC__)
+ LIBC=uclibc
+ #elif defined(__dietlibc__)
+ LIBC=dietlibc
+ #else
+ LIBC=gnu
+ #endif
+ EOF
+ eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'`
+ ;;
+esac
+
+# Note: order is significant - the case branches are not exclusive.
+
+case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+ *:NetBSD:*:*)
+ # NetBSD (nbsd) targets should (where applicable) match one or
+ # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*,
+ # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently
+ # switched to ELF, *-*-netbsd* would select the old
+ # object file format. This provides both forward
+ # compatibility and a consistent mechanism for selecting the
+ # object file format.
+ #
+ # Note: NetBSD doesn't particularly care about the vendor
+ # portion of the name. We always set it to "unknown".
+ sysctl="sysctl -n hw.machine_arch"
+ UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
+ /usr/sbin/$sysctl 2>/dev/null || echo unknown)`
+ case "${UNAME_MACHINE_ARCH}" in
+ armeb) machine=armeb-unknown ;;
+ arm*) machine=arm-unknown ;;
+ sh3el) machine=shl-unknown ;;
+ sh3eb) machine=sh-unknown ;;
+ sh5el) machine=sh5le-unknown ;;
+ *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
+ esac
+ # The Operating System including object format, if it has switched
+ # to ELF recently, or will in the future.
+ case "${UNAME_MACHINE_ARCH}" in
+ arm*|i386|m68k|ns32k|sh3*|sparc|vax)
+ eval $set_cc_for_build
+ if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
+ | grep -q __ELF__
+ then
+ # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
+ # Return netbsd for either. FIX?
+ os=netbsd
+ else
+ os=netbsdelf
+ fi
+ ;;
+ *)
+ os=netbsd
+ ;;
+ esac
+ # The OS release
+ # Debian GNU/NetBSD machines have a different userland, and
+ # thus, need a distinct triplet. However, they do not need
+ # kernel version information, so it can be replaced with a
+ # suitable tag, in the style of linux-gnu.
+ case "${UNAME_VERSION}" in
+ Debian*)
+ release='-gnu'
+ ;;
+ *)
+ release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+ ;;
+ esac
+ # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
+ # contains redundant information, the shorter form:
+ # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
+ echo "${machine}-${os}${release}"
+ exit ;;
+ *:Bitrig:*:*)
+ UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'`
+ echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE}
+ exit ;;
+ *:OpenBSD:*:*)
+ UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
+ echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
+ exit ;;
+ *:ekkoBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
+ exit ;;
+ *:SolidBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE}
+ exit ;;
+ macppc:MirBSD:*:*)
+ echo powerpc-unknown-mirbsd${UNAME_RELEASE}
+ exit ;;
+ *:MirBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
+ exit ;;
+ alpha:OSF1:*:*)
+ case $UNAME_RELEASE in
+ *4.0)
+ UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
+ ;;
+ *5.*)
+ UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
+ ;;
+ esac
+ # According to Compaq, /usr/sbin/psrinfo has been available on
+ # OSF/1 and Tru64 systems produced since 1995. I hope that
+ # covers most systems running today. This code pipes the CPU
+ # types through head -n 1, so we only detect the type of CPU 0.
+ ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1`
+ case "$ALPHA_CPU_TYPE" in
+ "EV4 (21064)")
+ UNAME_MACHINE="alpha" ;;
+ "EV4.5 (21064)")
+ UNAME_MACHINE="alpha" ;;
+ "LCA4 (21066/21068)")
+ UNAME_MACHINE="alpha" ;;
+ "EV5 (21164)")
+ UNAME_MACHINE="alphaev5" ;;
+ "EV5.6 (21164A)")
+ UNAME_MACHINE="alphaev56" ;;
+ "EV5.6 (21164PC)")
+ UNAME_MACHINE="alphapca56" ;;
+ "EV5.7 (21164PC)")
+ UNAME_MACHINE="alphapca57" ;;
+ "EV6 (21264)")
+ UNAME_MACHINE="alphaev6" ;;
+ "EV6.7 (21264A)")
+ UNAME_MACHINE="alphaev67" ;;
+ "EV6.8CB (21264C)")
+ UNAME_MACHINE="alphaev68" ;;
+ "EV6.8AL (21264B)")
+ UNAME_MACHINE="alphaev68" ;;
+ "EV6.8CX (21264D)")
+ UNAME_MACHINE="alphaev68" ;;
+ "EV6.9A (21264/EV69A)")
+ UNAME_MACHINE="alphaev69" ;;
+ "EV7 (21364)")
+ UNAME_MACHINE="alphaev7" ;;
+ "EV7.9 (21364A)")
+ UNAME_MACHINE="alphaev79" ;;
+ esac
+ # A Pn.n version is a patched version.
+ # A Vn.n version is a released version.
+ # A Tn.n version is a released field test version.
+ # A Xn.n version is an unreleased experimental baselevel.
+ # 1.2 uses "1.2" for uname -r.
+ echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+ # Reset EXIT trap before exiting to avoid spurious non-zero exit code.
+ exitcode=$?
+ trap '' 0
+ exit $exitcode ;;
+ Alpha\ *:Windows_NT*:*)
+ # How do we know it's Interix rather than the generic POSIX subsystem?
+ # Should we change UNAME_MACHINE based on the output of uname instead
+ # of the specific Alpha model?
+ echo alpha-pc-interix
+ exit ;;
+ 21064:Windows_NT:50:3)
+ echo alpha-dec-winnt3.5
+ exit ;;
+ Amiga*:UNIX_System_V:4.0:*)
+ echo m68k-unknown-sysv4
+ exit ;;
+ *:[Aa]miga[Oo][Ss]:*:*)
+ echo ${UNAME_MACHINE}-unknown-amigaos
+ exit ;;
+ *:[Mm]orph[Oo][Ss]:*:*)
+ echo ${UNAME_MACHINE}-unknown-morphos
+ exit ;;
+ *:OS/390:*:*)
+ echo i370-ibm-openedition
+ exit ;;
+ *:z/VM:*:*)
+ echo s390-ibm-zvmoe
+ exit ;;
+ *:OS400:*:*)
+ echo powerpc-ibm-os400
+ exit ;;
+ arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
+ echo arm-acorn-riscix${UNAME_RELEASE}
+ exit ;;
+ arm*:riscos:*:*|arm*:RISCOS:*:*)
+ echo arm-unknown-riscos
+ exit ;;
+ SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
+ echo hppa1.1-hitachi-hiuxmpp
+ exit ;;
+ Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
+ # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
+ if test "`(/bin/universe) 2>/dev/null`" = att ; then
+ echo pyramid-pyramid-sysv3
+ else
+ echo pyramid-pyramid-bsd
+ fi
+ exit ;;
+ NILE*:*:*:dcosx)
+ echo pyramid-pyramid-svr4
+ exit ;;
+ DRS?6000:unix:4.0:6*)
+ echo sparc-icl-nx6
+ exit ;;
+ DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*)
+ case `/usr/bin/uname -p` in
+ sparc) echo sparc-icl-nx7; exit ;;
+ esac ;;
+ s390x:SunOS:*:*)
+ echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ sun4H:SunOS:5.*:*)
+ echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
+ echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*)
+ echo i386-pc-auroraux${UNAME_RELEASE}
+ exit ;;
+ i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
+ eval $set_cc_for_build
+ SUN_ARCH="i386"
+ # If there is a compiler, see if it is configured for 64-bit objects.
+ # Note that the Sun cc does not turn __LP64__ into 1 like gcc does.
+ # This test works for both compilers.
+ if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+ if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \
+ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+ grep IS_64BIT_ARCH >/dev/null
+ then
+ SUN_ARCH="x86_64"
+ fi
+ fi
+ echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ sun4*:SunOS:6*:*)
+ # According to config.sub, this is the proper way to canonicalize
+ # SunOS6. Hard to guess exactly what SunOS6 will be like, but
+ # it's likely to be more like Solaris than SunOS4.
+ echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ sun4*:SunOS:*:*)
+ case "`/usr/bin/arch -k`" in
+ Series*|S4*)
+ UNAME_RELEASE=`uname -v`
+ ;;
+ esac
+ # Japanese Language versions have a version number like `4.1.3-JL'.
+ echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
+ exit ;;
+ sun3*:SunOS:*:*)
+ echo m68k-sun-sunos${UNAME_RELEASE}
+ exit ;;
+ sun*:*:4.2BSD:*)
+ UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
+ test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
+ case "`/bin/arch`" in
+ sun3)
+ echo m68k-sun-sunos${UNAME_RELEASE}
+ ;;
+ sun4)
+ echo sparc-sun-sunos${UNAME_RELEASE}
+ ;;
+ esac
+ exit ;;
+ aushp:SunOS:*:*)
+ echo sparc-auspex-sunos${UNAME_RELEASE}
+ exit ;;
+ # The situation for MiNT is a little confusing. The machine name
+ # can be virtually everything (everything which is not
+ # "atarist" or "atariste" at least should have a processor
+ # > m68000). The system name ranges from "MiNT" over "FreeMiNT"
+ # to the lowercase version "mint" (or "freemint"). Finally
+ # the system name "TOS" denotes a system which is actually not
+ # MiNT. But MiNT is downward compatible to TOS, so this should
+ # be no problem.
+ atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
+ echo m68k-atari-mint${UNAME_RELEASE}
+ exit ;;
+ atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
+ echo m68k-atari-mint${UNAME_RELEASE}
+ exit ;;
+ *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
+ echo m68k-atari-mint${UNAME_RELEASE}
+ exit ;;
+ milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
+ echo m68k-milan-mint${UNAME_RELEASE}
+ exit ;;
+ hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
+ echo m68k-hades-mint${UNAME_RELEASE}
+ exit ;;
+ *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
+ echo m68k-unknown-mint${UNAME_RELEASE}
+ exit ;;
+ m68k:machten:*:*)
+ echo m68k-apple-machten${UNAME_RELEASE}
+ exit ;;
+ powerpc:machten:*:*)
+ echo powerpc-apple-machten${UNAME_RELEASE}
+ exit ;;
+ RISC*:Mach:*:*)
+ echo mips-dec-mach_bsd4.3
+ exit ;;
+ RISC*:ULTRIX:*:*)
+ echo mips-dec-ultrix${UNAME_RELEASE}
+ exit ;;
+ VAX*:ULTRIX*:*:*)
+ echo vax-dec-ultrix${UNAME_RELEASE}
+ exit ;;
+ 2020:CLIX:*:* | 2430:CLIX:*:*)
+ echo clipper-intergraph-clix${UNAME_RELEASE}
+ exit ;;
+ mips:*:*:UMIPS | mips:*:*:RISCos)
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+#ifdef __cplusplus
+#include <stdio.h> /* for printf() prototype */
+ int main (int argc, char *argv[]) {
+#else
+ int main (argc, argv) int argc; char *argv[]; {
+#endif
+ #if defined (host_mips) && defined (MIPSEB)
+ #if defined (SYSTYPE_SYSV)
+ printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
+ #endif
+ #if defined (SYSTYPE_SVR4)
+ printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
+ #endif
+ #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
+ printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
+ #endif
+ #endif
+ exit (-1);
+ }
+EOF
+ $CC_FOR_BUILD -o $dummy $dummy.c &&
+ dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` &&
+ SYSTEM_NAME=`$dummy $dummyarg` &&
+ { echo "$SYSTEM_NAME"; exit; }
+ echo mips-mips-riscos${UNAME_RELEASE}
+ exit ;;
+ Motorola:PowerMAX_OS:*:*)
+ echo powerpc-motorola-powermax
+ exit ;;
+ Motorola:*:4.3:PL8-*)
+ echo powerpc-harris-powermax
+ exit ;;
+ Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)
+ echo powerpc-harris-powermax
+ exit ;;
+ Night_Hawk:Power_UNIX:*:*)
+ echo powerpc-harris-powerunix
+ exit ;;
+ m88k:CX/UX:7*:*)
+ echo m88k-harris-cxux7
+ exit ;;
+ m88k:*:4*:R4*)
+ echo m88k-motorola-sysv4
+ exit ;;
+ m88k:*:3*:R3*)
+ echo m88k-motorola-sysv3
+ exit ;;
+ AViiON:dgux:*:*)
+ # DG/UX returns AViiON for all architectures
+ UNAME_PROCESSOR=`/usr/bin/uname -p`
+ if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
+ then
+ if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
+ [ ${TARGET_BINARY_INTERFACE}x = x ]
+ then
+ echo m88k-dg-dgux${UNAME_RELEASE}
+ else
+ echo m88k-dg-dguxbcs${UNAME_RELEASE}
+ fi
+ else
+ echo i586-dg-dgux${UNAME_RELEASE}
+ fi
+ exit ;;
+ M88*:DolphinOS:*:*) # DolphinOS (SVR3)
+ echo m88k-dolphin-sysv3
+ exit ;;
+ M88*:*:R3*:*)
+ # Delta 88k system running SVR3
+ echo m88k-motorola-sysv3
+ exit ;;
+ XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
+ echo m88k-tektronix-sysv3
+ exit ;;
+ Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
+ echo m68k-tektronix-bsd
+ exit ;;
+ *:IRIX*:*:*)
+ echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
+ exit ;;
+ ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
+ echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id
+ exit ;; # Note that: echo "'`uname -s`'" gives 'AIX '
+ i*86:AIX:*:*)
+ echo i386-ibm-aix
+ exit ;;
+ ia64:AIX:*:*)
+ if [ -x /usr/bin/oslevel ] ; then
+ IBM_REV=`/usr/bin/oslevel`
+ else
+ IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+ fi
+ echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
+ exit ;;
+ *:AIX:2:3)
+ if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #include <sys/systemcfg.h>
+
+ main()
+ {
+ if (!__power_pc())
+ exit(1);
+ puts("powerpc-ibm-aix3.2.5");
+ exit(0);
+ }
+EOF
+ if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy`
+ then
+ echo "$SYSTEM_NAME"
+ else
+ echo rs6000-ibm-aix3.2.5
+ fi
+ elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
+ echo rs6000-ibm-aix3.2.4
+ else
+ echo rs6000-ibm-aix3.2
+ fi
+ exit ;;
+ *:AIX:*:[4567])
+ IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
+ if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
+ IBM_ARCH=rs6000
+ else
+ IBM_ARCH=powerpc
+ fi
+ if [ -x /usr/bin/oslevel ] ; then
+ IBM_REV=`/usr/bin/oslevel`
+ else
+ IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+ fi
+ echo ${IBM_ARCH}-ibm-aix${IBM_REV}
+ exit ;;
+ *:AIX:*:*)
+ echo rs6000-ibm-aix
+ exit ;;
+ ibmrt:4.4BSD:*|romp-ibm:BSD:*)
+ echo romp-ibm-bsd4.4
+ exit ;;
+ ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and
+ echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to
+ exit ;; # report: romp-ibm BSD 4.3
+ *:BOSX:*:*)
+ echo rs6000-bull-bosx
+ exit ;;
+ DPX/2?00:B.O.S.:*:*)
+ echo m68k-bull-sysv3
+ exit ;;
+ 9000/[34]??:4.3bsd:1.*:*)
+ echo m68k-hp-bsd
+ exit ;;
+ hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
+ echo m68k-hp-bsd4.4
+ exit ;;
+ 9000/[34678]??:HP-UX:*:*)
+ HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+ case "${UNAME_MACHINE}" in
+ 9000/31? ) HP_ARCH=m68000 ;;
+ 9000/[34]?? ) HP_ARCH=m68k ;;
+ 9000/[678][0-9][0-9])
+ if [ -x /usr/bin/getconf ]; then
+ sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
+ sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
+ case "${sc_cpu_version}" in
+ 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
+ 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
+ 532) # CPU_PA_RISC2_0
+ case "${sc_kernel_bits}" in
+ 32) HP_ARCH="hppa2.0n" ;;
+ 64) HP_ARCH="hppa2.0w" ;;
+ '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20
+ esac ;;
+ esac
+ fi
+ if [ "${HP_ARCH}" = "" ]; then
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+
+ #define _HPUX_SOURCE
+ #include <stdlib.h>
+ #include <unistd.h>
+
+ int main ()
+ {
+ #if defined(_SC_KERNEL_BITS)
+ long bits = sysconf(_SC_KERNEL_BITS);
+ #endif
+ long cpu = sysconf (_SC_CPU_VERSION);
+
+ switch (cpu)
+ {
+ case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
+ case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
+ case CPU_PA_RISC2_0:
+ #if defined(_SC_KERNEL_BITS)
+ switch (bits)
+ {
+ case 64: puts ("hppa2.0w"); break;
+ case 32: puts ("hppa2.0n"); break;
+ default: puts ("hppa2.0"); break;
+ } break;
+ #else /* !defined(_SC_KERNEL_BITS) */
+ puts ("hppa2.0"); break;
+ #endif
+ default: puts ("hppa1.0"); break;
+ }
+ exit (0);
+ }
+EOF
+ (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
+ test -z "$HP_ARCH" && HP_ARCH=hppa
+ fi ;;
+ esac
+ if [ ${HP_ARCH} = "hppa2.0w" ]
+ then
+ eval $set_cc_for_build
+
+ # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating
+ # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler
+ # generating 64-bit code. GNU and HP use different nomenclature:
+ #
+ # $ CC_FOR_BUILD=cc ./config.guess
+ # => hppa2.0w-hp-hpux11.23
+ # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess
+ # => hppa64-hp-hpux11.23
+
+ if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) |
+ grep -q __LP64__
+ then
+ HP_ARCH="hppa2.0w"
+ else
+ HP_ARCH="hppa64"
+ fi
+ fi
+ echo ${HP_ARCH}-hp-hpux${HPUX_REV}
+ exit ;;
+ ia64:HP-UX:*:*)
+ HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+ echo ia64-hp-hpux${HPUX_REV}
+ exit ;;
+ 3050*:HI-UX:*:*)
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #include <unistd.h>
+ int
+ main ()
+ {
+ long cpu = sysconf (_SC_CPU_VERSION);
+ /* The order matters, because CPU_IS_HP_MC68K erroneously returns
+ true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct
+ results, however. */
+ if (CPU_IS_PA_RISC (cpu))
+ {
+ switch (cpu)
+ {
+ case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
+ case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
+ case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
+ default: puts ("hppa-hitachi-hiuxwe2"); break;
+ }
+ }
+ else if (CPU_IS_HP_MC68K (cpu))
+ puts ("m68k-hitachi-hiuxwe2");
+ else puts ("unknown-hitachi-hiuxwe2");
+ exit (0);
+ }
+EOF
+ $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` &&
+ { echo "$SYSTEM_NAME"; exit; }
+ echo unknown-hitachi-hiuxwe2
+ exit ;;
+ 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
+ echo hppa1.1-hp-bsd
+ exit ;;
+ 9000/8??:4.3bsd:*:*)
+ echo hppa1.0-hp-bsd
+ exit ;;
+ *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
+ echo hppa1.0-hp-mpeix
+ exit ;;
+ hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
+ echo hppa1.1-hp-osf
+ exit ;;
+ hp8??:OSF1:*:*)
+ echo hppa1.0-hp-osf
+ exit ;;
+ i*86:OSF1:*:*)
+ if [ -x /usr/sbin/sysversion ] ; then
+ echo ${UNAME_MACHINE}-unknown-osf1mk
+ else
+ echo ${UNAME_MACHINE}-unknown-osf1
+ fi
+ exit ;;
+ parisc*:Lites*:*:*)
+ echo hppa1.1-hp-lites
+ exit ;;
+ C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
+ echo c1-convex-bsd
+ exit ;;
+ C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
+ if getsysinfo -f scalar_acc
+ then echo c32-convex-bsd
+ else echo c2-convex-bsd
+ fi
+ exit ;;
+ C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
+ echo c34-convex-bsd
+ exit ;;
+ C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
+ echo c38-convex-bsd
+ exit ;;
+ C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
+ echo c4-convex-bsd
+ exit ;;
+ CRAY*Y-MP:*:*:*)
+ echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ CRAY*[A-Z]90:*:*:*)
+ echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
+ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
+ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
+ -e 's/\.[^.]*$/.X/'
+ exit ;;
+ CRAY*TS:*:*:*)
+ echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ CRAY*T3E:*:*:*)
+ echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ CRAY*SV1:*:*:*)
+ echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ *:UNICOS/mp:*:*)
+ echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
+ FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+ FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+ FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+ echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+ exit ;;
+ 5000:UNIX_System_V:4.*:*)
+ FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+ FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
+ echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+ exit ;;
+ i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
+ echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
+ exit ;;
+ sparc*:BSD/OS:*:*)
+ echo sparc-unknown-bsdi${UNAME_RELEASE}
+ exit ;;
+ *:BSD/OS:*:*)
+ echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
+ exit ;;
+ *:FreeBSD:*:*)
+ UNAME_PROCESSOR=`/usr/bin/uname -p`
+ case ${UNAME_PROCESSOR} in
+ amd64)
+ echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+ *)
+ echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+ esac
+ exit ;;
+ i*:CYGWIN*:*)
+ echo ${UNAME_MACHINE}-pc-cygwin
+ exit ;;
+ *:MINGW64*:*)
+ echo ${UNAME_MACHINE}-pc-mingw64
+ exit ;;
+ *:MINGW*:*)
+ echo ${UNAME_MACHINE}-pc-mingw32
+ exit ;;
+ i*:MSYS*:*)
+ echo ${UNAME_MACHINE}-pc-msys
+ exit ;;
+ i*:windows32*:*)
+ # uname -m includes "-pc" on this system.
+ echo ${UNAME_MACHINE}-mingw32
+ exit ;;
+ i*:PW*:*)
+ echo ${UNAME_MACHINE}-pc-pw32
+ exit ;;
+ *:Interix*:*)
+ case ${UNAME_MACHINE} in
+ x86)
+ echo i586-pc-interix${UNAME_RELEASE}
+ exit ;;
+ authenticamd | genuineintel | EM64T)
+ echo x86_64-unknown-interix${UNAME_RELEASE}
+ exit ;;
+ IA64)
+ echo ia64-unknown-interix${UNAME_RELEASE}
+ exit ;;
+ esac ;;
+ [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
+ echo i${UNAME_MACHINE}-pc-mks
+ exit ;;
+ 8664:Windows_NT:*)
+ echo x86_64-pc-mks
+ exit ;;
+ i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
+ # How do we know it's Interix rather than the generic POSIX subsystem?
+ # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
+ # UNAME_MACHINE based on the output of uname instead of i386?
+ echo i586-pc-interix
+ exit ;;
+ i*:UWIN*:*)
+ echo ${UNAME_MACHINE}-pc-uwin
+ exit ;;
+ amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*)
+ echo x86_64-unknown-cygwin
+ exit ;;
+ p*:CYGWIN*:*)
+ echo powerpcle-unknown-cygwin
+ exit ;;
+ prep*:SunOS:5.*:*)
+ echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ *:GNU:*:*)
+ # the GNU system
+ echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+ exit ;;
+ *:GNU/*:*:*)
+ # other systems with GNU libc and userland
+ echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC}
+ exit ;;
+ i*86:Minix:*:*)
+ echo ${UNAME_MACHINE}-pc-minix
+ exit ;;
+ aarch64:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ aarch64_be:Linux:*:*)
+ UNAME_MACHINE=aarch64_be
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ alpha:Linux:*:*)
+ case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
+ EV5) UNAME_MACHINE=alphaev5 ;;
+ EV56) UNAME_MACHINE=alphaev56 ;;
+ PCA56) UNAME_MACHINE=alphapca56 ;;
+ PCA57) UNAME_MACHINE=alphapca56 ;;
+ EV6) UNAME_MACHINE=alphaev6 ;;
+ EV67) UNAME_MACHINE=alphaev67 ;;
+ EV68*) UNAME_MACHINE=alphaev68 ;;
+ esac
+ objdump --private-headers /bin/sh | grep -q ld.so.1
+ if test "$?" = 0 ; then LIBC="gnulibc1" ; fi
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ arc:Linux:*:* | arceb:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ arm*:Linux:*:*)
+ eval $set_cc_for_build
+ if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
+ | grep -q __ARM_EABI__
+ then
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ else
+ if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
+ | grep -q __ARM_PCS_VFP
+ then
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi
+ else
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf
+ fi
+ fi
+ exit ;;
+ avr32*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ cris:Linux:*:*)
+ echo ${UNAME_MACHINE}-axis-linux-${LIBC}
+ exit ;;
+ crisv32:Linux:*:*)
+ echo ${UNAME_MACHINE}-axis-linux-${LIBC}
+ exit ;;
+ frv:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ hexagon:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ i*86:Linux:*:*)
+ echo ${UNAME_MACHINE}-pc-linux-${LIBC}
+ exit ;;
+ ia64:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ m32r*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ m68*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ mips:Linux:*:* | mips64:Linux:*:*)
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #undef CPU
+ #undef ${UNAME_MACHINE}
+ #undef ${UNAME_MACHINE}el
+ #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+ CPU=${UNAME_MACHINE}el
+ #else
+ #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+ CPU=${UNAME_MACHINE}
+ #else
+ CPU=
+ #endif
+ #endif
+EOF
+ eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'`
+ test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; }
+ ;;
+ or1k:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ or32:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ padre:Linux:*:*)
+ echo sparc-unknown-linux-${LIBC}
+ exit ;;
+ parisc64:Linux:*:* | hppa64:Linux:*:*)
+ echo hppa64-unknown-linux-${LIBC}
+ exit ;;
+ parisc:Linux:*:* | hppa:Linux:*:*)
+ # Look for CPU level
+ case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
+ PA7*) echo hppa1.1-unknown-linux-${LIBC} ;;
+ PA8*) echo hppa2.0-unknown-linux-${LIBC} ;;
+ *) echo hppa-unknown-linux-${LIBC} ;;
+ esac
+ exit ;;
+ ppc64:Linux:*:*)
+ echo powerpc64-unknown-linux-${LIBC}
+ exit ;;
+ ppc:Linux:*:*)
+ echo powerpc-unknown-linux-${LIBC}
+ exit ;;
+ ppc64le:Linux:*:*)
+ echo powerpc64le-unknown-linux-${LIBC}
+ exit ;;
+ ppcle:Linux:*:*)
+ echo powerpcle-unknown-linux-${LIBC}
+ exit ;;
+ s390:Linux:*:* | s390x:Linux:*:*)
+ echo ${UNAME_MACHINE}-ibm-linux-${LIBC}
+ exit ;;
+ sh64*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ sh*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ sparc:Linux:*:* | sparc64:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ tile*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ vax:Linux:*:*)
+ echo ${UNAME_MACHINE}-dec-linux-${LIBC}
+ exit ;;
+ x86_64:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ xtensa*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ i*86:DYNIX/ptx:4*:*)
+ # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
+ # earlier versions are messed up and put the nodename in both
+ # sysname and nodename.
+ echo i386-sequent-sysv4
+ exit ;;
+ i*86:UNIX_SV:4.2MP:2.*)
+ # Unixware is an offshoot of SVR4, but it has its own version
+ # number series starting with 2...
+ # I am not positive that other SVR4 systems won't match this,
+ # I just have to hope. -- rms.
+ # Use sysv4.2uw... so that sysv4* matches it.
+ echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
+ exit ;;
+ i*86:OS/2:*:*)
+ # If we were able to find `uname', then EMX Unix compatibility
+ # is probably installed.
+ echo ${UNAME_MACHINE}-pc-os2-emx
+ exit ;;
+ i*86:XTS-300:*:STOP)
+ echo ${UNAME_MACHINE}-unknown-stop
+ exit ;;
+ i*86:atheos:*:*)
+ echo ${UNAME_MACHINE}-unknown-atheos
+ exit ;;
+ i*86:syllable:*:*)
+ echo ${UNAME_MACHINE}-pc-syllable
+ exit ;;
+ i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*)
+ echo i386-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ i*86:*DOS:*:*)
+ echo ${UNAME_MACHINE}-pc-msdosdjgpp
+ exit ;;
+ i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
+ UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
+ if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
+ echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
+ else
+ echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
+ fi
+ exit ;;
+ i*86:*:5:[678]*)
+ # UnixWare 7.x, OpenUNIX and OpenServer 6.
+ case `/bin/uname -X | grep "^Machine"` in
+ *486*) UNAME_MACHINE=i486 ;;
+ *Pentium) UNAME_MACHINE=i586 ;;
+ *Pent*|*Celeron) UNAME_MACHINE=i686 ;;
+ esac
+ echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
+ exit ;;
+ i*86:*:3.2:*)
+ if test -f /usr/options/cb.name; then
+ UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
+ echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
+ elif /bin/uname -X 2>/dev/null >/dev/null ; then
+ UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
+ (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
+ (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \
+ && UNAME_MACHINE=i586
+ (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \
+ && UNAME_MACHINE=i686
+ (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
+ && UNAME_MACHINE=i686
+ echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
+ else
+ echo ${UNAME_MACHINE}-pc-sysv32
+ fi
+ exit ;;
+ pc:*:*:*)
+ # Left here for compatibility:
+ # uname -m prints for DJGPP always 'pc', but it prints nothing about
+ # the processor, so we play safe by assuming i586.
+ # Note: whatever this is, it MUST be the same as what config.sub
+ # prints for the "djgpp" host, or else GDB configury will decide that
+ # this is a cross-build.
+ echo i586-pc-msdosdjgpp
+ exit ;;
+ Intel:Mach:3*:*)
+ echo i386-pc-mach3
+ exit ;;
+ paragon:*:*:*)
+ echo i860-intel-osf1
+ exit ;;
+ i860:*:4.*:*) # i860-SVR4
+ if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
+ echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
+ else # Add other i860-SVR4 vendors below as they are discovered.
+ echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4
+ fi
+ exit ;;
+ mini*:CTIX:SYS*5:*)
+ # "miniframe"
+ echo m68010-convergent-sysv
+ exit ;;
+ mc68k:UNIX:SYSTEM5:3.51m)
+ echo m68k-convergent-sysv
+ exit ;;
+ M680?0:D-NIX:5.3:*)
+ echo m68k-diab-dnix
+ exit ;;
+ M68*:*:R3V[5678]*:*)
+ test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;;
+ 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0)
+ OS_REL=''
+ test -r /etc/.relid \
+ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
+ /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
+ 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && { echo i486-ncr-sysv4; exit; } ;;
+ NCR*:*:4.2:* | MPRAS*:*:4.2:*)
+ OS_REL='.3'
+ test -r /etc/.relid \
+ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
+ /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+ && { echo i586-ncr-sysv4.3${OS_REL}; exit; }
+ /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \
+ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
+ m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
+ echo m68k-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ mc68030:UNIX_System_V:4.*:*)
+ echo m68k-atari-sysv4
+ exit ;;
+ TSUNAMI:LynxOS:2.*:*)
+ echo sparc-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ rs6000:LynxOS:2.*:*)
+ echo rs6000-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*)
+ echo powerpc-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ SM[BE]S:UNIX_SV:*:*)
+ echo mips-dde-sysv${UNAME_RELEASE}
+ exit ;;
+ RM*:ReliantUNIX-*:*:*)
+ echo mips-sni-sysv4
+ exit ;;
+ RM*:SINIX-*:*:*)
+ echo mips-sni-sysv4
+ exit ;;
+ *:SINIX-*:*:*)
+ if uname -p 2>/dev/null >/dev/null ; then
+ UNAME_MACHINE=`(uname -p) 2>/dev/null`
+ echo ${UNAME_MACHINE}-sni-sysv4
+ else
+ echo ns32k-sni-sysv
+ fi
+ exit ;;
+ PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+ # says <Richard.M.Bartel@ccMail.Census.GOV>
+ echo i586-unisys-sysv4
+ exit ;;
+ *:UNIX_System_V:4*:FTX*)
+ # From Gerald Hewes <hewes@openmarket.com>.
+ # How about differentiating between stratus architectures? -djm
+ echo hppa1.1-stratus-sysv4
+ exit ;;
+ *:*:*:FTX*)
+ # From seanf@swdc.stratus.com.
+ echo i860-stratus-sysv4
+ exit ;;
+ i*86:VOS:*:*)
+ # From Paul.Green@stratus.com.
+ echo ${UNAME_MACHINE}-stratus-vos
+ exit ;;
+ *:VOS:*:*)
+ # From Paul.Green@stratus.com.
+ echo hppa1.1-stratus-vos
+ exit ;;
+ mc68*:A/UX:*:*)
+ echo m68k-apple-aux${UNAME_RELEASE}
+ exit ;;
+ news*:NEWS-OS:6*:*)
+ echo mips-sony-newsos6
+ exit ;;
+ R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
+ if [ -d /usr/nec ]; then
+ echo mips-nec-sysv${UNAME_RELEASE}
+ else
+ echo mips-unknown-sysv${UNAME_RELEASE}
+ fi
+ exit ;;
+ BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only.
+ echo powerpc-be-beos
+ exit ;;
+ BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only.
+ echo powerpc-apple-beos
+ exit ;;
+ BePC:BeOS:*:*) # BeOS running on Intel PC compatible.
+ echo i586-pc-beos
+ exit ;;
+ BePC:Haiku:*:*) # Haiku running on Intel PC compatible.
+ echo i586-pc-haiku
+ exit ;;
+ x86_64:Haiku:*:*)
+ echo x86_64-unknown-haiku
+ exit ;;
+ SX-4:SUPER-UX:*:*)
+ echo sx4-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-5:SUPER-UX:*:*)
+ echo sx5-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-6:SUPER-UX:*:*)
+ echo sx6-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-7:SUPER-UX:*:*)
+ echo sx7-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-8:SUPER-UX:*:*)
+ echo sx8-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-8R:SUPER-UX:*:*)
+ echo sx8r-nec-superux${UNAME_RELEASE}
+ exit ;;
+ Power*:Rhapsody:*:*)
+ echo powerpc-apple-rhapsody${UNAME_RELEASE}
+ exit ;;
+ *:Rhapsody:*:*)
+ echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
+ exit ;;
+ *:Darwin:*:*)
+ UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
+ eval $set_cc_for_build
+ if test "$UNAME_PROCESSOR" = unknown ; then
+ UNAME_PROCESSOR=powerpc
+ fi
+ if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+ if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
+ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+ grep IS_64BIT_ARCH >/dev/null
+ then
+ case $UNAME_PROCESSOR in
+ i386) UNAME_PROCESSOR=x86_64 ;;
+ powerpc) UNAME_PROCESSOR=powerpc64 ;;
+ esac
+ fi
+ fi
+ echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
+ exit ;;
+ *:procnto*:*:* | *:QNX:[0123456789]*:*)
+ UNAME_PROCESSOR=`uname -p`
+ if test "$UNAME_PROCESSOR" = "x86"; then
+ UNAME_PROCESSOR=i386
+ UNAME_MACHINE=pc
+ fi
+ echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
+ exit ;;
+ *:QNX:*:4*)
+ echo i386-pc-qnx
+ exit ;;
+ NEO-?:NONSTOP_KERNEL:*:*)
+ echo neo-tandem-nsk${UNAME_RELEASE}
+ exit ;;
+ NSE-*:NONSTOP_KERNEL:*:*)
+ echo nse-tandem-nsk${UNAME_RELEASE}
+ exit ;;
+ NSR-?:NONSTOP_KERNEL:*:*)
+ echo nsr-tandem-nsk${UNAME_RELEASE}
+ exit ;;
+ *:NonStop-UX:*:*)
+ echo mips-compaq-nonstopux
+ exit ;;
+ BS2000:POSIX*:*:*)
+ echo bs2000-siemens-sysv
+ exit ;;
+ DS/*:UNIX_System_V:*:*)
+ echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
+ exit ;;
+ *:Plan9:*:*)
+ # "uname -m" is not consistent, so use $cputype instead. 386
+ # is converted to i386 for consistency with other x86
+ # operating systems.
+ if test "$cputype" = "386"; then
+ UNAME_MACHINE=i386
+ else
+ UNAME_MACHINE="$cputype"
+ fi
+ echo ${UNAME_MACHINE}-unknown-plan9
+ exit ;;
+ *:TOPS-10:*:*)
+ echo pdp10-unknown-tops10
+ exit ;;
+ *:TENEX:*:*)
+ echo pdp10-unknown-tenex
+ exit ;;
+ KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
+ echo pdp10-dec-tops20
+ exit ;;
+ XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
+ echo pdp10-xkl-tops20
+ exit ;;
+ *:TOPS-20:*:*)
+ echo pdp10-unknown-tops20
+ exit ;;
+ *:ITS:*:*)
+ echo pdp10-unknown-its
+ exit ;;
+ SEI:*:*:SEIUX)
+ echo mips-sei-seiux${UNAME_RELEASE}
+ exit ;;
+ *:DragonFly:*:*)
+ echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+ exit ;;
+ *:*VMS:*:*)
+ UNAME_MACHINE=`(uname -p) 2>/dev/null`
+ case "${UNAME_MACHINE}" in
+ A*) echo alpha-dec-vms ; exit ;;
+ I*) echo ia64-dec-vms ; exit ;;
+ V*) echo vax-dec-vms ; exit ;;
+ esac ;;
+ *:XENIX:*:SysV)
+ echo i386-pc-xenix
+ exit ;;
+ i*86:skyos:*:*)
+ echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//'
+ exit ;;
+ i*86:rdos:*:*)
+ echo ${UNAME_MACHINE}-pc-rdos
+ exit ;;
+ i*86:AROS:*:*)
+ echo ${UNAME_MACHINE}-pc-aros
+ exit ;;
+ x86_64:VMkernel:*:*)
+ echo ${UNAME_MACHINE}-unknown-esx
+ exit ;;
+esac
+
+eval $set_cc_for_build
+cat >$dummy.c <<EOF
+#ifdef _SEQUENT_
+# include <sys/types.h>
+# include <sys/utsname.h>
+#endif
+main ()
+{
+#if defined (sony)
+#if defined (MIPSEB)
+ /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed,
+ I don't know.... */
+ printf ("mips-sony-bsd\n"); exit (0);
+#else
+#include <sys/param.h>
+ printf ("m68k-sony-newsos%s\n",
+#ifdef NEWSOS4
+ "4"
+#else
+ ""
+#endif
+ ); exit (0);
+#endif
+#endif
+
+#if defined (__arm) && defined (__acorn) && defined (__unix)
+ printf ("arm-acorn-riscix\n"); exit (0);
+#endif
+
+#if defined (hp300) && !defined (hpux)
+ printf ("m68k-hp-bsd\n"); exit (0);
+#endif
+
+#if defined (NeXT)
+#if !defined (__ARCHITECTURE__)
+#define __ARCHITECTURE__ "m68k"
+#endif
+ int version;
+ version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
+ if (version < 4)
+ printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
+ else
+ printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
+ exit (0);
+#endif
+
+#if defined (MULTIMAX) || defined (n16)
+#if defined (UMAXV)
+ printf ("ns32k-encore-sysv\n"); exit (0);
+#else
+#if defined (CMU)
+ printf ("ns32k-encore-mach\n"); exit (0);
+#else
+ printf ("ns32k-encore-bsd\n"); exit (0);
+#endif
+#endif
+#endif
+
+#if defined (__386BSD__)
+ printf ("i386-pc-bsd\n"); exit (0);
+#endif
+
+#if defined (sequent)
+#if defined (i386)
+ printf ("i386-sequent-dynix\n"); exit (0);
+#endif
+#if defined (ns32000)
+ printf ("ns32k-sequent-dynix\n"); exit (0);
+#endif
+#endif
+
+#if defined (_SEQUENT_)
+ struct utsname un;
+
+ uname(&un);
+
+ if (strncmp(un.version, "V2", 2) == 0) {
+ printf ("i386-sequent-ptx2\n"); exit (0);
+ }
+ if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
+ printf ("i386-sequent-ptx1\n"); exit (0);
+ }
+ printf ("i386-sequent-ptx\n"); exit (0);
+
+#endif
+
+#if defined (vax)
+# if !defined (ultrix)
+# include <sys/param.h>
+# if defined (BSD)
+# if BSD == 43
+ printf ("vax-dec-bsd4.3\n"); exit (0);
+# else
+# if BSD == 199006
+ printf ("vax-dec-bsd4.3reno\n"); exit (0);
+# else
+ printf ("vax-dec-bsd\n"); exit (0);
+# endif
+# endif
+# else
+ printf ("vax-dec-bsd\n"); exit (0);
+# endif
+# else
+ printf ("vax-dec-ultrix\n"); exit (0);
+# endif
+#endif
+
+#if defined (alliant) && defined (i860)
+ printf ("i860-alliant-bsd\n"); exit (0);
+#endif
+
+ exit (1);
+}
+EOF
+
+$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` &&
+ { echo "$SYSTEM_NAME"; exit; }
+
+# Apollos put the system type in the environment.
+
+test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; }
+
+# Convex versions that predate uname can use getsysinfo(1)
+
+if [ -x /usr/convex/getsysinfo ]
+then
+ case `getsysinfo -f cpu_type` in
+ c1*)
+ echo c1-convex-bsd
+ exit ;;
+ c2*)
+ if getsysinfo -f scalar_acc
+ then echo c32-convex-bsd
+ else echo c2-convex-bsd
+ fi
+ exit ;;
+ c34*)
+ echo c34-convex-bsd
+ exit ;;
+ c38*)
+ echo c38-convex-bsd
+ exit ;;
+ c4*)
+ echo c4-convex-bsd
+ exit ;;
+ esac
+fi
+
+cat >&2 <<EOF
+$0: unable to guess system type
+
+This script, last modified $timestamp, has failed to recognize
+the operating system you are using. It is advised that you
+download the most up to date version of the config scripts from
+
+ http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
+and
+ http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
+
+If the version you run ($0) is already up to date, please
+send the following data and any information you think might be
+pertinent to <config-patches@gnu.org> in order to provide the needed
+information to handle your system.
+
+config.guess timestamp = $timestamp
+
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
+/bin/uname -X = `(/bin/uname -X) 2>/dev/null`
+
+hostinfo = `(hostinfo) 2>/dev/null`
+/bin/universe = `(/bin/universe) 2>/dev/null`
+/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null`
+/bin/arch = `(/bin/arch) 2>/dev/null`
+/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
+
+UNAME_MACHINE = ${UNAME_MACHINE}
+UNAME_RELEASE = ${UNAME_RELEASE}
+UNAME_SYSTEM = ${UNAME_SYSTEM}
+UNAME_VERSION = ${UNAME_VERSION}
+EOF
+
+exit 1
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
diff --git a/config.sub b/config.sub
new file mode 100755
index 0000000..c765b34
--- /dev/null
+++ b/config.sub
@@ -0,0 +1,1788 @@
+#! /bin/sh
+# Configuration validation subroutine script.
+# Copyright 1992-2013 Free Software Foundation, Inc.
+
+timestamp='2013-04-24'
+
+# This file 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 3 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, see <http://www.gnu.org/licenses/>.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that
+# program. This Exception is an additional permission under section 7
+# of the GNU General Public License, version 3 ("GPLv3").
+
+
+# Please send patches with a ChangeLog entry to config-patches@gnu.org.
+#
+# Configuration subroutine to validate and canonicalize a configuration type.
+# Supply the specified configuration type as an argument.
+# If it is invalid, we print an error message on stderr and exit with code 1.
+# Otherwise, we print the canonical config type on stdout and succeed.
+
+# You can get the latest version of this script from:
+# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
+
+# This file is supposed to be the same for all GNU packages
+# and recognize all the CPU types, system types and aliases
+# that are meaningful with *any* GNU software.
+# Each package is responsible for reporting which valid configurations
+# it does not support. The user should be able to distinguish
+# a failure to support a valid configuration from a meaningless
+# configuration.
+
+# The goal of this file is to map all the various variations of a given
+# machine specification into a single specification in the form:
+# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or in some cases, the newer four-part form:
+# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# It is wrong to echo any other type of specification.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION] CPU-MFR-OPSYS
+ $0 [OPTION] ALIAS
+
+Canonicalize a configuration name.
+
+Operation modes:
+ -h, --help print this help, then exit
+ -t, --time-stamp print date of last modification, then exit
+ -v, --version print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.sub ($timestamp)
+
+Copyright 1992-2013 Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions. There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+ case $1 in
+ --time-stamp | --time* | -t )
+ echo "$timestamp" ; exit ;;
+ --version | -v )
+ echo "$version" ; exit ;;
+ --help | --h* | -h )
+ echo "$usage"; exit ;;
+ -- ) # Stop option processing
+ shift; break ;;
+ - ) # Use stdin as input.
+ break ;;
+ -* )
+ echo "$me: invalid option $1$help"
+ exit 1 ;;
+
+ *local*)
+ # First pass through any local machine types.
+ echo $1
+ exit ;;
+
+ * )
+ break ;;
+ esac
+done
+
+case $# in
+ 0) echo "$me: missing argument$help" >&2
+ exit 1;;
+ 1) ;;
+ *) echo "$me: too many arguments$help" >&2
+ exit 1;;
+esac
+
+# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
+# Here we must recognize all the valid KERNEL-OS combinations.
+maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+case $maybe_os in
+ nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
+ linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
+ knetbsd*-gnu* | netbsd*-gnu* | \
+ kopensolaris*-gnu* | \
+ storm-chaos* | os2-emx* | rtmk-nova*)
+ os=-$maybe_os
+ basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+ ;;
+ android-linux)
+ os=-linux-android
+ basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown
+ ;;
+ *)
+ basic_machine=`echo $1 | sed 's/-[^-]*$//'`
+ if [ $basic_machine != $1 ]
+ then os=`echo $1 | sed 's/.*-/-/'`
+ else os=; fi
+ ;;
+esac
+
+### Let's recognize common machines as not being operating systems so
+### that things like config.sub decstation-3100 work. We also
+### recognize some manufacturers as not being operating systems, so we
+### can provide default operating systems below.
+case $os in
+ -sun*os*)
+ # Prevent following clause from handling this invalid input.
+ ;;
+ -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
+ -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
+ -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
+ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
+ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
+ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
+ -apple | -axis | -knuth | -cray | -microblaze*)
+ os=
+ basic_machine=$1
+ ;;
+ -bluegene*)
+ os=-cnk
+ ;;
+ -sim | -cisco | -oki | -wec | -winbond)
+ os=
+ basic_machine=$1
+ ;;
+ -scout)
+ ;;
+ -wrs)
+ os=-vxworks
+ basic_machine=$1
+ ;;
+ -chorusos*)
+ os=-chorusos
+ basic_machine=$1
+ ;;
+ -chorusrdb)
+ os=-chorusrdb
+ basic_machine=$1
+ ;;
+ -hiux*)
+ os=-hiuxwe2
+ ;;
+ -sco6)
+ os=-sco5v6
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco5)
+ os=-sco3.2v5
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco4)
+ os=-sco3.2v4
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco3.2.[4-9]*)
+ os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco3.2v[4-9]*)
+ # Don't forget version if it is 3.2v4 or newer.
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco5v6*)
+ # Don't forget version if it is 3.2v4 or newer.
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco*)
+ os=-sco3.2v2
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -udk*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -isc)
+ os=-isc2.2
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -clix*)
+ basic_machine=clipper-intergraph
+ ;;
+ -isc*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -lynx*178)
+ os=-lynxos178
+ ;;
+ -lynx*5)
+ os=-lynxos5
+ ;;
+ -lynx*)
+ os=-lynxos
+ ;;
+ -ptx*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
+ ;;
+ -windowsnt*)
+ os=`echo $os | sed -e 's/windowsnt/winnt/'`
+ ;;
+ -psos*)
+ os=-psos
+ ;;
+ -mint | -mint[0-9]*)
+ basic_machine=m68k-atari
+ os=-mint
+ ;;
+esac
+
+# Decode aliases for certain CPU-COMPANY combinations.
+case $basic_machine in
+ # Recognize the basic CPU types without company name.
+ # Some are omitted here because they have special meanings below.
+ 1750a | 580 \
+ | a29k \
+ | aarch64 | aarch64_be \
+ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
+ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
+ | am33_2.0 \
+ | arc | arceb \
+ | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \
+ | avr | avr32 \
+ | be32 | be64 \
+ | bfin \
+ | c4x | clipper \
+ | d10v | d30v | dlx | dsp16xx \
+ | epiphany \
+ | fido | fr30 | frv \
+ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
+ | hexagon \
+ | i370 | i860 | i960 | ia64 \
+ | ip2k | iq2000 \
+ | le32 | le64 \
+ | lm32 \
+ | m32c | m32r | m32rle | m68000 | m68k | m88k \
+ | maxq | mb | microblaze | microblazeel | mcore | mep | metag \
+ | mips | mipsbe | mipseb | mipsel | mipsle \
+ | mips16 \
+ | mips64 | mips64el \
+ | mips64octeon | mips64octeonel \
+ | mips64orion | mips64orionel \
+ | mips64r5900 | mips64r5900el \
+ | mips64vr | mips64vrel \
+ | mips64vr4100 | mips64vr4100el \
+ | mips64vr4300 | mips64vr4300el \
+ | mips64vr5000 | mips64vr5000el \
+ | mips64vr5900 | mips64vr5900el \
+ | mipsisa32 | mipsisa32el \
+ | mipsisa32r2 | mipsisa32r2el \
+ | mipsisa64 | mipsisa64el \
+ | mipsisa64r2 | mipsisa64r2el \
+ | mipsisa64sb1 | mipsisa64sb1el \
+ | mipsisa64sr71k | mipsisa64sr71kel \
+ | mipsr5900 | mipsr5900el \
+ | mipstx39 | mipstx39el \
+ | mn10200 | mn10300 \
+ | moxie \
+ | mt \
+ | msp430 \
+ | nds32 | nds32le | nds32be \
+ | nios | nios2 | nios2eb | nios2el \
+ | ns16k | ns32k \
+ | open8 \
+ | or1k | or32 \
+ | pdp10 | pdp11 | pj | pjl \
+ | powerpc | powerpc64 | powerpc64le | powerpcle \
+ | pyramid \
+ | rl78 | rx \
+ | score \
+ | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
+ | sh64 | sh64le \
+ | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
+ | sparcv8 | sparcv9 | sparcv9b | sparcv9v \
+ | spu \
+ | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \
+ | ubicom32 \
+ | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
+ | we32k \
+ | x86 | xc16x | xstormy16 | xtensa \
+ | z8k | z80)
+ basic_machine=$basic_machine-unknown
+ ;;
+ c54x)
+ basic_machine=tic54x-unknown
+ ;;
+ c55x)
+ basic_machine=tic55x-unknown
+ ;;
+ c6x)
+ basic_machine=tic6x-unknown
+ ;;
+ m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | picochip)
+ basic_machine=$basic_machine-unknown
+ os=-none
+ ;;
+ m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
+ ;;
+ ms1)
+ basic_machine=mt-unknown
+ ;;
+
+ strongarm | thumb | xscale)
+ basic_machine=arm-unknown
+ ;;
+ xgate)
+ basic_machine=$basic_machine-unknown
+ os=-none
+ ;;
+ xscaleeb)
+ basic_machine=armeb-unknown
+ ;;
+
+ xscaleel)
+ basic_machine=armel-unknown
+ ;;
+
+ # We use `pc' rather than `unknown'
+ # because (1) that's what they normally are, and
+ # (2) the word "unknown" tends to confuse beginning users.
+ i*86 | x86_64)
+ basic_machine=$basic_machine-pc
+ ;;
+ # Object if more than one company name word.
+ *-*-*)
+ echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+ exit 1
+ ;;
+ # Recognize the basic CPU types with company name.
+ 580-* \
+ | a29k-* \
+ | aarch64-* | aarch64_be-* \
+ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
+ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
+ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \
+ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \
+ | avr-* | avr32-* \
+ | be32-* | be64-* \
+ | bfin-* | bs2000-* \
+ | c[123]* | c30-* | [cjt]90-* | c4x-* \
+ | clipper-* | craynv-* | cydra-* \
+ | d10v-* | d30v-* | dlx-* \
+ | elxsi-* \
+ | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
+ | h8300-* | h8500-* \
+ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
+ | hexagon-* \
+ | i*86-* | i860-* | i960-* | ia64-* \
+ | ip2k-* | iq2000-* \
+ | le32-* | le64-* \
+ | lm32-* \
+ | m32c-* | m32r-* | m32rle-* \
+ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
+ | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \
+ | microblaze-* | microblazeel-* \
+ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
+ | mips16-* \
+ | mips64-* | mips64el-* \
+ | mips64octeon-* | mips64octeonel-* \
+ | mips64orion-* | mips64orionel-* \
+ | mips64r5900-* | mips64r5900el-* \
+ | mips64vr-* | mips64vrel-* \
+ | mips64vr4100-* | mips64vr4100el-* \
+ | mips64vr4300-* | mips64vr4300el-* \
+ | mips64vr5000-* | mips64vr5000el-* \
+ | mips64vr5900-* | mips64vr5900el-* \
+ | mipsisa32-* | mipsisa32el-* \
+ | mipsisa32r2-* | mipsisa32r2el-* \
+ | mipsisa64-* | mipsisa64el-* \
+ | mipsisa64r2-* | mipsisa64r2el-* \
+ | mipsisa64sb1-* | mipsisa64sb1el-* \
+ | mipsisa64sr71k-* | mipsisa64sr71kel-* \
+ | mipsr5900-* | mipsr5900el-* \
+ | mipstx39-* | mipstx39el-* \
+ | mmix-* \
+ | mt-* \
+ | msp430-* \
+ | nds32-* | nds32le-* | nds32be-* \
+ | nios-* | nios2-* | nios2eb-* | nios2el-* \
+ | none-* | np1-* | ns16k-* | ns32k-* \
+ | open8-* \
+ | orion-* \
+ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
+ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
+ | pyramid-* \
+ | rl78-* | romp-* | rs6000-* | rx-* \
+ | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
+ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
+ | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
+ | sparclite-* \
+ | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \
+ | tahoe-* \
+ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
+ | tile*-* \
+ | tron-* \
+ | ubicom32-* \
+ | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
+ | vax-* \
+ | we32k-* \
+ | x86-* | x86_64-* | xc16x-* | xps100-* \
+ | xstormy16-* | xtensa*-* \
+ | ymp-* \
+ | z8k-* | z80-*)
+ ;;
+ # Recognize the basic CPU types without company name, with glob match.
+ xtensa*)
+ basic_machine=$basic_machine-unknown
+ ;;
+ # Recognize the various machine names and aliases which stand
+ # for a CPU type and a company and sometimes even an OS.
+ 386bsd)
+ basic_machine=i386-unknown
+ os=-bsd
+ ;;
+ 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
+ basic_machine=m68000-att
+ ;;
+ 3b*)
+ basic_machine=we32k-att
+ ;;
+ a29khif)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ abacus)
+ basic_machine=abacus-unknown
+ ;;
+ adobe68k)
+ basic_machine=m68010-adobe
+ os=-scout
+ ;;
+ alliant | fx80)
+ basic_machine=fx80-alliant
+ ;;
+ altos | altos3068)
+ basic_machine=m68k-altos
+ ;;
+ am29k)
+ basic_machine=a29k-none
+ os=-bsd
+ ;;
+ amd64)
+ basic_machine=x86_64-pc
+ ;;
+ amd64-*)
+ basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ amdahl)
+ basic_machine=580-amdahl
+ os=-sysv
+ ;;
+ amiga | amiga-*)
+ basic_machine=m68k-unknown
+ ;;
+ amigaos | amigados)
+ basic_machine=m68k-unknown
+ os=-amigaos
+ ;;
+ amigaunix | amix)
+ basic_machine=m68k-unknown
+ os=-sysv4
+ ;;
+ apollo68)
+ basic_machine=m68k-apollo
+ os=-sysv
+ ;;
+ apollo68bsd)
+ basic_machine=m68k-apollo
+ os=-bsd
+ ;;
+ aros)
+ basic_machine=i386-pc
+ os=-aros
+ ;;
+ aux)
+ basic_machine=m68k-apple
+ os=-aux
+ ;;
+ balance)
+ basic_machine=ns32k-sequent
+ os=-dynix
+ ;;
+ blackfin)
+ basic_machine=bfin-unknown
+ os=-linux
+ ;;
+ blackfin-*)
+ basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`
+ os=-linux
+ ;;
+ bluegene*)
+ basic_machine=powerpc-ibm
+ os=-cnk
+ ;;
+ c54x-*)
+ basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ c55x-*)
+ basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ c6x-*)
+ basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ c90)
+ basic_machine=c90-cray
+ os=-unicos
+ ;;
+ cegcc)
+ basic_machine=arm-unknown
+ os=-cegcc
+ ;;
+ convex-c1)
+ basic_machine=c1-convex
+ os=-bsd
+ ;;
+ convex-c2)
+ basic_machine=c2-convex
+ os=-bsd
+ ;;
+ convex-c32)
+ basic_machine=c32-convex
+ os=-bsd
+ ;;
+ convex-c34)
+ basic_machine=c34-convex
+ os=-bsd
+ ;;
+ convex-c38)
+ basic_machine=c38-convex
+ os=-bsd
+ ;;
+ cray | j90)
+ basic_machine=j90-cray
+ os=-unicos
+ ;;
+ craynv)
+ basic_machine=craynv-cray
+ os=-unicosmp
+ ;;
+ cr16 | cr16-*)
+ basic_machine=cr16-unknown
+ os=-elf
+ ;;
+ crds | unos)
+ basic_machine=m68k-crds
+ ;;
+ crisv32 | crisv32-* | etraxfs*)
+ basic_machine=crisv32-axis
+ ;;
+ cris | cris-* | etrax*)
+ basic_machine=cris-axis
+ ;;
+ crx)
+ basic_machine=crx-unknown
+ os=-elf
+ ;;
+ da30 | da30-*)
+ basic_machine=m68k-da30
+ ;;
+ decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
+ basic_machine=mips-dec
+ ;;
+ decsystem10* | dec10*)
+ basic_machine=pdp10-dec
+ os=-tops10
+ ;;
+ decsystem20* | dec20*)
+ basic_machine=pdp10-dec
+ os=-tops20
+ ;;
+ delta | 3300 | motorola-3300 | motorola-delta \
+ | 3300-motorola | delta-motorola)
+ basic_machine=m68k-motorola
+ ;;
+ delta88)
+ basic_machine=m88k-motorola
+ os=-sysv3
+ ;;
+ dicos)
+ basic_machine=i686-pc
+ os=-dicos
+ ;;
+ djgpp)
+ basic_machine=i586-pc
+ os=-msdosdjgpp
+ ;;
+ dpx20 | dpx20-*)
+ basic_machine=rs6000-bull
+ os=-bosx
+ ;;
+ dpx2* | dpx2*-bull)
+ basic_machine=m68k-bull
+ os=-sysv3
+ ;;
+ ebmon29k)
+ basic_machine=a29k-amd
+ os=-ebmon
+ ;;
+ elxsi)
+ basic_machine=elxsi-elxsi
+ os=-bsd
+ ;;
+ encore | umax | mmax)
+ basic_machine=ns32k-encore
+ ;;
+ es1800 | OSE68k | ose68k | ose | OSE)
+ basic_machine=m68k-ericsson
+ os=-ose
+ ;;
+ fx2800)
+ basic_machine=i860-alliant
+ ;;
+ genix)
+ basic_machine=ns32k-ns
+ ;;
+ gmicro)
+ basic_machine=tron-gmicro
+ os=-sysv
+ ;;
+ go32)
+ basic_machine=i386-pc
+ os=-go32
+ ;;
+ h3050r* | hiux*)
+ basic_machine=hppa1.1-hitachi
+ os=-hiuxwe2
+ ;;
+ h8300hms)
+ basic_machine=h8300-hitachi
+ os=-hms
+ ;;
+ h8300xray)
+ basic_machine=h8300-hitachi
+ os=-xray
+ ;;
+ h8500hms)
+ basic_machine=h8500-hitachi
+ os=-hms
+ ;;
+ harris)
+ basic_machine=m88k-harris
+ os=-sysv3
+ ;;
+ hp300-*)
+ basic_machine=m68k-hp
+ ;;
+ hp300bsd)
+ basic_machine=m68k-hp
+ os=-bsd
+ ;;
+ hp300hpux)
+ basic_machine=m68k-hp
+ os=-hpux
+ ;;
+ hp3k9[0-9][0-9] | hp9[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hp9k2[0-9][0-9] | hp9k31[0-9])
+ basic_machine=m68000-hp
+ ;;
+ hp9k3[2-9][0-9])
+ basic_machine=m68k-hp
+ ;;
+ hp9k6[0-9][0-9] | hp6[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hp9k7[0-79][0-9] | hp7[0-79][0-9])
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k78[0-9] | hp78[0-9])
+ # FIXME: really hppa2.0-hp
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
+ # FIXME: really hppa2.0-hp
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[0-9][13679] | hp8[0-9][13679])
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[0-9][0-9] | hp8[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hppa-next)
+ os=-nextstep3
+ ;;
+ hppaosf)
+ basic_machine=hppa1.1-hp
+ os=-osf
+ ;;
+ hppro)
+ basic_machine=hppa1.1-hp
+ os=-proelf
+ ;;
+ i370-ibm* | ibm*)
+ basic_machine=i370-ibm
+ ;;
+ i*86v32)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv32
+ ;;
+ i*86v4*)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv4
+ ;;
+ i*86v)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv
+ ;;
+ i*86sol2)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-solaris2
+ ;;
+ i386mach)
+ basic_machine=i386-mach
+ os=-mach
+ ;;
+ i386-vsta | vsta)
+ basic_machine=i386-unknown
+ os=-vsta
+ ;;
+ iris | iris4d)
+ basic_machine=mips-sgi
+ case $os in
+ -irix*)
+ ;;
+ *)
+ os=-irix4
+ ;;
+ esac
+ ;;
+ isi68 | isi)
+ basic_machine=m68k-isi
+ os=-sysv
+ ;;
+ m68knommu)
+ basic_machine=m68k-unknown
+ os=-linux
+ ;;
+ m68knommu-*)
+ basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'`
+ os=-linux
+ ;;
+ m88k-omron*)
+ basic_machine=m88k-omron
+ ;;
+ magnum | m3230)
+ basic_machine=mips-mips
+ os=-sysv
+ ;;
+ merlin)
+ basic_machine=ns32k-utek
+ os=-sysv
+ ;;
+ microblaze*)
+ basic_machine=microblaze-xilinx
+ ;;
+ mingw64)
+ basic_machine=x86_64-pc
+ os=-mingw64
+ ;;
+ mingw32)
+ basic_machine=i386-pc
+ os=-mingw32
+ ;;
+ mingw32ce)
+ basic_machine=arm-unknown
+ os=-mingw32ce
+ ;;
+ miniframe)
+ basic_machine=m68000-convergent
+ ;;
+ *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
+ basic_machine=m68k-atari
+ os=-mint
+ ;;
+ mips3*-*)
+ basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
+ ;;
+ mips3*)
+ basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
+ ;;
+ monitor)
+ basic_machine=m68k-rom68k
+ os=-coff
+ ;;
+ morphos)
+ basic_machine=powerpc-unknown
+ os=-morphos
+ ;;
+ msdos)
+ basic_machine=i386-pc
+ os=-msdos
+ ;;
+ ms1-*)
+ basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
+ ;;
+ msys)
+ basic_machine=i386-pc
+ os=-msys
+ ;;
+ mvs)
+ basic_machine=i370-ibm
+ os=-mvs
+ ;;
+ nacl)
+ basic_machine=le32-unknown
+ os=-nacl
+ ;;
+ ncr3000)
+ basic_machine=i486-ncr
+ os=-sysv4
+ ;;
+ netbsd386)
+ basic_machine=i386-unknown
+ os=-netbsd
+ ;;
+ netwinder)
+ basic_machine=armv4l-rebel
+ os=-linux
+ ;;
+ news | news700 | news800 | news900)
+ basic_machine=m68k-sony
+ os=-newsos
+ ;;
+ news1000)
+ basic_machine=m68030-sony
+ os=-newsos
+ ;;
+ news-3600 | risc-news)
+ basic_machine=mips-sony
+ os=-newsos
+ ;;
+ necv70)
+ basic_machine=v70-nec
+ os=-sysv
+ ;;
+ next | m*-next )
+ basic_machine=m68k-next
+ case $os in
+ -nextstep* )
+ ;;
+ -ns2*)
+ os=-nextstep2
+ ;;
+ *)
+ os=-nextstep3
+ ;;
+ esac
+ ;;
+ nh3000)
+ basic_machine=m68k-harris
+ os=-cxux
+ ;;
+ nh[45]000)
+ basic_machine=m88k-harris
+ os=-cxux
+ ;;
+ nindy960)
+ basic_machine=i960-intel
+ os=-nindy
+ ;;
+ mon960)
+ basic_machine=i960-intel
+ os=-mon960
+ ;;
+ nonstopux)
+ basic_machine=mips-compaq
+ os=-nonstopux
+ ;;
+ np1)
+ basic_machine=np1-gould
+ ;;
+ neo-tandem)
+ basic_machine=neo-tandem
+ ;;
+ nse-tandem)
+ basic_machine=nse-tandem
+ ;;
+ nsr-tandem)
+ basic_machine=nsr-tandem
+ ;;
+ op50n-* | op60c-*)
+ basic_machine=hppa1.1-oki
+ os=-proelf
+ ;;
+ openrisc | openrisc-*)
+ basic_machine=or32-unknown
+ ;;
+ os400)
+ basic_machine=powerpc-ibm
+ os=-os400
+ ;;
+ OSE68000 | ose68000)
+ basic_machine=m68000-ericsson
+ os=-ose
+ ;;
+ os68k)
+ basic_machine=m68k-none
+ os=-os68k
+ ;;
+ pa-hitachi)
+ basic_machine=hppa1.1-hitachi
+ os=-hiuxwe2
+ ;;
+ paragon)
+ basic_machine=i860-intel
+ os=-osf
+ ;;
+ parisc)
+ basic_machine=hppa-unknown
+ os=-linux
+ ;;
+ parisc-*)
+ basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'`
+ os=-linux
+ ;;
+ pbd)
+ basic_machine=sparc-tti
+ ;;
+ pbb)
+ basic_machine=m68k-tti
+ ;;
+ pc532 | pc532-*)
+ basic_machine=ns32k-pc532
+ ;;
+ pc98)
+ basic_machine=i386-pc
+ ;;
+ pc98-*)
+ basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentium | p5 | k5 | k6 | nexgen | viac3)
+ basic_machine=i586-pc
+ ;;
+ pentiumpro | p6 | 6x86 | athlon | athlon_*)
+ basic_machine=i686-pc
+ ;;
+ pentiumii | pentium2 | pentiumiii | pentium3)
+ basic_machine=i686-pc
+ ;;
+ pentium4)
+ basic_machine=i786-pc
+ ;;
+ pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
+ basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentiumpro-* | p6-* | 6x86-* | athlon-*)
+ basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
+ basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentium4-*)
+ basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pn)
+ basic_machine=pn-gould
+ ;;
+ power) basic_machine=power-ibm
+ ;;
+ ppc | ppcbe) basic_machine=powerpc-unknown
+ ;;
+ ppc-* | ppcbe-*)
+ basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ppcle | powerpclittle | ppc-le | powerpc-little)
+ basic_machine=powerpcle-unknown
+ ;;
+ ppcle-* | powerpclittle-*)
+ basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ppc64) basic_machine=powerpc64-unknown
+ ;;
+ ppc64-* | ppc64p7-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ppc64le | powerpc64little | ppc64-le | powerpc64-little)
+ basic_machine=powerpc64le-unknown
+ ;;
+ ppc64le-* | powerpc64little-*)
+ basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ps2)
+ basic_machine=i386-ibm
+ ;;
+ pw32)
+ basic_machine=i586-unknown
+ os=-pw32
+ ;;
+ rdos | rdos64)
+ basic_machine=x86_64-pc
+ os=-rdos
+ ;;
+ rdos32)
+ basic_machine=i386-pc
+ os=-rdos
+ ;;
+ rom68k)
+ basic_machine=m68k-rom68k
+ os=-coff
+ ;;
+ rm[46]00)
+ basic_machine=mips-siemens
+ ;;
+ rtpc | rtpc-*)
+ basic_machine=romp-ibm
+ ;;
+ s390 | s390-*)
+ basic_machine=s390-ibm
+ ;;
+ s390x | s390x-*)
+ basic_machine=s390x-ibm
+ ;;
+ sa29200)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ sb1)
+ basic_machine=mipsisa64sb1-unknown
+ ;;
+ sb1el)
+ basic_machine=mipsisa64sb1el-unknown
+ ;;
+ sde)
+ basic_machine=mipsisa32-sde
+ os=-elf
+ ;;
+ sei)
+ basic_machine=mips-sei
+ os=-seiux
+ ;;
+ sequent)
+ basic_machine=i386-sequent
+ ;;
+ sh)
+ basic_machine=sh-hitachi
+ os=-hms
+ ;;
+ sh5el)
+ basic_machine=sh5le-unknown
+ ;;
+ sh64)
+ basic_machine=sh64-unknown
+ ;;
+ sparclite-wrs | simso-wrs)
+ basic_machine=sparclite-wrs
+ os=-vxworks
+ ;;
+ sps7)
+ basic_machine=m68k-bull
+ os=-sysv2
+ ;;
+ spur)
+ basic_machine=spur-unknown
+ ;;
+ st2000)
+ basic_machine=m68k-tandem
+ ;;
+ stratus)
+ basic_machine=i860-stratus
+ os=-sysv4
+ ;;
+ strongarm-* | thumb-*)
+ basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ sun2)
+ basic_machine=m68000-sun
+ ;;
+ sun2os3)
+ basic_machine=m68000-sun
+ os=-sunos3
+ ;;
+ sun2os4)
+ basic_machine=m68000-sun
+ os=-sunos4
+ ;;
+ sun3os3)
+ basic_machine=m68k-sun
+ os=-sunos3
+ ;;
+ sun3os4)
+ basic_machine=m68k-sun
+ os=-sunos4
+ ;;
+ sun4os3)
+ basic_machine=sparc-sun
+ os=-sunos3
+ ;;
+ sun4os4)
+ basic_machine=sparc-sun
+ os=-sunos4
+ ;;
+ sun4sol2)
+ basic_machine=sparc-sun
+ os=-solaris2
+ ;;
+ sun3 | sun3-*)
+ basic_machine=m68k-sun
+ ;;
+ sun4)
+ basic_machine=sparc-sun
+ ;;
+ sun386 | sun386i | roadrunner)
+ basic_machine=i386-sun
+ ;;
+ sv1)
+ basic_machine=sv1-cray
+ os=-unicos
+ ;;
+ symmetry)
+ basic_machine=i386-sequent
+ os=-dynix
+ ;;
+ t3e)
+ basic_machine=alphaev5-cray
+ os=-unicos
+ ;;
+ t90)
+ basic_machine=t90-cray
+ os=-unicos
+ ;;
+ tile*)
+ basic_machine=$basic_machine-unknown
+ os=-linux-gnu
+ ;;
+ tx39)
+ basic_machine=mipstx39-unknown
+ ;;
+ tx39el)
+ basic_machine=mipstx39el-unknown
+ ;;
+ toad1)
+ basic_machine=pdp10-xkl
+ os=-tops20
+ ;;
+ tower | tower-32)
+ basic_machine=m68k-ncr
+ ;;
+ tpf)
+ basic_machine=s390x-ibm
+ os=-tpf
+ ;;
+ udi29k)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ ultra3)
+ basic_machine=a29k-nyu
+ os=-sym1
+ ;;
+ v810 | necv810)
+ basic_machine=v810-nec
+ os=-none
+ ;;
+ vaxv)
+ basic_machine=vax-dec
+ os=-sysv
+ ;;
+ vms)
+ basic_machine=vax-dec
+ os=-vms
+ ;;
+ vpp*|vx|vx-*)
+ basic_machine=f301-fujitsu
+ ;;
+ vxworks960)
+ basic_machine=i960-wrs
+ os=-vxworks
+ ;;
+ vxworks68)
+ basic_machine=m68k-wrs
+ os=-vxworks
+ ;;
+ vxworks29k)
+ basic_machine=a29k-wrs
+ os=-vxworks
+ ;;
+ w65*)
+ basic_machine=w65-wdc
+ os=-none
+ ;;
+ w89k-*)
+ basic_machine=hppa1.1-winbond
+ os=-proelf
+ ;;
+ xbox)
+ basic_machine=i686-pc
+ os=-mingw32
+ ;;
+ xps | xps100)
+ basic_machine=xps100-honeywell
+ ;;
+ xscale-* | xscalee[bl]-*)
+ basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'`
+ ;;
+ ymp)
+ basic_machine=ymp-cray
+ os=-unicos
+ ;;
+ z8k-*-coff)
+ basic_machine=z8k-unknown
+ os=-sim
+ ;;
+ z80-*-coff)
+ basic_machine=z80-unknown
+ os=-sim
+ ;;
+ none)
+ basic_machine=none-none
+ os=-none
+ ;;
+
+# Here we handle the default manufacturer of certain CPU types. It is in
+# some cases the only manufacturer, in others, it is the most popular.
+ w89k)
+ basic_machine=hppa1.1-winbond
+ ;;
+ op50n)
+ basic_machine=hppa1.1-oki
+ ;;
+ op60c)
+ basic_machine=hppa1.1-oki
+ ;;
+ romp)
+ basic_machine=romp-ibm
+ ;;
+ mmix)
+ basic_machine=mmix-knuth
+ ;;
+ rs6000)
+ basic_machine=rs6000-ibm
+ ;;
+ vax)
+ basic_machine=vax-dec
+ ;;
+ pdp10)
+ # there are many clones, so DEC is not a safe bet
+ basic_machine=pdp10-unknown
+ ;;
+ pdp11)
+ basic_machine=pdp11-dec
+ ;;
+ we32k)
+ basic_machine=we32k-att
+ ;;
+ sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele)
+ basic_machine=sh-unknown
+ ;;
+ sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
+ basic_machine=sparc-sun
+ ;;
+ cydra)
+ basic_machine=cydra-cydrome
+ ;;
+ orion)
+ basic_machine=orion-highlevel
+ ;;
+ orion105)
+ basic_machine=clipper-highlevel
+ ;;
+ mac | mpw | mac-mpw)
+ basic_machine=m68k-apple
+ ;;
+ pmac | pmac-mpw)
+ basic_machine=powerpc-apple
+ ;;
+ *-unknown)
+ # Make sure to match an already-canonicalized machine name.
+ ;;
+ *)
+ echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+ exit 1
+ ;;
+esac
+
+# Here we canonicalize certain aliases for manufacturers.
+case $basic_machine in
+ *-digital*)
+ basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
+ ;;
+ *-commodore*)
+ basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
+ ;;
+ *)
+ ;;
+esac
+
+# Decode manufacturer-specific aliases for certain operating systems.
+
+if [ x"$os" != x"" ]
+then
+case $os in
+ # First match some system type aliases
+ # that might get confused with valid system types.
+ # -solaris* is a basic system type, with this one exception.
+ -auroraux)
+ os=-auroraux
+ ;;
+ -solaris1 | -solaris1.*)
+ os=`echo $os | sed -e 's|solaris1|sunos4|'`
+ ;;
+ -solaris)
+ os=-solaris2
+ ;;
+ -svr4*)
+ os=-sysv4
+ ;;
+ -unixware*)
+ os=-sysv4.2uw
+ ;;
+ -gnu/linux*)
+ os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
+ ;;
+ # First accept the basic system types.
+ # The portable systems comes first.
+ # Each alternative MUST END IN A *, to match a version number.
+ # -sysv* is not here because it comes later, after sysvr4.
+ -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
+ | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\
+ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
+ | -sym* | -kopensolaris* | -plan9* \
+ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+ | -aos* | -aros* \
+ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
+ | -bitrig* | -openbsd* | -solidbsd* \
+ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
+ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
+ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
+ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
+ | -chorusos* | -chorusrdb* | -cegcc* \
+ | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+ | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
+ | -linux-newlib* | -linux-musl* | -linux-uclibc* \
+ | -uxpv* | -beos* | -mpeix* | -udk* \
+ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
+ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
+ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
+ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
+ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
+ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
+ | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*)
+ # Remember, each alternative MUST END IN *, to match a version number.
+ ;;
+ -qnx*)
+ case $basic_machine in
+ x86-* | i*86-*)
+ ;;
+ *)
+ os=-nto$os
+ ;;
+ esac
+ ;;
+ -nto-qnx*)
+ ;;
+ -nto*)
+ os=`echo $os | sed -e 's|nto|nto-qnx|'`
+ ;;
+ -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
+ | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \
+ | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
+ ;;
+ -mac*)
+ os=`echo $os | sed -e 's|mac|macos|'`
+ ;;
+ -linux-dietlibc)
+ os=-linux-dietlibc
+ ;;
+ -linux*)
+ os=`echo $os | sed -e 's|linux|linux-gnu|'`
+ ;;
+ -sunos5*)
+ os=`echo $os | sed -e 's|sunos5|solaris2|'`
+ ;;
+ -sunos6*)
+ os=`echo $os | sed -e 's|sunos6|solaris3|'`
+ ;;
+ -opened*)
+ os=-openedition
+ ;;
+ -os400*)
+ os=-os400
+ ;;
+ -wince*)
+ os=-wince
+ ;;
+ -osfrose*)
+ os=-osfrose
+ ;;
+ -osf*)
+ os=-osf
+ ;;
+ -utek*)
+ os=-bsd
+ ;;
+ -dynix*)
+ os=-bsd
+ ;;
+ -acis*)
+ os=-aos
+ ;;
+ -atheos*)
+ os=-atheos
+ ;;
+ -syllable*)
+ os=-syllable
+ ;;
+ -386bsd)
+ os=-bsd
+ ;;
+ -ctix* | -uts*)
+ os=-sysv
+ ;;
+ -nova*)
+ os=-rtmk-nova
+ ;;
+ -ns2 )
+ os=-nextstep2
+ ;;
+ -nsk*)
+ os=-nsk
+ ;;
+ # Preserve the version number of sinix5.
+ -sinix5.*)
+ os=`echo $os | sed -e 's|sinix|sysv|'`
+ ;;
+ -sinix*)
+ os=-sysv4
+ ;;
+ -tpf*)
+ os=-tpf
+ ;;
+ -triton*)
+ os=-sysv3
+ ;;
+ -oss*)
+ os=-sysv3
+ ;;
+ -svr4)
+ os=-sysv4
+ ;;
+ -svr3)
+ os=-sysv3
+ ;;
+ -sysvr4)
+ os=-sysv4
+ ;;
+ # This must come after -sysvr4.
+ -sysv*)
+ ;;
+ -ose*)
+ os=-ose
+ ;;
+ -es1800*)
+ os=-ose
+ ;;
+ -xenix)
+ os=-xenix
+ ;;
+ -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+ os=-mint
+ ;;
+ -aros*)
+ os=-aros
+ ;;
+ -zvmoe)
+ os=-zvmoe
+ ;;
+ -dicos*)
+ os=-dicos
+ ;;
+ -nacl*)
+ ;;
+ -none)
+ ;;
+ *)
+ # Get rid of the `-' at the beginning of $os.
+ os=`echo $os | sed 's/[^-]*-//'`
+ echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
+ exit 1
+ ;;
+esac
+else
+
+# Here we handle the default operating systems that come with various machines.
+# The value should be what the vendor currently ships out the door with their
+# machine or put another way, the most popular os provided with the machine.
+
+# Note that if you're going to try to match "-MANUFACTURER" here (say,
+# "-sun"), then you have to tell the case statement up towards the top
+# that MANUFACTURER isn't an operating system. Otherwise, code above
+# will signal an error saying that MANUFACTURER isn't an operating
+# system, and we'll never get to this point.
+
+case $basic_machine in
+ score-*)
+ os=-elf
+ ;;
+ spu-*)
+ os=-elf
+ ;;
+ *-acorn)
+ os=-riscix1.2
+ ;;
+ arm*-rebel)
+ os=-linux
+ ;;
+ arm*-semi)
+ os=-aout
+ ;;
+ c4x-* | tic4x-*)
+ os=-coff
+ ;;
+ hexagon-*)
+ os=-elf
+ ;;
+ tic54x-*)
+ os=-coff
+ ;;
+ tic55x-*)
+ os=-coff
+ ;;
+ tic6x-*)
+ os=-coff
+ ;;
+ # This must come before the *-dec entry.
+ pdp10-*)
+ os=-tops20
+ ;;
+ pdp11-*)
+ os=-none
+ ;;
+ *-dec | vax-*)
+ os=-ultrix4.2
+ ;;
+ m68*-apollo)
+ os=-domain
+ ;;
+ i386-sun)
+ os=-sunos4.0.2
+ ;;
+ m68000-sun)
+ os=-sunos3
+ ;;
+ m68*-cisco)
+ os=-aout
+ ;;
+ mep-*)
+ os=-elf
+ ;;
+ mips*-cisco)
+ os=-elf
+ ;;
+ mips*-*)
+ os=-elf
+ ;;
+ or1k-*)
+ os=-elf
+ ;;
+ or32-*)
+ os=-coff
+ ;;
+ *-tti) # must be before sparc entry or we get the wrong os.
+ os=-sysv3
+ ;;
+ sparc-* | *-sun)
+ os=-sunos4.1.1
+ ;;
+ *-be)
+ os=-beos
+ ;;
+ *-haiku)
+ os=-haiku
+ ;;
+ *-ibm)
+ os=-aix
+ ;;
+ *-knuth)
+ os=-mmixware
+ ;;
+ *-wec)
+ os=-proelf
+ ;;
+ *-winbond)
+ os=-proelf
+ ;;
+ *-oki)
+ os=-proelf
+ ;;
+ *-hp)
+ os=-hpux
+ ;;
+ *-hitachi)
+ os=-hiux
+ ;;
+ i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
+ os=-sysv
+ ;;
+ *-cbm)
+ os=-amigaos
+ ;;
+ *-dg)
+ os=-dgux
+ ;;
+ *-dolphin)
+ os=-sysv3
+ ;;
+ m68k-ccur)
+ os=-rtu
+ ;;
+ m88k-omron*)
+ os=-luna
+ ;;
+ *-next )
+ os=-nextstep
+ ;;
+ *-sequent)
+ os=-ptx
+ ;;
+ *-crds)
+ os=-unos
+ ;;
+ *-ns)
+ os=-genix
+ ;;
+ i370-*)
+ os=-mvs
+ ;;
+ *-next)
+ os=-nextstep3
+ ;;
+ *-gould)
+ os=-sysv
+ ;;
+ *-highlevel)
+ os=-bsd
+ ;;
+ *-encore)
+ os=-bsd
+ ;;
+ *-sgi)
+ os=-irix
+ ;;
+ *-siemens)
+ os=-sysv4
+ ;;
+ *-masscomp)
+ os=-rtu
+ ;;
+ f30[01]-fujitsu | f700-fujitsu)
+ os=-uxpv
+ ;;
+ *-rom68k)
+ os=-coff
+ ;;
+ *-*bug)
+ os=-coff
+ ;;
+ *-apple)
+ os=-macos
+ ;;
+ *-atari*)
+ os=-mint
+ ;;
+ *)
+ os=-none
+ ;;
+esac
+fi
+
+# Here we handle the case where we know the os, and the CPU type, but not the
+# manufacturer. We pick the logical manufacturer.
+vendor=unknown
+case $basic_machine in
+ *-unknown)
+ case $os in
+ -riscix*)
+ vendor=acorn
+ ;;
+ -sunos*)
+ vendor=sun
+ ;;
+ -cnk*|-aix*)
+ vendor=ibm
+ ;;
+ -beos*)
+ vendor=be
+ ;;
+ -hpux*)
+ vendor=hp
+ ;;
+ -mpeix*)
+ vendor=hp
+ ;;
+ -hiux*)
+ vendor=hitachi
+ ;;
+ -unos*)
+ vendor=crds
+ ;;
+ -dgux*)
+ vendor=dg
+ ;;
+ -luna*)
+ vendor=omron
+ ;;
+ -genix*)
+ vendor=ns
+ ;;
+ -mvs* | -opened*)
+ vendor=ibm
+ ;;
+ -os400*)
+ vendor=ibm
+ ;;
+ -ptx*)
+ vendor=sequent
+ ;;
+ -tpf*)
+ vendor=ibm
+ ;;
+ -vxsim* | -vxworks* | -windiss*)
+ vendor=wrs
+ ;;
+ -aux*)
+ vendor=apple
+ ;;
+ -hms*)
+ vendor=hitachi
+ ;;
+ -mpw* | -macos*)
+ vendor=apple
+ ;;
+ -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+ vendor=atari
+ ;;
+ -vos*)
+ vendor=stratus
+ ;;
+ esac
+ basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
+ ;;
+esac
+
+echo $basic_machine$os
+exit
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
diff --git a/configure b/configure
new file mode 100755
index 0000000..635e48d
--- /dev/null
+++ b/configure
@@ -0,0 +1,19793 @@
+#! /bin/sh
+# Guess values for system-dependent variables and create Makefiles.
+# Generated by GNU Autoconf 2.69 for corosync 3.1.8.
+#
+# Report bugs to <users@clusterlabs.org>.
+#
+#
+# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
+#
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in #(
+ *posix*) :
+ set -o posix ;; #(
+ *) :
+ ;;
+esac
+fi
+
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='print -r --'
+ as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='printf %s\n'
+ as_echo_n='printf %s'
+else
+ if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+ as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+ as_echo_n='/usr/ucb/echo -n'
+ else
+ as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+ as_echo_n_body='eval
+ arg=$1;
+ case $arg in #(
+ *"$as_nl"*)
+ expr "X$arg" : "X\\(.*\\)$as_nl";
+ arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+ esac;
+ expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+ '
+ export as_echo_n_body
+ as_echo_n='sh -c $as_echo_n_body as_echo'
+ fi
+ export as_echo_body
+ as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ PATH_SEPARATOR=:
+ (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+ (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+ PATH_SEPARATOR=';'
+ }
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order. Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" "" $as_nl"
+
+# Find who we are. Look in the path if we contain no directory separator.
+as_myself=
+case $0 in #((
+ *[\\/]* ) as_myself=$0 ;;
+ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+ as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+ $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+ exit 1
+fi
+
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there. '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+# Use a proper internal environment variable to ensure we don't fall
+ # into an infinite loop, continuously re-executing ourselves.
+ if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then
+ _as_can_reexec=no; export _as_can_reexec;
+ # We cannot yet assume a decent shell, so we have to provide a
+# neutralization value for shells without unset; and this also
+# works around shells that cannot unset nonexistent variables.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in # ((((
+ *v*x* | *x*v* ) as_opts=-vx ;;
+ *v* ) as_opts=-v ;;
+ *x* ) as_opts=-x ;;
+ * ) as_opts= ;;
+esac
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed `exec'.
+$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
+as_fn_exit 255
+ fi
+ # We don't want this to propagate to other subprocesses.
+ { _as_can_reexec=; unset _as_can_reexec;}
+if test "x$CONFIG_SHELL" = x; then
+ as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then :
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '\${1+\"\$@\"}'='\"\$@\"'
+ setopt NO_GLOB_SUBST
+else
+ case \`(set -o) 2>/dev/null\` in #(
+ *posix*) :
+ set -o posix ;; #(
+ *) :
+ ;;
+esac
+fi
+"
+ as_required="as_fn_return () { (exit \$1); }
+as_fn_success () { as_fn_return 0; }
+as_fn_failure () { as_fn_return 1; }
+as_fn_ret_success () { return 0; }
+as_fn_ret_failure () { return 1; }
+
+exitcode=0
+as_fn_success || { exitcode=1; echo as_fn_success failed.; }
+as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; }
+as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; }
+as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; }
+if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then :
+
+else
+ exitcode=1; echo positional parameters were not saved.
+fi
+test x\$exitcode = x0 || exit 1
+test -x / || exit 1"
+ as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO
+ as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO
+ eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" &&
+ test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1
+test \$(( 1 + 1 )) = 2 || exit 1
+
+ test -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || (
+ ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+ ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO
+ ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO
+ PATH=/empty FPATH=/empty; export PATH FPATH
+ test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\
+ || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || exit 1"
+ if (eval "$as_required") 2>/dev/null; then :
+ as_have_required=yes
+else
+ as_have_required=no
+fi
+ if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then :
+
+else
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+as_found=false
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ as_found=:
+ case $as_dir in #(
+ /*)
+ for as_base in sh bash ksh sh5; do
+ # Try only shells that exist, to save several forks.
+ as_shell=$as_dir/$as_base
+ if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&
+ { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then :
+ CONFIG_SHELL=$as_shell as_have_required=yes
+ if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then :
+ break 2
+fi
+fi
+ done;;
+ esac
+ as_found=false
+done
+$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } &&
+ { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then :
+ CONFIG_SHELL=$SHELL as_have_required=yes
+fi; }
+IFS=$as_save_IFS
+
+
+ if test "x$CONFIG_SHELL" != x; then :
+ export CONFIG_SHELL
+ # We cannot yet assume a decent shell, so we have to provide a
+# neutralization value for shells without unset; and this also
+# works around shells that cannot unset nonexistent variables.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in # ((((
+ *v*x* | *x*v* ) as_opts=-vx ;;
+ *v* ) as_opts=-v ;;
+ *x* ) as_opts=-x ;;
+ * ) as_opts= ;;
+esac
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed `exec'.
+$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
+exit 255
+fi
+
+ if test x$as_have_required = xno; then :
+ $as_echo "$0: This script requires a shell more modern than all"
+ $as_echo "$0: the shells that I found on your system."
+ if test x${ZSH_VERSION+set} = xset ; then
+ $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should"
+ $as_echo "$0: be upgraded to zsh 4.3.4 or later."
+ else
+ $as_echo "$0: Please tell bug-autoconf@gnu.org and
+$0: users@clusterlabs.org about your system, including any
+$0: error possibly output before this message. Then install
+$0: a modern shell, or manually run the script under such a
+$0: shell if you do have one."
+ fi
+ exit 1
+fi
+fi
+fi
+SHELL=${CONFIG_SHELL-/bin/sh}
+export SHELL
+# Unset more variables known to interfere with behavior of common tools.
+CLICOLOR_FORCE= GREP_OPTIONS=
+unset CLICOLOR_FORCE GREP_OPTIONS
+
+## --------------------- ##
+## M4sh Shell Functions. ##
+## --------------------- ##
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+ { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+ return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+ set +e
+ as_fn_set_status $1
+ exit $1
+} # as_fn_exit
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+ case $as_dir in #(
+ -*) as_dir=./$as_dir;;
+ esac
+ test -d "$as_dir" || eval $as_mkdir_p || {
+ as_dirs=
+ while :; do
+ case $as_dir in #(
+ *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+ *) as_qdir=$as_dir;;
+ esac
+ as_dirs="'$as_qdir' $as_dirs"
+ as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ test -d "$as_dir" && break
+ done
+ test -z "$as_dirs" || eval "mkdir $as_dirs"
+ } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
+
+
+} # as_fn_mkdir_p
+
+# as_fn_executable_p FILE
+# -----------------------
+# Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+ test -f "$1" && test -x "$1"
+} # as_fn_executable_p
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+ eval 'as_fn_append ()
+ {
+ eval $1+=\$2
+ }'
+else
+ as_fn_append ()
+ {
+ eval $1=\$$1\$2
+ }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+ eval 'as_fn_arith ()
+ {
+ as_val=$(( $* ))
+ }'
+else
+ as_fn_arith ()
+ {
+ as_val=`expr "$@" || test $? -eq 1`
+ }
+fi # as_fn_arith
+
+
+# as_fn_error STATUS ERROR [LINENO LOG_FD]
+# ----------------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with STATUS, using 1 if that was 0.
+as_fn_error ()
+{
+ as_status=$1; test $as_status -eq 0 && as_status=1
+ if test "$4"; then
+ as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+ fi
+ $as_echo "$as_me: error: $2" >&2
+ as_fn_exit $as_status
+} # as_fn_error
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+ test "X`expr 00001 : '.*\(...\)'`" = X001; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+ as_basename=basename
+else
+ as_basename=false
+fi
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+ as_dirname=dirname
+else
+ as_dirname=false
+fi
+
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+
+ as_lineno_1=$LINENO as_lineno_1a=$LINENO
+ as_lineno_2=$LINENO as_lineno_2a=$LINENO
+ eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" &&
+ test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || {
+ # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-)
+ sed -n '
+ p
+ /[$]LINENO/=
+ ' <$as_myself |
+ sed '
+ s/[$]LINENO.*/&-/
+ t lineno
+ b
+ :lineno
+ N
+ :loop
+ s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
+ t loop
+ s/-\n.*//
+ ' >$as_me.lineno &&
+ chmod +x "$as_me.lineno" ||
+ { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
+
+ # If we had to re-execute with $CONFIG_SHELL, we're ensured to have
+ # already done that, so ensure we don't try to do so again and fall
+ # in an infinite loop. This has already happened in practice.
+ _as_can_reexec=no; export _as_can_reexec
+ # Don't try to exec as it changes $[0], causing all sort of problems
+ # (the dirname of $[0] is not the place where we might find the
+ # original and so on. Autoconf is especially sensitive to this).
+ . "./$as_me.lineno"
+ # Exit status is that of the last command.
+ exit
+}
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in #(((((
+-n*)
+ case `echo 'xy\c'` in
+ *c*) ECHO_T=' ';; # ECHO_T is single tab character.
+ xy) ECHO_C='\c';;
+ *) echo `echo ksh88 bug on AIX 6.1` > /dev/null
+ ECHO_T=' ';;
+ esac;;
+*)
+ ECHO_N='-n';;
+esac
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+ rm -f conf$$.dir/conf$$.file
+else
+ rm -f conf$$.dir
+ mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+ if ln -s conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s='ln -s'
+ # ... but there are two gotchas:
+ # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+ # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+ # In both cases, we have to default to `cp -pR'.
+ ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+ as_ln_s='cp -pR'
+ elif ln conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s=ln
+ else
+ as_ln_s='cp -pR'
+ fi
+else
+ as_ln_s='cp -pR'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+if mkdir -p . 2>/dev/null; then
+ as_mkdir_p='mkdir -p "$as_dir"'
+else
+ test -d ./-p && rmdir ./-p
+ as_mkdir_p=false
+fi
+
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+
+test -n "$DJDIR" || exec 7<&0 </dev/null
+exec 6>&1
+
+# Name of the host.
+# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status,
+# so uname gets run too.
+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
+
+#
+# Initializations.
+#
+ac_default_prefix=/usr/local
+ac_clean_files=
+ac_config_libobj_dir=.
+LIBOBJS=
+cross_compiling=no
+subdirs=
+MFLAGS=
+MAKEFLAGS=
+
+# Identity of this package.
+PACKAGE_NAME='corosync'
+PACKAGE_TARNAME='corosync'
+PACKAGE_VERSION='3.1.8'
+PACKAGE_STRING='corosync 3.1.8'
+PACKAGE_BUGREPORT='users@clusterlabs.org'
+PACKAGE_URL=''
+
+# Factoring default headers for most tests.
+ac_includes_default="\
+#include <stdio.h>
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# ifdef HAVE_STDLIB_H
+# include <stdlib.h>
+# endif
+#endif
+#ifdef HAVE_STRING_H
+# if !defined STDC_HEADERS && defined HAVE_MEMORY_H
+# include <memory.h>
+# endif
+# include <string.h>
+#endif
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif
+#ifdef HAVE_INTTYPES_H
+# include <inttypes.h>
+#endif
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif"
+
+ac_unique_file="lib/cpg.c"
+ac_header_list=
+ac_subst_vars='am__EXEEXT_FALSE
+am__EXEEXT_TRUE
+LTLIBOBJS
+COROSYSCONFDIR
+LINT_FLAGS
+BUILD_HTML_DOCS_FALSE
+BUILD_HTML_DOCS_TRUE
+AUGTOOL_FALSE
+AUGTOOL_TRUE
+INSTALL_DBUSCONF_FALSE
+INSTALL_DBUSCONF_TRUE
+INSTALL_MIB_FALSE
+INSTALL_MIB_TRUE
+RUST_TARGET_DIR
+RUST_FLAGS
+SONAME
+SOMICRO
+SOMINOR
+SOMAJOR
+LOGROTATEDIR
+LOGDIR
+SYSTEMDDIR
+INITDDIR
+VERSCRIPT_LDFLAGS
+BUILD_SNMP_FALSE
+BUILD_SNMP_TRUE
+SNMP_LIBS
+SNMPCONFIG
+nozzle_LIBS
+nozzle_CFLAGS
+VQSIM_READLINE_FALSE
+VQSIM_READLINE_TRUE
+libsystemd_LIBS
+libsystemd_CFLAGS
+statgrabge090_LIBS
+statgrabge090_CFLAGS
+statgrab_LIBS
+statgrab_CFLAGS
+DBUS_LIBS
+DBUS_CFLAGS
+BUILD_VQSIM_FALSE
+BUILD_VQSIM_TRUE
+INSTALL_XMLCONF_FALSE
+INSTALL_XMLCONF_TRUE
+INITCONFIGDIR
+INSTALL_SYSTEMD_FALSE
+INSTALL_SYSTEMD_TRUE
+INSTALL_AUGEAS_FALSE
+INSTALL_AUGEAS_TRUE
+BUILD_WATCHDOG_FALSE
+BUILD_WATCHDOG_TRUE
+BUILD_MONITORING_FALSE
+BUILD_MONITORING_TRUE
+CMAP_SONAME
+VOTEQUORUM_SONAME
+SAM_SONAME
+QUORUM_SONAME
+CPG_SONAME
+CFG_SONAME
+RUSTFMT
+CLIPPY
+BINDGEN
+RUSTDOC
+RUSTC
+CARGO
+LIBOBJS
+ALLOCA
+HAVE_CRC32_FALSE
+HAVE_CRC32_TRUE
+knet_LIBS
+knet_CFLAGS
+HAVE_QB_LOG_FILE_REOPEN_FALSE
+HAVE_QB_LOG_FILE_REOPEN_TRUE
+LIBQB_LIBS
+LIBQB_CFLAGS
+BASHPATH
+DOXYGEN
+DOT
+AUGTOOL
+GROFF
+PKG_CONFIG_LIBDIR
+PKG_CONFIG_PATH
+PKG_CONFIG
+corosyncrustver
+BUILD_RUST_BINDINGS_FALSE
+BUILD_RUST_BINDINGS_TRUE
+WITH_LIST
+OTOOL64
+OTOOL
+LIPO
+NMEDIT
+DSYMUTIL
+MANIFEST_TOOL
+RANLIB
+ac_ct_AR
+AR
+DLLTOOL
+OBJDUMP
+LN_S
+NM
+ac_ct_DUMPBIN
+DUMPBIN
+LD
+FGREP
+SED
+host_os
+host_vendor
+host_cpu
+host
+build_os
+build_vendor
+build_cpu
+build
+LIBTOOL
+AM_BACKSLASH
+AM_DEFAULT_VERBOSITY
+AM_DEFAULT_V
+AM_V
+am__fastdepCC_FALSE
+am__fastdepCC_TRUE
+CCDEPMODE
+am__nodep
+AMDEPBACKSLASH
+AMDEP_FALSE
+AMDEP_TRUE
+am__quote
+am__include
+DEPDIR
+am__untar
+am__tar
+AMTAR
+am__leading_dot
+SET_MAKE
+AWK
+mkdir_p
+MKDIR_P
+INSTALL_STRIP_PROGRAM
+STRIP
+install_sh
+MAKEINFO
+AUTOHEADER
+AUTOMAKE
+AUTOCONF
+ACLOCAL
+VERSION
+PACKAGE
+CYGPATH_W
+am__isrc
+INSTALL_DATA
+INSTALL_SCRIPT
+INSTALL_PROGRAM
+EGREP
+GREP
+CPP
+OBJEXT
+EXEEXT
+ac_ct_CC
+CPPFLAGS
+LDFLAGS
+CFLAGS
+CC
+target_alias
+host_alias
+build_alias
+LIBS
+ECHO_T
+ECHO_N
+ECHO_C
+DEFS
+mandir
+localedir
+libdir
+psdir
+pdfdir
+dvidir
+htmldir
+infodir
+docdir
+oldincludedir
+includedir
+localstatedir
+sharedstatedir
+sysconfdir
+datadir
+datarootdir
+libexecdir
+sbindir
+bindir
+program_transform_name
+prefix
+exec_prefix
+PACKAGE_URL
+PACKAGE_BUGREPORT
+PACKAGE_STRING
+PACKAGE_VERSION
+PACKAGE_TARNAME
+PACKAGE_NAME
+PATH_SEPARATOR
+SHELL'
+ac_subst_files=''
+ac_user_opts='
+enable_option_checking
+enable_dependency_tracking
+enable_silent_rules
+enable_shared
+enable_static
+with_pic
+enable_fast_install
+with_gnu_ld
+with_sysroot
+enable_libtool_lock
+enable_interlib_deps
+enable_rust_bindings
+enable_ansi
+enable_fatal_warnings
+enable_debug
+with_sanitizers
+enable_secure_build
+enable_user_flags
+enable_coverage
+enable_small_memory_footprint
+enable_dbus
+enable_monitoring
+enable_watchdog
+enable_augeas
+enable_systemd
+with_initconfigdir
+with_initddir
+with_systemddir
+with_logdir
+with_logrotatedir
+enable_snmp
+enable_xmlconf
+enable_vqsim
+enable_nozzle
+'
+ ac_precious_vars='build_alias
+host_alias
+target_alias
+CC
+CFLAGS
+LDFLAGS
+LIBS
+CPPFLAGS
+CPP
+PKG_CONFIG
+PKG_CONFIG_PATH
+PKG_CONFIG_LIBDIR
+LIBQB_CFLAGS
+LIBQB_LIBS
+knet_CFLAGS
+knet_LIBS
+DBUS_CFLAGS
+DBUS_LIBS
+statgrab_CFLAGS
+statgrab_LIBS
+statgrabge090_CFLAGS
+statgrabge090_LIBS
+libsystemd_CFLAGS
+libsystemd_LIBS
+nozzle_CFLAGS
+nozzle_LIBS'
+
+
+# Initialize some variables set by options.
+ac_init_help=
+ac_init_version=false
+ac_unrecognized_opts=
+ac_unrecognized_sep=
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+cache_file=/dev/null
+exec_prefix=NONE
+no_create=
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+verbose=
+x_includes=NONE
+x_libraries=NONE
+
+# Installation directory options.
+# These are left unexpanded so users can "make install exec_prefix=/foo"
+# and all the variables that are supposed to be based on exec_prefix
+# by default will actually change.
+# Use braces instead of parens because sh, perl, etc. also accept them.
+# (The list follows the same order as the GNU Coding Standards.)
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datarootdir='${prefix}/share'
+datadir='${datarootdir}'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
+infodir='${datarootdir}/info'
+htmldir='${docdir}'
+dvidir='${docdir}'
+pdfdir='${docdir}'
+psdir='${docdir}'
+libdir='${exec_prefix}/lib'
+localedir='${datarootdir}/locale'
+mandir='${datarootdir}/man'
+
+ac_prev=
+ac_dashdash=
+for ac_option
+do
+ # If the previous option needs an argument, assign it.
+ if test -n "$ac_prev"; then
+ eval $ac_prev=\$ac_option
+ ac_prev=
+ continue
+ fi
+
+ case $ac_option in
+ *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
+ *=) ac_optarg= ;;
+ *) ac_optarg=yes ;;
+ esac
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case $ac_dashdash$ac_option in
+ --)
+ ac_dashdash=yes ;;
+
+ -bindir | --bindir | --bindi | --bind | --bin | --bi)
+ ac_prev=bindir ;;
+ -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+ bindir=$ac_optarg ;;
+
+ -build | --build | --buil | --bui | --bu)
+ ac_prev=build_alias ;;
+ -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+ build_alias=$ac_optarg ;;
+
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+ cache_file=$ac_optarg ;;
+
+ --config-cache | -C)
+ cache_file=config.cache ;;
+
+ -datadir | --datadir | --datadi | --datad)
+ ac_prev=datadir ;;
+ -datadir=* | --datadir=* | --datadi=* | --datad=*)
+ datadir=$ac_optarg ;;
+
+ -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \
+ | --dataroo | --dataro | --datar)
+ ac_prev=datarootdir ;;
+ -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \
+ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*)
+ datarootdir=$ac_optarg ;;
+
+ -disable-* | --disable-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ as_fn_error $? "invalid feature name: $ac_useropt"
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"enable_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval enable_$ac_useropt=no ;;
+
+ -docdir | --docdir | --docdi | --doc | --do)
+ ac_prev=docdir ;;
+ -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*)
+ docdir=$ac_optarg ;;
+
+ -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv)
+ ac_prev=dvidir ;;
+ -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*)
+ dvidir=$ac_optarg ;;
+
+ -enable-* | --enable-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ as_fn_error $? "invalid feature name: $ac_useropt"
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"enable_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval enable_$ac_useropt=\$ac_optarg ;;
+
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+ | --exec | --exe | --ex)
+ ac_prev=exec_prefix ;;
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+ | --exec=* | --exe=* | --ex=*)
+ exec_prefix=$ac_optarg ;;
+
+ -gas | --gas | --ga | --g)
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
+
+ -help | --help | --hel | --he | -h)
+ ac_init_help=long ;;
+ -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
+ ac_init_help=recursive ;;
+ -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
+ ac_init_help=short ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host_alias ;;
+ -host=* | --host=* | --hos=* | --ho=*)
+ host_alias=$ac_optarg ;;
+
+ -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht)
+ ac_prev=htmldir ;;
+ -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \
+ | --ht=*)
+ htmldir=$ac_optarg ;;
+
+ -includedir | --includedir | --includedi | --included | --include \
+ | --includ | --inclu | --incl | --inc)
+ ac_prev=includedir ;;
+ -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+ | --includ=* | --inclu=* | --incl=* | --inc=*)
+ includedir=$ac_optarg ;;
+
+ -infodir | --infodir | --infodi | --infod | --info | --inf)
+ ac_prev=infodir ;;
+ -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+ infodir=$ac_optarg ;;
+
+ -libdir | --libdir | --libdi | --libd)
+ ac_prev=libdir ;;
+ -libdir=* | --libdir=* | --libdi=* | --libd=*)
+ libdir=$ac_optarg ;;
+
+ -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+ | --libexe | --libex | --libe)
+ ac_prev=libexecdir ;;
+ -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+ | --libexe=* | --libex=* | --libe=*)
+ libexecdir=$ac_optarg ;;
+
+ -localedir | --localedir | --localedi | --localed | --locale)
+ ac_prev=localedir ;;
+ -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*)
+ localedir=$ac_optarg ;;
+
+ -localstatedir | --localstatedir | --localstatedi | --localstated \
+ | --localstate | --localstat | --localsta | --localst | --locals)
+ ac_prev=localstatedir ;;
+ -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*)
+ localstatedir=$ac_optarg ;;
+
+ -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+ ac_prev=mandir ;;
+ -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+ mandir=$ac_optarg ;;
+
+ -nfp | --nfp | --nf)
+ # Obsolete; use --without-fp.
+ with_fp=no ;;
+
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c | -n)
+ no_create=yes ;;
+
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+ no_recursion=yes ;;
+
+ -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+ | --oldin | --oldi | --old | --ol | --o)
+ ac_prev=oldincludedir ;;
+ -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+ oldincludedir=$ac_optarg ;;
+
+ -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+ ac_prev=prefix ;;
+ -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+ prefix=$ac_optarg ;;
+
+ -program-prefix | --program-prefix | --program-prefi | --program-pref \
+ | --program-pre | --program-pr | --program-p)
+ ac_prev=program_prefix ;;
+ -program-prefix=* | --program-prefix=* | --program-prefi=* \
+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+ program_prefix=$ac_optarg ;;
+
+ -program-suffix | --program-suffix | --program-suffi | --program-suff \
+ | --program-suf | --program-su | --program-s)
+ ac_prev=program_suffix ;;
+ -program-suffix=* | --program-suffix=* | --program-suffi=* \
+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+ program_suffix=$ac_optarg ;;
+
+ -program-transform-name | --program-transform-name \
+ | --program-transform-nam | --program-transform-na \
+ | --program-transform-n | --program-transform- \
+ | --program-transform | --program-transfor \
+ | --program-transfo | --program-transf \
+ | --program-trans | --program-tran \
+ | --progr-tra | --program-tr | --program-t)
+ ac_prev=program_transform_name ;;
+ -program-transform-name=* | --program-transform-name=* \
+ | --program-transform-nam=* | --program-transform-na=* \
+ | --program-transform-n=* | --program-transform-=* \
+ | --program-transform=* | --program-transfor=* \
+ | --program-transfo=* | --program-transf=* \
+ | --program-trans=* | --program-tran=* \
+ | --progr-tra=* | --program-tr=* | --program-t=*)
+ program_transform_name=$ac_optarg ;;
+
+ -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd)
+ ac_prev=pdfdir ;;
+ -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*)
+ pdfdir=$ac_optarg ;;
+
+ -psdir | --psdir | --psdi | --psd | --ps)
+ ac_prev=psdir ;;
+ -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*)
+ psdir=$ac_optarg ;;
+
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ silent=yes ;;
+
+ -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+ ac_prev=sbindir ;;
+ -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+ | --sbi=* | --sb=*)
+ sbindir=$ac_optarg ;;
+
+ -sharedstatedir | --sharedstatedir | --sharedstatedi \
+ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+ | --sharedst | --shareds | --shared | --share | --shar \
+ | --sha | --sh)
+ ac_prev=sharedstatedir ;;
+ -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+ | --sha=* | --sh=*)
+ sharedstatedir=$ac_optarg ;;
+
+ -site | --site | --sit)
+ ac_prev=site ;;
+ -site=* | --site=* | --sit=*)
+ site=$ac_optarg ;;
+
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+ srcdir=$ac_optarg ;;
+
+ -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+ | --syscon | --sysco | --sysc | --sys | --sy)
+ ac_prev=sysconfdir ;;
+ -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+ sysconfdir=$ac_optarg ;;
+
+ -target | --target | --targe | --targ | --tar | --ta | --t)
+ ac_prev=target_alias ;;
+ -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+ target_alias=$ac_optarg ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers | -V)
+ ac_init_version=: ;;
+
+ -with-* | --with-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ as_fn_error $? "invalid package name: $ac_useropt"
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"with_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval with_$ac_useropt=\$ac_optarg ;;
+
+ -without-* | --without-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ as_fn_error $? "invalid package name: $ac_useropt"
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"with_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval with_$ac_useropt=no ;;
+
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
+
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+ | --x-incl | --x-inc | --x-in | --x-i)
+ ac_prev=x_includes ;;
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+ x_includes=$ac_optarg ;;
+
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+ ac_prev=x_libraries ;;
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+ x_libraries=$ac_optarg ;;
+
+ -*) as_fn_error $? "unrecognized option: \`$ac_option'
+Try \`$0 --help' for more information"
+ ;;
+
+ *=*)
+ ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
+ # Reject names that are not valid shell variable names.
+ case $ac_envvar in #(
+ '' | [0-9]* | *[!_$as_cr_alnum]* )
+ as_fn_error $? "invalid variable name: \`$ac_envvar'" ;;
+ esac
+ eval $ac_envvar=\$ac_optarg
+ export $ac_envvar ;;
+
+ *)
+ # FIXME: should be removed in autoconf 3.0.
+ $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+ expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+ $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2
+ : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}"
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ ac_option=--`echo $ac_prev | sed 's/_/-/g'`
+ as_fn_error $? "missing argument to $ac_option"
+fi
+
+if test -n "$ac_unrecognized_opts"; then
+ case $enable_option_checking in
+ no) ;;
+ fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;;
+ *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;;
+ esac
+fi
+
+# Check all directory arguments for consistency.
+for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \
+ datadir sysconfdir sharedstatedir localstatedir includedir \
+ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
+ libdir localedir mandir
+do
+ eval ac_val=\$$ac_var
+ # Remove trailing slashes.
+ case $ac_val in
+ */ )
+ ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'`
+ eval $ac_var=\$ac_val;;
+ esac
+ # Be sure to have absolute directory names.
+ case $ac_val in
+ [\\/$]* | ?:[\\/]* ) continue;;
+ NONE | '' ) case $ac_var in *prefix ) continue;; esac;;
+ esac
+ as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val"
+done
+
+# There might be people who depend on the old broken behavior: `$host'
+# used to hold the argument of --host etc.
+# FIXME: To remove some day.
+build=$build_alias
+host=$host_alias
+target=$target_alias
+
+# FIXME: To remove some day.
+if test "x$host_alias" != x; then
+ if test "x$build_alias" = x; then
+ cross_compiling=maybe
+ elif test "x$build_alias" != "x$host_alias"; then
+ cross_compiling=yes
+ fi
+fi
+
+ac_tool_prefix=
+test -n "$host_alias" && ac_tool_prefix=$host_alias-
+
+test "$silent" = yes && exec 6>/dev/null
+
+
+ac_pwd=`pwd` && test -n "$ac_pwd" &&
+ac_ls_di=`ls -di .` &&
+ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` ||
+ as_fn_error $? "working directory cannot be determined"
+test "X$ac_ls_di" = "X$ac_pwd_ls_di" ||
+ as_fn_error $? "pwd does not report name of working directory"
+
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+ ac_srcdir_defaulted=yes
+ # Try the directory containing this script, then the parent directory.
+ ac_confdir=`$as_dirname -- "$as_myself" ||
+$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_myself" : 'X\(//\)[^/]' \| \
+ X"$as_myself" : 'X\(//\)$' \| \
+ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_myself" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ srcdir=$ac_confdir
+ if test ! -r "$srcdir/$ac_unique_file"; then
+ srcdir=..
+ fi
+else
+ ac_srcdir_defaulted=no
+fi
+if test ! -r "$srcdir/$ac_unique_file"; then
+ test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .."
+ as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir"
+fi
+ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work"
+ac_abs_confdir=`(
+ cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg"
+ pwd)`
+# When building in place, set srcdir=.
+if test "$ac_abs_confdir" = "$ac_pwd"; then
+ srcdir=.
+fi
+# Remove unnecessary trailing slashes from srcdir.
+# Double slashes in file names in object file debugging info
+# mess up M-x gdb in Emacs.
+case $srcdir in
+*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;;
+esac
+for ac_var in $ac_precious_vars; do
+ eval ac_env_${ac_var}_set=\${${ac_var}+set}
+ eval ac_env_${ac_var}_value=\$${ac_var}
+ eval ac_cv_env_${ac_var}_set=\${${ac_var}+set}
+ eval ac_cv_env_${ac_var}_value=\$${ac_var}
+done
+
+#
+# Report the --help message.
+#
+if test "$ac_init_help" = "long"; then
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat <<_ACEOF
+\`configure' configures corosync 3.1.8 to adapt to many kinds of systems.
+
+Usage: $0 [OPTION]... [VAR=VALUE]...
+
+To assign environment variables (e.g., CC, CFLAGS...), specify them as
+VAR=VALUE. See below for descriptions of some of the useful variables.
+
+Defaults for the options are specified in brackets.
+
+Configuration:
+ -h, --help display this help and exit
+ --help=short display options specific to this package
+ --help=recursive display the short help of all the included packages
+ -V, --version display version information and exit
+ -q, --quiet, --silent do not print \`checking ...' messages
+ --cache-file=FILE cache test results in FILE [disabled]
+ -C, --config-cache alias for \`--cache-file=config.cache'
+ -n, --no-create do not create output files
+ --srcdir=DIR find the sources in DIR [configure dir or \`..']
+
+Installation directories:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_prefix]
+ --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
+ [PREFIX]
+
+By default, \`make install' will install all the files in
+\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify
+an installation prefix other than \`$ac_default_prefix' using \`--prefix',
+for instance \`--prefix=\$HOME'.
+
+For better control, use the options below.
+
+Fine tuning of the installation directories:
+ --bindir=DIR user executables [EPREFIX/bin]
+ --sbindir=DIR system admin executables [EPREFIX/sbin]
+ --libexecdir=DIR program executables [EPREFIX/libexec]
+ --sysconfdir=DIR read-only single-machine data [PREFIX/etc]
+ --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
+ --localstatedir=DIR modifiable single-machine data [PREFIX/var]
+ --libdir=DIR object code libraries [EPREFIX/lib]
+ --includedir=DIR C header files [PREFIX/include]
+ --oldincludedir=DIR C header files for non-gcc [/usr/include]
+ --datarootdir=DIR read-only arch.-independent data root [PREFIX/share]
+ --datadir=DIR read-only architecture-independent data [DATAROOTDIR]
+ --infodir=DIR info documentation [DATAROOTDIR/info]
+ --localedir=DIR locale-dependent data [DATAROOTDIR/locale]
+ --mandir=DIR man documentation [DATAROOTDIR/man]
+ --docdir=DIR documentation root [DATAROOTDIR/doc/corosync]
+ --htmldir=DIR html documentation [DOCDIR]
+ --dvidir=DIR dvi documentation [DOCDIR]
+ --pdfdir=DIR pdf documentation [DOCDIR]
+ --psdir=DIR ps documentation [DOCDIR]
+_ACEOF
+
+ cat <<\_ACEOF
+
+Program names:
+ --program-prefix=PREFIX prepend PREFIX to installed program names
+ --program-suffix=SUFFIX append SUFFIX to installed program names
+ --program-transform-name=PROGRAM run sed PROGRAM on installed program names
+
+System types:
+ --build=BUILD configure for building on BUILD [guessed]
+ --host=HOST cross-compile to build programs to run on HOST [BUILD]
+_ACEOF
+fi
+
+if test -n "$ac_init_help"; then
+ case $ac_init_help in
+ short | recursive ) echo "Configuration of corosync 3.1.8:";;
+ esac
+ cat <<\_ACEOF
+
+Optional Features:
+ --disable-option-checking ignore unrecognized --enable/--with options
+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --enable-dependency-tracking
+ do not reject slow dependency extractors
+ --disable-dependency-tracking
+ speeds up one-time build
+ --enable-silent-rules less verbose build output (undo: "make V=1")
+ --disable-silent-rules verbose build output (undo: "make V=0")
+ --enable-shared[=PKGS] build shared libraries [default=yes]
+ --enable-static[=PKGS] build static libraries [default=yes]
+ --enable-fast-install[=PKGS]
+ optimize for fast installation [default=yes]
+ --disable-libtool-lock avoid locking (might break parallel builds)
+ --disable-interlib-deps
+ disable inter-library dependencies (might break
+ builds)
+ --enable-rust-bindings rust bindings support
+ --enable-ansi : force to build with ANSI standards.
+ --enable-fatal-warnings : enable fatal warnings.
+ --enable-debug : enable debug build.
+ --enable-secure-build : enable PIE/RELRO build.
+ --enable-user-flags : rely on user environment.
+ --enable-coverage : coverage analysis of the codebase.
+ --enable-small-memory-footprint : Use small message queues and small messages sizes.
+ --enable-dbus : dbus events.
+ --enable-monitoring : resource monitoring
+ --enable-watchdog : Watchdog support
+ --enable-augeas : Install the augeas lens for corosync.conf
+ --enable-systemd : Install systemd service files
+ --enable-snmp : SNMP protocol support
+ --enable-xmlconf : XML configuration support
+ --enable-vqsim : Quorum simulator support
+ --enable-nozzle : Support for nozzle
+
+Optional Packages:
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --with-pic[=PKGS] try to use only PIC/non-PIC objects [default=use
+ both]
+ --with-gnu-ld assume the C compiler uses GNU ld [default=no]
+ --with-sysroot=DIR Search for dependent libraries within DIR
+ (or the compiler's sysroot if not specified).
+ --with-sanitizers=...,...
+ enable SANitizer build, do *NOT* use for production.
+ Only ASAN/UBSAN/TSAN are currently supported
+ --with-initconfigdir=DIR
+ configuration directory [SYSCONFDIR/sysconfig]
+ --with-initddir=DIR : path to init script directory.
+ --with-systemddir=DIR : path to systemd unit files directory.
+ --with-logdir=DIR : the base directory for corosync logging files.
+ --with-logrotatedir=DIR : the base directory for logrorate.d files.
+
+Some influential environment variables:
+ CC C compiler command
+ CFLAGS C compiler flags
+ LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a
+ nonstandard directory <lib dir>
+ LIBS libraries to pass to the linker, e.g. -l<library>
+ CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if
+ you have headers in a nonstandard directory <include dir>
+ CPP C preprocessor
+ PKG_CONFIG path to pkg-config utility
+ PKG_CONFIG_PATH
+ directories to add to pkg-config's search path
+ PKG_CONFIG_LIBDIR
+ path overriding pkg-config's built-in search path
+ LIBQB_CFLAGS
+ C compiler flags for LIBQB, overriding pkg-config
+ LIBQB_LIBS linker flags for LIBQB, overriding pkg-config
+ knet_CFLAGS C compiler flags for knet, overriding pkg-config
+ knet_LIBS linker flags for knet, overriding pkg-config
+ DBUS_CFLAGS C compiler flags for DBUS, overriding pkg-config
+ DBUS_LIBS linker flags for DBUS, overriding pkg-config
+ statgrab_CFLAGS
+ C compiler flags for statgrab, overriding pkg-config
+ statgrab_LIBS
+ linker flags for statgrab, overriding pkg-config
+ statgrabge090_CFLAGS
+ C compiler flags for statgrabge090, overriding pkg-config
+ statgrabge090_LIBS
+ linker flags for statgrabge090, overriding pkg-config
+ libsystemd_CFLAGS
+ C compiler flags for libsystemd, overriding pkg-config
+ libsystemd_LIBS
+ linker flags for libsystemd, overriding pkg-config
+ nozzle_CFLAGS
+ C compiler flags for nozzle, overriding pkg-config
+ nozzle_LIBS linker flags for nozzle, overriding pkg-config
+
+Use these variables to override the choices made by `configure' or to help
+it to find libraries and programs with nonstandard names/locations.
+
+Report bugs to <users@clusterlabs.org>.
+_ACEOF
+ac_status=$?
+fi
+
+if test "$ac_init_help" = "recursive"; then
+ # If there are subdirs, report their specific --help.
+ for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
+ test -d "$ac_dir" ||
+ { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } ||
+ continue
+ ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+ ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+ # A ".." for each directory in $ac_dir_suffix.
+ ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+ case $ac_top_builddir_sub in
+ "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+ *) ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+ esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+ .) # We are building in place.
+ ac_srcdir=.
+ ac_top_srcdir=$ac_top_builddir_sub
+ ac_abs_top_srcdir=$ac_pwd ;;
+ [\\/]* | ?:[\\/]* ) # Absolute name.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir
+ ac_abs_top_srcdir=$srcdir ;;
+ *) # Relative name.
+ ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_build_prefix$srcdir
+ ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+ cd "$ac_dir" || { ac_status=$?; continue; }
+ # Check for guested configure.
+ if test -f "$ac_srcdir/configure.gnu"; then
+ echo &&
+ $SHELL "$ac_srcdir/configure.gnu" --help=recursive
+ elif test -f "$ac_srcdir/configure"; then
+ echo &&
+ $SHELL "$ac_srcdir/configure" --help=recursive
+ else
+ $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+ fi || ac_status=$?
+ cd "$ac_pwd" || { ac_status=$?; break; }
+ done
+fi
+
+test -n "$ac_init_help" && exit $ac_status
+if $ac_init_version; then
+ cat <<\_ACEOF
+corosync configure 3.1.8
+generated by GNU Autoconf 2.69
+
+Copyright (C) 2012 Free Software Foundation, Inc.
+This configure script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it.
+_ACEOF
+ exit
+fi
+
+## ------------------------ ##
+## Autoconf initialization. ##
+## ------------------------ ##
+
+# ac_fn_c_try_compile LINENO
+# --------------------------
+# Try to compile conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_compile ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ rm -f conftest.$ac_objext
+ if { { ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compile") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ grep -v '^ *+' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ mv -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1
+fi
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_compile
+
+# ac_fn_c_try_cpp LINENO
+# ----------------------
+# Try to preprocess conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_cpp ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ if { { ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ grep -v '^ *+' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ mv -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } > conftest.i && {
+ test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ }; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1
+fi
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_cpp
+
+# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES
+# -------------------------------------------------------
+# Tests whether HEADER exists, giving a warning if it cannot be compiled using
+# the include files in INCLUDES and setting the cache variable VAR
+# accordingly.
+ac_fn_c_check_header_mongrel ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ if eval \${$3+:} false; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+else
+ # Is the header compilable?
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5
+$as_echo_n "checking $2 usability... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+#include <$2>
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_header_compiler=yes
+else
+ ac_header_compiler=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5
+$as_echo "$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5
+$as_echo_n "checking $2 presence... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <$2>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+ ac_header_preproc=yes
+else
+ ac_header_preproc=no
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5
+$as_echo "$ac_header_preproc" >&6; }
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #((
+ yes:no: )
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5
+$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
+ ;;
+ no:yes:* )
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5
+$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5
+$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5
+$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5
+$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
+( $as_echo "## ------------------------------------ ##
+## Report this to users@clusterlabs.org ##
+## ------------------------------------ ##"
+ ) | sed "s/^/$as_me: WARNING: /" >&2
+ ;;
+esac
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ eval "$3=\$ac_header_compiler"
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+fi
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_header_mongrel
+
+# ac_fn_c_try_run LINENO
+# ----------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes
+# that executables *can* be run.
+ac_fn_c_try_run ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ if { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && { ac_try='./conftest$ac_exeext'
+ { { case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: program exited with status $ac_status" >&5
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=$ac_status
+fi
+ rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_run
+
+# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES
+# -------------------------------------------------------
+# Tests whether HEADER exists and can be compiled using the include files in
+# INCLUDES, setting the cache variable VAR accordingly.
+ac_fn_c_check_header_compile ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+#include <$2>
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ eval "$3=yes"
+else
+ eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_header_compile
+
+# ac_fn_c_try_link LINENO
+# -----------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_link ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ rm -f conftest.$ac_objext conftest$ac_exeext
+ if { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ grep -v '^ *+' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ mv -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext && {
+ test "$cross_compiling" = yes ||
+ test -x conftest$ac_exeext
+ }; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1
+fi
+ # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information
+ # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would
+ # interfere with the next link command; also delete a directory that is
+ # left behind by Apple's compiler. We do this before executing the actions.
+ rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_link
+
+# ac_fn_c_check_func LINENO FUNC VAR
+# ----------------------------------
+# Tests whether FUNC exists, setting the cache variable VAR accordingly
+ac_fn_c_check_func ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+/* Define $2 to an innocuous variant, in case <limits.h> declares $2.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $2 innocuous_$2
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $2 (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $2
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char $2 ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined __stub_$2 || defined __stub___$2
+choke me
+#endif
+
+int
+main ()
+{
+return $2 ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ eval "$3=yes"
+else
+ eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_func
+
+# ac_fn_c_check_member LINENO AGGR MEMBER VAR INCLUDES
+# ----------------------------------------------------
+# Tries to find if the field MEMBER exists in type AGGR, after including
+# INCLUDES, setting cache variable VAR accordingly.
+ac_fn_c_check_member ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2.$3" >&5
+$as_echo_n "checking for $2.$3... " >&6; }
+if eval \${$4+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$5
+int
+main ()
+{
+static $2 ac_aggr;
+if (ac_aggr.$3)
+return 0;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ eval "$4=yes"
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$5
+int
+main ()
+{
+static $2 ac_aggr;
+if (sizeof ac_aggr.$3)
+return 0;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ eval "$4=yes"
+else
+ eval "$4=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$4
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_member
+
+# ac_fn_c_find_intX_t LINENO BITS VAR
+# -----------------------------------
+# Finds a signed integer type with width BITS, setting cache variable VAR
+# accordingly.
+ac_fn_c_find_intX_t ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for int$2_t" >&5
+$as_echo_n "checking for int$2_t... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ eval "$3=no"
+ # Order is important - never check a type that is potentially smaller
+ # than half of the expected target width.
+ for ac_type in int$2_t 'int' 'long int' \
+ 'long long int' 'short int' 'signed char'; do
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$ac_includes_default
+ enum { N = $2 / 2 - 1 };
+int
+main ()
+{
+static int test_array [1 - 2 * !(0 < ($ac_type) ((((($ac_type) 1 << N) << N) - 1) * 2 + 1))];
+test_array [0] = 0;
+return test_array [0];
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$ac_includes_default
+ enum { N = $2 / 2 - 1 };
+int
+main ()
+{
+static int test_array [1 - 2 * !(($ac_type) ((((($ac_type) 1 << N) << N) - 1) * 2 + 1)
+ < ($ac_type) ((((($ac_type) 1 << N) << N) - 1) * 2 + 2))];
+test_array [0] = 0;
+return test_array [0];
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+else
+ case $ac_type in #(
+ int$2_t) :
+ eval "$3=yes" ;; #(
+ *) :
+ eval "$3=\$ac_type" ;;
+esac
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ if eval test \"x\$"$3"\" = x"no"; then :
+
+else
+ break
+fi
+ done
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_find_intX_t
+
+# ac_fn_c_find_uintX_t LINENO BITS VAR
+# ------------------------------------
+# Finds an unsigned integer type with width BITS, setting cache variable VAR
+# accordingly.
+ac_fn_c_find_uintX_t ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for uint$2_t" >&5
+$as_echo_n "checking for uint$2_t... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ eval "$3=no"
+ # Order is important - never check a type that is potentially smaller
+ # than half of the expected target width.
+ for ac_type in uint$2_t 'unsigned int' 'unsigned long int' \
+ 'unsigned long long int' 'unsigned short int' 'unsigned char'; do
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !((($ac_type) -1 >> ($2 / 2 - 1)) >> ($2 / 2 - 1) == 3)];
+test_array [0] = 0;
+return test_array [0];
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ case $ac_type in #(
+ uint$2_t) :
+ eval "$3=yes" ;; #(
+ *) :
+ eval "$3=\$ac_type" ;;
+esac
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ if eval test \"x\$"$3"\" = x"no"; then :
+
+else
+ break
+fi
+ done
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_find_uintX_t
+
+# ac_fn_c_check_type LINENO TYPE VAR INCLUDES
+# -------------------------------------------
+# Tests whether TYPE exists after having included INCLUDES, setting cache
+# variable VAR accordingly.
+ac_fn_c_check_type ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ eval "$3=no"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+if (sizeof ($2))
+ return 0;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+if (sizeof (($2)))
+ return 0;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+else
+ eval "$3=yes"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_type
+cat >config.log <<_ACEOF
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+It was created by corosync $as_me 3.1.8, which was
+generated by GNU Autoconf 2.69. Invocation command line was
+
+ $ $0 $@
+
+_ACEOF
+exec 5>>config.log
+{
+cat <<_ASUNAME
+## --------- ##
+## Platform. ##
+## --------- ##
+
+hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
+/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown`
+
+/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown`
+/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
+/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown`
+/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown`
+/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown`
+/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown`
+
+_ASUNAME
+
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ $as_echo "PATH: $as_dir"
+ done
+IFS=$as_save_IFS
+
+} >&5
+
+cat >&5 <<_ACEOF
+
+
+## ----------- ##
+## Core tests. ##
+## ----------- ##
+
+_ACEOF
+
+
+# Keep a trace of the command line.
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Strip out --silent because we don't want to record it for future runs.
+# Also quote any args containing shell meta-characters.
+# Make two passes to allow for proper duplicate-argument suppression.
+ac_configure_args=
+ac_configure_args0=
+ac_configure_args1=
+ac_must_keep_next=false
+for ac_pass in 1 2
+do
+ for ac_arg
+ do
+ case $ac_arg in
+ -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ continue ;;
+ *\'*)
+ ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ esac
+ case $ac_pass in
+ 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;;
+ 2)
+ as_fn_append ac_configure_args1 " '$ac_arg'"
+ if test $ac_must_keep_next = true; then
+ ac_must_keep_next=false # Got value, back to normal.
+ else
+ case $ac_arg in
+ *=* | --config-cache | -C | -disable-* | --disable-* \
+ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
+ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
+ | -with-* | --with-* | -without-* | --without-* | --x)
+ case "$ac_configure_args0 " in
+ "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
+ esac
+ ;;
+ -* ) ac_must_keep_next=true ;;
+ esac
+ fi
+ as_fn_append ac_configure_args " '$ac_arg'"
+ ;;
+ esac
+ done
+done
+{ ac_configure_args0=; unset ac_configure_args0;}
+{ ac_configure_args1=; unset ac_configure_args1;}
+
+# When interrupted or exit'd, cleanup temporary files, and complete
+# config.log. We remove comments because anyway the quotes in there
+# would cause problems or look ugly.
+# WARNING: Use '\'' to represent an apostrophe within the trap.
+# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug.
+trap 'exit_status=$?
+ # Save into config.log some information that might help in debugging.
+ {
+ echo
+
+ $as_echo "## ---------------- ##
+## Cache variables. ##
+## ---------------- ##"
+ echo
+ # The following way of writing the cache mishandles newlines in values,
+(
+ for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do
+ eval ac_val=\$$ac_var
+ case $ac_val in #(
+ *${as_nl}*)
+ case $ac_var in #(
+ *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+ esac
+ case $ac_var in #(
+ _ | IFS | as_nl) ;; #(
+ BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+ *) { eval $ac_var=; unset $ac_var;} ;;
+ esac ;;
+ esac
+ done
+ (set) 2>&1 |
+ case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #(
+ *${as_nl}ac_space=\ *)
+ sed -n \
+ "s/'\''/'\''\\\\'\'''\''/g;
+ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p"
+ ;; #(
+ *)
+ sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+ ;;
+ esac |
+ sort
+)
+ echo
+
+ $as_echo "## ----------------- ##
+## Output variables. ##
+## ----------------- ##"
+ echo
+ for ac_var in $ac_subst_vars
+ do
+ eval ac_val=\$$ac_var
+ case $ac_val in
+ *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+ esac
+ $as_echo "$ac_var='\''$ac_val'\''"
+ done | sort
+ echo
+
+ if test -n "$ac_subst_files"; then
+ $as_echo "## ------------------- ##
+## File substitutions. ##
+## ------------------- ##"
+ echo
+ for ac_var in $ac_subst_files
+ do
+ eval ac_val=\$$ac_var
+ case $ac_val in
+ *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+ esac
+ $as_echo "$ac_var='\''$ac_val'\''"
+ done | sort
+ echo
+ fi
+
+ if test -s confdefs.h; then
+ $as_echo "## ----------- ##
+## confdefs.h. ##
+## ----------- ##"
+ echo
+ cat confdefs.h
+ echo
+ fi
+ test "$ac_signal" != 0 &&
+ $as_echo "$as_me: caught signal $ac_signal"
+ $as_echo "$as_me: exit $exit_status"
+ } >&5
+ rm -f core *.core core.conftest.* &&
+ rm -f -r conftest* confdefs* conf$$* $ac_clean_files &&
+ exit $exit_status
+' 0
+for ac_signal in 1 2 13 15; do
+ trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal
+done
+ac_signal=0
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -f -r conftest* confdefs.h
+
+$as_echo "/* confdefs.h */" > confdefs.h
+
+# Predefined preprocessor variables.
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_NAME "$PACKAGE_NAME"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_VERSION "$PACKAGE_VERSION"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_STRING "$PACKAGE_STRING"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_URL "$PACKAGE_URL"
+_ACEOF
+
+
+# Let the site file select an alternate cache file if it wants to.
+# Prefer an explicitly selected file to automatically selected ones.
+ac_site_file1=NONE
+ac_site_file2=NONE
+if test -n "$CONFIG_SITE"; then
+ # We do not want a PATH search for config.site.
+ case $CONFIG_SITE in #((
+ -*) ac_site_file1=./$CONFIG_SITE;;
+ */*) ac_site_file1=$CONFIG_SITE;;
+ *) ac_site_file1=./$CONFIG_SITE;;
+ esac
+elif test "x$prefix" != xNONE; then
+ ac_site_file1=$prefix/share/config.site
+ ac_site_file2=$prefix/etc/config.site
+else
+ ac_site_file1=$ac_default_prefix/share/config.site
+ ac_site_file2=$ac_default_prefix/etc/config.site
+fi
+for ac_site_file in "$ac_site_file1" "$ac_site_file2"
+do
+ test "x$ac_site_file" = xNONE && continue
+ if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5
+$as_echo "$as_me: loading site script $ac_site_file" >&6;}
+ sed 's/^/| /' "$ac_site_file" >&5
+ . "$ac_site_file" \
+ || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "failed to load site script $ac_site_file
+See \`config.log' for more details" "$LINENO" 5; }
+ fi
+done
+
+if test -r "$cache_file"; then
+ # Some versions of bash will fail to source /dev/null (special files
+ # actually), so we avoid doing that. DJGPP emulates it as a regular file.
+ if test /dev/null != "$cache_file" && test -f "$cache_file"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5
+$as_echo "$as_me: loading cache $cache_file" >&6;}
+ case $cache_file in
+ [\\/]* | ?:[\\/]* ) . "$cache_file";;
+ *) . "./$cache_file";;
+ esac
+ fi
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5
+$as_echo "$as_me: creating cache $cache_file" >&6;}
+ >$cache_file
+fi
+
+as_fn_append ac_header_list " stdlib.h"
+as_fn_append ac_header_list " unistd.h"
+as_fn_append ac_header_list " sys/param.h"
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in $ac_precious_vars; do
+ eval ac_old_set=\$ac_cv_env_${ac_var}_set
+ eval ac_new_set=\$ac_env_${ac_var}_set
+ eval ac_old_val=\$ac_cv_env_${ac_var}_value
+ eval ac_new_val=\$ac_env_${ac_var}_value
+ case $ac_old_set,$ac_new_set in
+ set,)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+ ac_cache_corrupted=: ;;
+ ,set)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+ ac_cache_corrupted=: ;;
+ ,);;
+ *)
+ if test "x$ac_old_val" != "x$ac_new_val"; then
+ # differences in whitespace do not lead to failure.
+ ac_old_val_w=`echo x $ac_old_val`
+ ac_new_val_w=`echo x $ac_new_val`
+ if test "$ac_old_val_w" != "$ac_new_val_w"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5
+$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+ ac_cache_corrupted=:
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5
+$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;}
+ eval $ac_var=\$ac_old_val
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5
+$as_echo "$as_me: former value: \`$ac_old_val'" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5
+$as_echo "$as_me: current value: \`$ac_new_val'" >&2;}
+ fi;;
+ esac
+ # Pass precious variables to config.status.
+ if test "$ac_new_set" = set; then
+ case $ac_new_val in
+ *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+ *) ac_arg=$ac_var=$ac_new_val ;;
+ esac
+ case " $ac_configure_args " in
+ *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy.
+ *) as_fn_append ac_configure_args " '$ac_arg'" ;;
+ esac
+ fi
+done
+if $ac_cache_corrupted; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5
+$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;}
+ as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5
+fi
+## -------------------- ##
+## Main body of script. ##
+## -------------------- ##
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="${ac_tool_prefix}gcc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+ ac_ct_CC=$CC
+ # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_CC="gcc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_CC" = x; then
+ CC=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ CC=$ac_ct_CC
+ fi
+else
+ CC="$ac_cv_prog_CC"
+fi
+
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="${ac_tool_prefix}cc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ fi
+fi
+if test -z "$CC"; then
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+ ac_prog_rejected=yes
+ continue
+ fi
+ ac_cv_prog_CC="cc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+if test $ac_prog_rejected = yes; then
+ # We found a bogon in the path, so make sure we never use it.
+ set dummy $ac_cv_prog_CC
+ shift
+ if test $# != 0; then
+ # We chose a different compiler from the bogus one.
+ # However, it has the same basename, so the bogon will be chosen
+ # first if we set CC to just the basename; use the full file name.
+ shift
+ ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+ fi
+fi
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ for ac_prog in cl.exe
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$CC" && break
+ done
+fi
+if test -z "$CC"; then
+ ac_ct_CC=$CC
+ for ac_prog in cl.exe
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_CC="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$ac_ct_CC" && break
+done
+
+ if test "x$ac_ct_CC" = x; then
+ CC=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ CC=$ac_ct_CC
+ fi
+fi
+
+fi
+
+
+test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "no acceptable C compiler found in \$PATH
+See \`config.log' for more details" "$LINENO" 5; }
+
+# Provide some information about the compiler.
+$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+for ac_option in --version -v -V -qversion; do
+ { { ac_try="$ac_compiler $ac_option >&5"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compiler $ac_option >&5") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ sed '10a\
+... rest of stderr output deleted ...
+ 10q' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ fi
+ rm -f conftest.er1 conftest.err
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+done
+
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out"
+# Try to create an executable without -o first, disregard a.out.
+# It will help us diagnose broken compilers, and finding out an intuition
+# of exeext.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5
+$as_echo_n "checking whether the C compiler works... " >&6; }
+ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+
+# The possible output files:
+ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*"
+
+ac_rmfiles=
+for ac_file in $ac_files
+do
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+ * ) ac_rmfiles="$ac_rmfiles $ac_file";;
+ esac
+done
+rm -f $ac_rmfiles
+
+if { { ac_try="$ac_link_default"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link_default") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then :
+ # Autoconf-2.13 could set the ac_cv_exeext variable to `no'.
+# So ignore a value of `no', otherwise this would lead to `EXEEXT = no'
+# in a Makefile. We should not override ac_cv_exeext if it was cached,
+# so that the user can short-circuit this test for compilers unknown to
+# Autoconf.
+for ac_file in $ac_files ''
+do
+ test -f "$ac_file" || continue
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj )
+ ;;
+ [ab].out )
+ # We found the default executable, but exeext='' is most
+ # certainly right.
+ break;;
+ *.* )
+ if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no;
+ then :; else
+ ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+ fi
+ # We set ac_cv_exeext here because the later test for it is not
+ # safe: cross compilers may not add the suffix if given an `-o'
+ # argument, so we may need to know it at that point already.
+ # Even if this section looks crufty: it has the advantage of
+ # actually working.
+ break;;
+ * )
+ break;;
+ esac
+done
+test "$ac_cv_exeext" = no && ac_cv_exeext=
+
+else
+ ac_file=''
+fi
+if test -z "$ac_file"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+$as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "C compiler cannot create executables
+See \`config.log' for more details" "$LINENO" 5; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5
+$as_echo_n "checking for C compiler default output file name... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5
+$as_echo "$ac_file" >&6; }
+ac_exeext=$ac_cv_exeext
+
+rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out
+ac_clean_files=$ac_clean_files_save
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5
+$as_echo_n "checking for suffix of executables... " >&6; }
+if { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then :
+ # If both `conftest.exe' and `conftest' are `present' (well, observable)
+# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will
+# work properly (i.e., refer to `conftest.exe'), while it won't with
+# `rm'.
+for ac_file in conftest.exe conftest conftest.*; do
+ test -f "$ac_file" || continue
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+ *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+ break;;
+ * ) break;;
+ esac
+done
+else
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+rm -f conftest conftest$ac_cv_exeext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5
+$as_echo "$ac_cv_exeext" >&6; }
+
+rm -f conftest.$ac_ext
+EXEEXT=$ac_cv_exeext
+ac_exeext=$EXEEXT
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdio.h>
+int
+main ()
+{
+FILE *f = fopen ("conftest.out", "w");
+ return ferror (f) || fclose (f) != 0;
+
+ ;
+ return 0;
+}
+_ACEOF
+ac_clean_files="$ac_clean_files conftest.out"
+# Check that the compiler produces executables we can run. If not, either
+# the compiler is broken, or we cross compile.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5
+$as_echo_n "checking whether we are cross compiling... " >&6; }
+if test "$cross_compiling" != yes; then
+ { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ if { ac_try='./conftest$ac_cv_exeext'
+ { { case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }; then
+ cross_compiling=no
+ else
+ if test "$cross_compiling" = maybe; then
+ cross_compiling=yes
+ else
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details" "$LINENO" 5; }
+ fi
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5
+$as_echo "$cross_compiling" >&6; }
+
+rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out
+ac_clean_files=$ac_clean_files_save
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5
+$as_echo_n "checking for suffix of object files... " >&6; }
+if ${ac_cv_objext+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.o conftest.obj
+if { { ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compile") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then :
+ for ac_file in conftest.o conftest.obj conftest.*; do
+ test -f "$ac_file" || continue;
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;;
+ *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
+ break;;
+ esac
+done
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot compute suffix of object files: cannot compile
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+rm -f conftest.$ac_cv_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5
+$as_echo "$ac_cv_objext" >&6; }
+OBJEXT=$ac_cv_objext
+ac_objext=$OBJEXT
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5
+$as_echo_n "checking whether we are using the GNU C compiler... " >&6; }
+if ${ac_cv_c_compiler_gnu+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+#ifndef __GNUC__
+ choke me
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_compiler_gnu=yes
+else
+ ac_compiler_gnu=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5
+$as_echo "$ac_cv_c_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+ GCC=yes
+else
+ GCC=
+fi
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5
+$as_echo_n "checking whether $CC accepts -g... " >&6; }
+if ${ac_cv_prog_cc_g+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_save_c_werror_flag=$ac_c_werror_flag
+ ac_c_werror_flag=yes
+ ac_cv_prog_cc_g=no
+ CFLAGS="-g"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_g=yes
+else
+ CFLAGS=""
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+else
+ ac_c_werror_flag=$ac_save_c_werror_flag
+ CFLAGS="-g"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_g=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_c_werror_flag=$ac_save_c_werror_flag
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5
+$as_echo "$ac_cv_prog_cc_g" >&6; }
+if test "$ac_test_CFLAGS" = set; then
+ CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+ if test "$GCC" = yes; then
+ CFLAGS="-g -O2"
+ else
+ CFLAGS="-g"
+ fi
+else
+ if test "$GCC" = yes; then
+ CFLAGS="-O2"
+ else
+ CFLAGS=
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5
+$as_echo_n "checking for $CC option to accept ISO C89... " >&6; }
+if ${ac_cv_prog_cc_c89+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_prog_cc_c89=no
+ac_save_CC=$CC
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdarg.h>
+#include <stdio.h>
+struct stat;
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+ char **p;
+ int i;
+{
+ return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+ char *s;
+ va_list v;
+ va_start (v,p);
+ s = g (p, va_arg (v,int));
+ va_end (v);
+ return s;
+}
+
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has
+ function prototypes and stuff, but not '\xHH' hex character constants.
+ These don't provoke an error unfortunately, instead are silently treated
+ as 'x'. The following induces an error, until -std is added to get
+ proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an
+ array size at least. It's necessary to write '\x00'==0 to get something
+ that's true only with -std. */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+
+/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
+ inside strings and character constants. */
+#define FOO(x) 'x'
+int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
+
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1];
+ ;
+ return 0;
+}
+_ACEOF
+for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
+ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+ CC="$ac_save_CC $ac_arg"
+ if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_c89=$ac_arg
+fi
+rm -f core conftest.err conftest.$ac_objext
+ test "x$ac_cv_prog_cc_c89" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CC=$ac_save_CC
+
+fi
+# AC_CACHE_VAL
+case "x$ac_cv_prog_cc_c89" in
+ x)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+$as_echo "none needed" >&6; } ;;
+ xno)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+$as_echo "unsupported" >&6; } ;;
+ *)
+ CC="$CC $ac_cv_prog_cc_c89"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
+$as_echo "$ac_cv_prog_cc_c89" >&6; } ;;
+esac
+if test "x$ac_cv_prog_cc_c89" != xno; then :
+
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5
+$as_echo_n "checking how to run the C preprocessor... " >&6; }
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+ CPP=
+fi
+if test -z "$CPP"; then
+ if ${ac_cv_prog_CPP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ # Double quotes because CPP needs to be expanded
+ for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
+ do
+ ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+
+else
+ # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether nonexistent headers
+ # can be detected and how.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+ # Broken: success on invalid input.
+continue
+else
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+ break
+fi
+
+ done
+ ac_cv_prog_CPP=$CPP
+
+fi
+ CPP=$ac_cv_prog_CPP
+else
+ ac_cv_prog_CPP=$CPP
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5
+$as_echo "$CPP" >&6; }
+ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+
+else
+ # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether nonexistent headers
+ # can be detected and how.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+ # Broken: success on invalid input.
+continue
+else
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+
+else
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5
+$as_echo_n "checking for grep that handles long lines and -e... " >&6; }
+if ${ac_cv_path_GREP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -z "$GREP"; then
+ ac_path_GREP_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in grep ggrep; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
+ as_fn_executable_p "$ac_path_GREP" || continue
+# Check for GNU ac_path_GREP and select it if it is found.
+ # Check for GNU $ac_path_GREP
+case `"$ac_path_GREP" --version 2>&1` in
+*GNU*)
+ ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;
+*)
+ ac_count=0
+ $as_echo_n 0123456789 >"conftest.in"
+ while :
+ do
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
+ mv "conftest.tmp" "conftest.in"
+ cp "conftest.in" "conftest.nl"
+ $as_echo 'GREP' >> "conftest.nl"
+ "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+ as_fn_arith $ac_count + 1 && ac_count=$as_val
+ if test $ac_count -gt ${ac_path_GREP_max-0}; then
+ # Best one so far, save it but keep looking for a better one
+ ac_cv_path_GREP="$ac_path_GREP"
+ ac_path_GREP_max=$ac_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test $ac_count -gt 10 && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+ $ac_path_GREP_found && break 3
+ done
+ done
+ done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_GREP"; then
+ as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+ fi
+else
+ ac_cv_path_GREP=$GREP
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5
+$as_echo "$ac_cv_path_GREP" >&6; }
+ GREP="$ac_cv_path_GREP"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5
+$as_echo_n "checking for egrep... " >&6; }
+if ${ac_cv_path_EGREP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
+ then ac_cv_path_EGREP="$GREP -E"
+ else
+ if test -z "$EGREP"; then
+ ac_path_EGREP_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in egrep; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
+ as_fn_executable_p "$ac_path_EGREP" || continue
+# Check for GNU ac_path_EGREP and select it if it is found.
+ # Check for GNU $ac_path_EGREP
+case `"$ac_path_EGREP" --version 2>&1` in
+*GNU*)
+ ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;;
+*)
+ ac_count=0
+ $as_echo_n 0123456789 >"conftest.in"
+ while :
+ do
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
+ mv "conftest.tmp" "conftest.in"
+ cp "conftest.in" "conftest.nl"
+ $as_echo 'EGREP' >> "conftest.nl"
+ "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+ as_fn_arith $ac_count + 1 && ac_count=$as_val
+ if test $ac_count -gt ${ac_path_EGREP_max-0}; then
+ # Best one so far, save it but keep looking for a better one
+ ac_cv_path_EGREP="$ac_path_EGREP"
+ ac_path_EGREP_max=$ac_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test $ac_count -gt 10 && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+ $ac_path_EGREP_found && break 3
+ done
+ done
+ done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_EGREP"; then
+ as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+ fi
+else
+ ac_cv_path_EGREP=$EGREP
+fi
+
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5
+$as_echo "$ac_cv_path_EGREP" >&6; }
+ EGREP="$ac_cv_path_EGREP"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
+$as_echo_n "checking for ANSI C header files... " >&6; }
+if ${ac_cv_header_stdc+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_header_stdc=yes
+else
+ ac_cv_header_stdc=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+ # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "memchr" >/dev/null 2>&1; then :
+
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "free" >/dev/null 2>&1; then :
+
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+ if test "$cross_compiling" = yes; then :
+ :
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ctype.h>
+#include <stdlib.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+ (('a' <= (c) && (c) <= 'i') \
+ || ('j' <= (c) && (c) <= 'r') \
+ || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+ int i;
+ for (i = 0; i < 256; i++)
+ if (XOR (islower (i), ISLOWER (i))
+ || toupper (i) != TOUPPER (i))
+ return 2;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+
+else
+ ac_cv_header_stdc=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5
+$as_echo "$ac_cv_header_stdc" >&6; }
+if test $ac_cv_header_stdc = yes; then
+
+$as_echo "#define STDC_HEADERS 1" >>confdefs.h
+
+fi
+
+# On IRIX 5.3, sys/types and inttypes.h are conflicting.
+for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
+ inttypes.h stdint.h unistd.h
+do :
+ as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
+"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+
+ ac_fn_c_check_header_mongrel "$LINENO" "minix/config.h" "ac_cv_header_minix_config_h" "$ac_includes_default"
+if test "x$ac_cv_header_minix_config_h" = xyes; then :
+ MINIX=yes
+else
+ MINIX=
+fi
+
+
+ if test "$MINIX" = yes; then
+
+$as_echo "#define _POSIX_SOURCE 1" >>confdefs.h
+
+
+$as_echo "#define _POSIX_1_SOURCE 2" >>confdefs.h
+
+
+$as_echo "#define _MINIX 1" >>confdefs.h
+
+ fi
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether it is safe to define __EXTENSIONS__" >&5
+$as_echo_n "checking whether it is safe to define __EXTENSIONS__... " >&6; }
+if ${ac_cv_safe_to_define___extensions__+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+# define __EXTENSIONS__ 1
+ $ac_includes_default
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_safe_to_define___extensions__=yes
+else
+ ac_cv_safe_to_define___extensions__=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_safe_to_define___extensions__" >&5
+$as_echo "$ac_cv_safe_to_define___extensions__" >&6; }
+ test $ac_cv_safe_to_define___extensions__ = yes &&
+ $as_echo "#define __EXTENSIONS__ 1" >>confdefs.h
+
+ $as_echo "#define _ALL_SOURCE 1" >>confdefs.h
+
+ $as_echo "#define _GNU_SOURCE 1" >>confdefs.h
+
+ $as_echo "#define _POSIX_PTHREAD_SEMANTICS 1" >>confdefs.h
+
+ $as_echo "#define _TANDEM_SOURCE 1" >>confdefs.h
+
+
+
+am__api_version='1.13'
+
+ac_aux_dir=
+for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do
+ if test -f "$ac_dir/install-sh"; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install-sh -c"
+ break
+ elif test -f "$ac_dir/install.sh"; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install.sh -c"
+ break
+ elif test -f "$ac_dir/shtool"; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/shtool install -c"
+ break
+ fi
+done
+if test -z "$ac_aux_dir"; then
+ as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5
+fi
+
+# These three variables are undocumented and unsupported,
+# and are intended to be withdrawn in a future Autoconf release.
+# They can cause serious problems if a builder's source tree is in a directory
+# whose full name contains unusual characters.
+ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var.
+ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var.
+ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var.
+
+
+# Find a good install program. We prefer a C program (faster),
+# so one script is as good as another. But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AmigaOS /C/install, which installs bootblocks on floppy discs
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# OS/2's system install, which has a completely different semantic
+# ./install, which can be erroneously created by make from ./install.sh.
+# Reject install programs that cannot install multiple files.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5
+$as_echo_n "checking for a BSD-compatible install... " >&6; }
+if test -z "$INSTALL"; then
+if ${ac_cv_path_install+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ # Account for people who put trailing slashes in PATH elements.
+case $as_dir/ in #((
+ ./ | .// | /[cC]/* | \
+ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
+ ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \
+ /usr/ucb/* ) ;;
+ *)
+ # OSF1 and SCO ODT 3.0 have their own names for install.
+ # Don't use installbsd from OSF since it installs stuff as root
+ # by default.
+ for ac_prog in ginstall scoinst install; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then
+ if test $ac_prog = install &&
+ grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+ # AIX install. It has an incompatible calling convention.
+ :
+ elif test $ac_prog = install &&
+ grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+ # program-specific install script used by HP pwplus--don't use.
+ :
+ else
+ rm -rf conftest.one conftest.two conftest.dir
+ echo one > conftest.one
+ echo two > conftest.two
+ mkdir conftest.dir
+ if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" &&
+ test -s conftest.one && test -s conftest.two &&
+ test -s conftest.dir/conftest.one &&
+ test -s conftest.dir/conftest.two
+ then
+ ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
+ break 3
+ fi
+ fi
+ fi
+ done
+ done
+ ;;
+esac
+
+ done
+IFS=$as_save_IFS
+
+rm -rf conftest.one conftest.two conftest.dir
+
+fi
+ if test "${ac_cv_path_install+set}" = set; then
+ INSTALL=$ac_cv_path_install
+ else
+ # As a last resort, use the slow shell script. Don't cache a
+ # value for INSTALL within a source directory, because that will
+ # break other packages using the cache if that directory is
+ # removed, or if the value is a relative name.
+ INSTALL=$ac_install_sh
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5
+$as_echo "$INSTALL" >&6; }
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5
+$as_echo_n "checking whether build environment is sane... " >&6; }
+# Reject unsafe characters in $srcdir or the absolute working directory
+# name. Accept space and tab only in the latter.
+am_lf='
+'
+case `pwd` in
+ *[\\\"\#\$\&\'\`$am_lf]*)
+ as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;;
+esac
+case $srcdir in
+ *[\\\"\#\$\&\'\`$am_lf\ \ ]*)
+ as_fn_error $? "unsafe srcdir value: '$srcdir'" "$LINENO" 5;;
+esac
+
+# Do 'set' in a subshell so we don't clobber the current shell's
+# arguments. Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+ am_has_slept=no
+ for am_try in 1 2; do
+ echo "timestamp, slept: $am_has_slept" > conftest.file
+ set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null`
+ if test "$*" = "X"; then
+ # -L didn't work.
+ set X `ls -t "$srcdir/configure" conftest.file`
+ fi
+ if test "$*" != "X $srcdir/configure conftest.file" \
+ && test "$*" != "X conftest.file $srcdir/configure"; then
+
+ # If neither matched, then we have a broken ls. This can happen
+ # if, for instance, CONFIG_SHELL is bash and it inherits a
+ # broken ls alias from the environment. This has actually
+ # happened. Such a system could not be considered "sane".
+ as_fn_error $? "ls -t appears to fail. Make sure there is not a broken
+ alias in your environment" "$LINENO" 5
+ fi
+ if test "$2" = conftest.file || test $am_try -eq 2; then
+ break
+ fi
+ # Just in case.
+ sleep 1
+ am_has_slept=yes
+ done
+ test "$2" = conftest.file
+ )
+then
+ # Ok.
+ :
+else
+ as_fn_error $? "newly created file is older than distributed files!
+Check your system clock" "$LINENO" 5
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+# If we didn't sleep, we still need to ensure time stamps of config.status and
+# generated files are strictly newer.
+am_sleep_pid=
+if grep 'slept: no' conftest.file >/dev/null 2>&1; then
+ ( sleep 1 ) &
+ am_sleep_pid=$!
+fi
+
+rm -f conftest.file
+
+test "$program_prefix" != NONE &&
+ program_transform_name="s&^&$program_prefix&;$program_transform_name"
+# Use a double $ so make ignores it.
+test "$program_suffix" != NONE &&
+ program_transform_name="s&\$&$program_suffix&;$program_transform_name"
+# Double any \ or $.
+# By default was `s,x,x', remove it if useless.
+ac_script='s/[\\$]/&&/g;s/;s,x,x,$//'
+program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"`
+
+# expand $ac_aux_dir to an absolute path
+am_aux_dir=`cd $ac_aux_dir && pwd`
+
+if test x"${MISSING+set}" != xset; then
+ case $am_aux_dir in
+ *\ * | *\ *)
+ MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;;
+ *)
+ MISSING="\${SHELL} $am_aux_dir/missing" ;;
+ esac
+fi
+# Use eval to expand $SHELL
+if eval "$MISSING --is-lightweight"; then
+ am_missing_run="$MISSING "
+else
+ am_missing_run=
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5
+$as_echo "$as_me: WARNING: 'missing' script is too old or missing" >&2;}
+fi
+
+if test x"${install_sh}" != xset; then
+ case $am_aux_dir in
+ *\ * | *\ *)
+ install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;;
+ *)
+ install_sh="\${SHELL} $am_aux_dir/install-sh"
+ esac
+fi
+
+# Installed binaries are usually stripped using 'strip' when the user
+# run "make install-strip". However 'strip' might not be the right
+# tool to use in cross-compilation environments, therefore Automake
+# will honor the 'STRIP' environment variable to overrule this program.
+if test "$cross_compiling" != no; then
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
+set dummy ${ac_tool_prefix}strip; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_STRIP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$STRIP"; then
+ ac_cv_prog_STRIP="$STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_STRIP="${ac_tool_prefix}strip"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+STRIP=$ac_cv_prog_STRIP
+if test -n "$STRIP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5
+$as_echo "$STRIP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_STRIP"; then
+ ac_ct_STRIP=$STRIP
+ # Extract the first word of "strip", so it can be a program name with args.
+set dummy strip; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_STRIP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_STRIP"; then
+ ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_STRIP="strip"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP
+if test -n "$ac_ct_STRIP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5
+$as_echo "$ac_ct_STRIP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_STRIP" = x; then
+ STRIP=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ STRIP=$ac_ct_STRIP
+ fi
+else
+ STRIP="$ac_cv_prog_STRIP"
+fi
+
+fi
+INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5
+$as_echo_n "checking for a thread-safe mkdir -p... " >&6; }
+if test -z "$MKDIR_P"; then
+ if ${ac_cv_path_mkdir+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in mkdir gmkdir; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue
+ case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #(
+ 'mkdir (GNU coreutils) '* | \
+ 'mkdir (coreutils) '* | \
+ 'mkdir (fileutils) '4.1*)
+ ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext
+ break 3;;
+ esac
+ done
+ done
+ done
+IFS=$as_save_IFS
+
+fi
+
+ test -d ./--version && rmdir ./--version
+ if test "${ac_cv_path_mkdir+set}" = set; then
+ MKDIR_P="$ac_cv_path_mkdir -p"
+ else
+ # As a last resort, use the slow shell script. Don't cache a
+ # value for MKDIR_P within a source directory, because that will
+ # break other packages using the cache if that directory is
+ # removed, or if the value is a relative name.
+ MKDIR_P="$ac_install_sh -d"
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5
+$as_echo "$MKDIR_P" >&6; }
+
+for ac_prog in gawk mawk nawk awk
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_AWK+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$AWK"; then
+ ac_cv_prog_AWK="$AWK" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_AWK="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+AWK=$ac_cv_prog_AWK
+if test -n "$AWK"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5
+$as_echo "$AWK" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$AWK" && break
+done
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5
+$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; }
+set x ${MAKE-make}
+ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'`
+if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat >conftest.make <<\_ACEOF
+SHELL = /bin/sh
+all:
+ @echo '@@@%%%=$(MAKE)=@@@%%%'
+_ACEOF
+# GNU make sometimes prints "make[1]: Entering ...", which would confuse us.
+case `${MAKE-make} -f conftest.make 2>/dev/null` in
+ *@@@%%%=?*=@@@%%%*)
+ eval ac_cv_prog_make_${ac_make}_set=yes;;
+ *)
+ eval ac_cv_prog_make_${ac_make}_set=no;;
+esac
+rm -f conftest.make
+fi
+if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ SET_MAKE=
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+rm -rf .tst 2>/dev/null
+mkdir .tst 2>/dev/null
+if test -d .tst; then
+ am__leading_dot=.
+else
+ am__leading_dot=_
+fi
+rmdir .tst 2>/dev/null
+
+DEPDIR="${am__leading_dot}deps"
+
+ac_config_commands="$ac_config_commands depfiles"
+
+
+am_make=${MAKE-make}
+cat > confinc << 'END'
+am__doit:
+ @echo this is the am__doit target
+.PHONY: am__doit
+END
+# If we don't find an include directive, just comment out the code.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5
+$as_echo_n "checking for style of include used by $am_make... " >&6; }
+am__include="#"
+am__quote=
+_am_result=none
+# First try GNU make style include.
+echo "include confinc" > confmf
+# Ignore all kinds of additional output from 'make'.
+case `$am_make -s -f confmf 2> /dev/null` in #(
+*the\ am__doit\ target*)
+ am__include=include
+ am__quote=
+ _am_result=GNU
+ ;;
+esac
+# Now try BSD make style include.
+if test "$am__include" = "#"; then
+ echo '.include "confinc"' > confmf
+ case `$am_make -s -f confmf 2> /dev/null` in #(
+ *the\ am__doit\ target*)
+ am__include=.include
+ am__quote="\""
+ _am_result=BSD
+ ;;
+ esac
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5
+$as_echo "$_am_result" >&6; }
+rm -f confinc confmf
+
+# Check whether --enable-dependency-tracking was given.
+if test "${enable_dependency_tracking+set}" = set; then :
+ enableval=$enable_dependency_tracking;
+fi
+
+if test "x$enable_dependency_tracking" != xno; then
+ am_depcomp="$ac_aux_dir/depcomp"
+ AMDEPBACKSLASH='\'
+ am__nodep='_no'
+fi
+ if test "x$enable_dependency_tracking" != xno; then
+ AMDEP_TRUE=
+ AMDEP_FALSE='#'
+else
+ AMDEP_TRUE='#'
+ AMDEP_FALSE=
+fi
+
+
+# Check whether --enable-silent-rules was given.
+if test "${enable_silent_rules+set}" = set; then :
+ enableval=$enable_silent_rules;
+fi
+
+case $enable_silent_rules in # (((
+ yes) AM_DEFAULT_VERBOSITY=0;;
+ no) AM_DEFAULT_VERBOSITY=1;;
+ *) AM_DEFAULT_VERBOSITY=1;;
+esac
+am_make=${MAKE-make}
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5
+$as_echo_n "checking whether $am_make supports nested variables... " >&6; }
+if ${am_cv_make_support_nested_variables+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if $as_echo 'TRUE=$(BAR$(V))
+BAR0=false
+BAR1=true
+V=1
+am__doit:
+ @$(TRUE)
+.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then
+ am_cv_make_support_nested_variables=yes
+else
+ am_cv_make_support_nested_variables=no
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5
+$as_echo "$am_cv_make_support_nested_variables" >&6; }
+if test $am_cv_make_support_nested_variables = yes; then
+ AM_V='$(V)'
+ AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)'
+else
+ AM_V=$AM_DEFAULT_VERBOSITY
+ AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY
+fi
+AM_BACKSLASH='\'
+
+if test "`cd $srcdir && pwd`" != "`pwd`"; then
+ # Use -I$(srcdir) only when $(srcdir) != ., so that make's output
+ # is not polluted with repeated "-I."
+ am__isrc=' -I$(srcdir)'
+ # test to see if srcdir already configured
+ if test -f $srcdir/config.status; then
+ as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5
+ fi
+fi
+
+# test whether we have cygpath
+if test -z "$CYGPATH_W"; then
+ if (cygpath --version) >/dev/null 2>/dev/null; then
+ CYGPATH_W='cygpath -w'
+ else
+ CYGPATH_W=echo
+ fi
+fi
+
+
+# Define the identity of the package.
+ PACKAGE='corosync'
+ VERSION='3.1.8'
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE "$PACKAGE"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define VERSION "$VERSION"
+_ACEOF
+
+# Some tools Automake needs.
+
+ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"}
+
+
+AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"}
+
+
+AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"}
+
+
+AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"}
+
+
+MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"}
+
+# For better backward compatibility. To be removed once Automake 1.9.x
+# dies out for good. For more background, see:
+# <http://lists.gnu.org/archive/html/automake/2012-07/msg00001.html>
+# <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
+mkdir_p='$(MKDIR_P)'
+
+# We need awk for the "check" target. The system "awk" is bad on
+# some platforms.
+# Always define AMTAR for backward compatibility. Yes, it's still used
+# in the wild :-( We should find a proper way to deprecate it ...
+AMTAR='$${TAR-tar}'
+
+
+# We'll loop over all known methods to create a tar archive until one works.
+_am_tools='gnutar pax cpio none'
+
+am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'
+
+
+
+
+
+depcc="$CC" am_compiler_list=
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5
+$as_echo_n "checking dependency style of $depcc... " >&6; }
+if ${am_cv_CC_dependencies_compiler_type+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+ # We make a subdir and do the tests there. Otherwise we can end up
+ # making bogus files that we don't know about and never remove. For
+ # instance it was reported that on HP-UX the gcc test will end up
+ # making a dummy file named 'D' -- because '-MD' means "put the output
+ # in D".
+ rm -rf conftest.dir
+ mkdir conftest.dir
+ # Copy depcomp to subdir because otherwise we won't find it if we're
+ # using a relative directory.
+ cp "$am_depcomp" conftest.dir
+ cd conftest.dir
+ # We will build objects and dependencies in a subdirectory because
+ # it helps to detect inapplicable dependency modes. For instance
+ # both Tru64's cc and ICC support -MD to output dependencies as a
+ # side effect of compilation, but ICC will put the dependencies in
+ # the current directory while Tru64 will put them in the object
+ # directory.
+ mkdir sub
+
+ am_cv_CC_dependencies_compiler_type=none
+ if test "$am_compiler_list" = ""; then
+ am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp`
+ fi
+ am__universal=false
+ case " $depcc " in #(
+ *\ -arch\ *\ -arch\ *) am__universal=true ;;
+ esac
+
+ for depmode in $am_compiler_list; do
+ # Setup a source with many dependencies, because some compilers
+ # like to wrap large dependency lists on column 80 (with \), and
+ # we should not choose a depcomp mode which is confused by this.
+ #
+ # We need to recreate these files for each test, as the compiler may
+ # overwrite some of them when testing with obscure command lines.
+ # This happens at least with the AIX C compiler.
+ : > sub/conftest.c
+ for i in 1 2 3 4 5 6; do
+ echo '#include "conftst'$i'.h"' >> sub/conftest.c
+ # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with
+ # Solaris 10 /bin/sh.
+ echo '/* dummy */' > sub/conftst$i.h
+ done
+ echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+ # We check with '-c' and '-o' for the sake of the "dashmstdout"
+ # mode. It turns out that the SunPro C++ compiler does not properly
+ # handle '-M -o', and we need to detect this. Also, some Intel
+ # versions had trouble with output in subdirs.
+ am__obj=sub/conftest.${OBJEXT-o}
+ am__minus_obj="-o $am__obj"
+ case $depmode in
+ gcc)
+ # This depmode causes a compiler race in universal mode.
+ test "$am__universal" = false || continue
+ ;;
+ nosideeffect)
+ # After this tag, mechanisms are not by side-effect, so they'll
+ # only be used when explicitly requested.
+ if test "x$enable_dependency_tracking" = xyes; then
+ continue
+ else
+ break
+ fi
+ ;;
+ msvc7 | msvc7msys | msvisualcpp | msvcmsys)
+ # This compiler won't grok '-c -o', but also, the minuso test has
+ # not run yet. These depmodes are late enough in the game, and
+ # so weak that their functioning should not be impacted.
+ am__obj=conftest.${OBJEXT-o}
+ am__minus_obj=
+ ;;
+ none) break ;;
+ esac
+ if depmode=$depmode \
+ source=sub/conftest.c object=$am__obj \
+ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \
+ >/dev/null 2>conftest.err &&
+ grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep $am__obj sub/conftest.Po > /dev/null 2>&1 &&
+ ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+ # icc doesn't choke on unknown options, it will just issue warnings
+ # or remarks (even with -Werror). So we grep stderr for any message
+ # that says an option was ignored or not supported.
+ # When given -MP, icc 7.0 and 7.1 complain thusly:
+ # icc: Command line warning: ignoring option '-M'; no argument required
+ # The diagnosis changed in icc 8.0:
+ # icc: Command line remark: option '-MP' not supported
+ if (grep 'ignoring option' conftest.err ||
+ grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
+ am_cv_CC_dependencies_compiler_type=$depmode
+ break
+ fi
+ fi
+ done
+
+ cd ..
+ rm -rf conftest.dir
+else
+ am_cv_CC_dependencies_compiler_type=none
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5
+$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; }
+CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type
+
+ if
+ test "x$enable_dependency_tracking" != xno \
+ && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then
+ am__fastdepCC_TRUE=
+ am__fastdepCC_FALSE='#'
+else
+ am__fastdepCC_TRUE='#'
+ am__fastdepCC_FALSE=
+fi
+
+
+
+
+
+case `pwd` in
+ *\ * | *\ *)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5
+$as_echo "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;;
+esac
+
+
+
+macro_version='2.4.2'
+macro_revision='1.3337'
+
+
+
+
+
+
+
+
+
+
+
+
+
+ltmain="$ac_aux_dir/ltmain.sh"
+
+# Make sure we can run config.sub.
+$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 ||
+ as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5
+$as_echo_n "checking build system type... " >&6; }
+if ${ac_cv_build+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_build_alias=$build_alias
+test "x$ac_build_alias" = x &&
+ ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"`
+test "x$ac_build_alias" = x &&
+ as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5
+ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` ||
+ as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5
+$as_echo "$ac_cv_build" >&6; }
+case $ac_cv_build in
+*-*-*) ;;
+*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;;
+esac
+build=$ac_cv_build
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_build
+shift
+build_cpu=$1
+build_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+build_os=$*
+IFS=$ac_save_IFS
+case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5
+$as_echo_n "checking host system type... " >&6; }
+if ${ac_cv_host+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "x$host_alias" = x; then
+ ac_cv_host=$ac_cv_build
+else
+ ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` ||
+ as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5
+$as_echo "$ac_cv_host" >&6; }
+case $ac_cv_host in
+*-*-*) ;;
+*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;;
+esac
+host=$ac_cv_host
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_host
+shift
+host_cpu=$1
+host_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+host_os=$*
+IFS=$ac_save_IFS
+case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac
+
+
+# Backslashify metacharacters that are still active within
+# double-quoted strings.
+sed_quote_subst='s/\(["`$\\]\)/\\\1/g'
+
+# Same as above, but do not quote variable references.
+double_quote_subst='s/\(["`\\]\)/\\\1/g'
+
+# Sed substitution to delay expansion of an escaped shell variable in a
+# double_quote_subst'ed string.
+delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g'
+
+# Sed substitution to delay expansion of an escaped single quote.
+delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g'
+
+# Sed substitution to avoid accidental globbing in evaled expressions
+no_glob_subst='s/\*/\\\*/g'
+
+ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO
+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5
+$as_echo_n "checking how to print strings... " >&6; }
+# Test print first, because it will be a builtin if present.
+if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \
+ test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then
+ ECHO='print -r --'
+elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then
+ ECHO='printf %s\n'
+else
+ # Use this function as a fallback that always works.
+ func_fallback_echo ()
+ {
+ eval 'cat <<_LTECHO_EOF
+$1
+_LTECHO_EOF'
+ }
+ ECHO='func_fallback_echo'
+fi
+
+# func_echo_all arg...
+# Invoke $ECHO with all args, space-separated.
+func_echo_all ()
+{
+ $ECHO ""
+}
+
+case "$ECHO" in
+ printf*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: printf" >&5
+$as_echo "printf" >&6; } ;;
+ print*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: print -r" >&5
+$as_echo "print -r" >&6; } ;;
+ *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: cat" >&5
+$as_echo "cat" >&6; } ;;
+esac
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5
+$as_echo_n "checking for a sed that does not truncate output... " >&6; }
+if ${ac_cv_path_SED+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/
+ for ac_i in 1 2 3 4 5 6 7; do
+ ac_script="$ac_script$as_nl$ac_script"
+ done
+ echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed
+ { ac_script=; unset ac_script;}
+ if test -z "$SED"; then
+ ac_path_SED_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in sed gsed; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_SED="$as_dir/$ac_prog$ac_exec_ext"
+ as_fn_executable_p "$ac_path_SED" || continue
+# Check for GNU ac_path_SED and select it if it is found.
+ # Check for GNU $ac_path_SED
+case `"$ac_path_SED" --version 2>&1` in
+*GNU*)
+ ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;;
+*)
+ ac_count=0
+ $as_echo_n 0123456789 >"conftest.in"
+ while :
+ do
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
+ mv "conftest.tmp" "conftest.in"
+ cp "conftest.in" "conftest.nl"
+ $as_echo '' >> "conftest.nl"
+ "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break
+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+ as_fn_arith $ac_count + 1 && ac_count=$as_val
+ if test $ac_count -gt ${ac_path_SED_max-0}; then
+ # Best one so far, save it but keep looking for a better one
+ ac_cv_path_SED="$ac_path_SED"
+ ac_path_SED_max=$ac_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test $ac_count -gt 10 && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+ $ac_path_SED_found && break 3
+ done
+ done
+ done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_SED"; then
+ as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5
+ fi
+else
+ ac_cv_path_SED=$SED
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5
+$as_echo "$ac_cv_path_SED" >&6; }
+ SED="$ac_cv_path_SED"
+ rm -f conftest.sed
+
+test -z "$SED" && SED=sed
+Xsed="$SED -e 1s/^X//"
+
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5
+$as_echo_n "checking for fgrep... " >&6; }
+if ${ac_cv_path_FGREP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1
+ then ac_cv_path_FGREP="$GREP -F"
+ else
+ if test -z "$FGREP"; then
+ ac_path_FGREP_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in fgrep; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext"
+ as_fn_executable_p "$ac_path_FGREP" || continue
+# Check for GNU ac_path_FGREP and select it if it is found.
+ # Check for GNU $ac_path_FGREP
+case `"$ac_path_FGREP" --version 2>&1` in
+*GNU*)
+ ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;;
+*)
+ ac_count=0
+ $as_echo_n 0123456789 >"conftest.in"
+ while :
+ do
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
+ mv "conftest.tmp" "conftest.in"
+ cp "conftest.in" "conftest.nl"
+ $as_echo 'FGREP' >> "conftest.nl"
+ "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break
+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+ as_fn_arith $ac_count + 1 && ac_count=$as_val
+ if test $ac_count -gt ${ac_path_FGREP_max-0}; then
+ # Best one so far, save it but keep looking for a better one
+ ac_cv_path_FGREP="$ac_path_FGREP"
+ ac_path_FGREP_max=$ac_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test $ac_count -gt 10 && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+ $ac_path_FGREP_found && break 3
+ done
+ done
+ done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_FGREP"; then
+ as_fn_error $? "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+ fi
+else
+ ac_cv_path_FGREP=$FGREP
+fi
+
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5
+$as_echo "$ac_cv_path_FGREP" >&6; }
+ FGREP="$ac_cv_path_FGREP"
+
+
+test -z "$GREP" && GREP=grep
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# Check whether --with-gnu-ld was given.
+if test "${with_gnu_ld+set}" = set; then :
+ withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes
+else
+ with_gnu_ld=no
+fi
+
+ac_prog=ld
+if test "$GCC" = yes; then
+ # Check if gcc -print-prog-name=ld gives a path.
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5
+$as_echo_n "checking for ld used by $CC... " >&6; }
+ case $host in
+ *-*-mingw*)
+ # gcc leaves a trailing carriage return which upsets mingw
+ ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
+ *)
+ ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
+ esac
+ case $ac_prog in
+ # Accept absolute paths.
+ [\\/]* | ?:[\\/]*)
+ re_direlt='/[^/][^/]*/\.\./'
+ # Canonicalize the pathname of ld
+ ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'`
+ while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do
+ ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"`
+ done
+ test -z "$LD" && LD="$ac_prog"
+ ;;
+ "")
+ # If it fails, then pretend we aren't using GCC.
+ ac_prog=ld
+ ;;
+ *)
+ # If it is relative, then search for the first ld in PATH.
+ with_gnu_ld=unknown
+ ;;
+ esac
+elif test "$with_gnu_ld" = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5
+$as_echo_n "checking for GNU ld... " >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5
+$as_echo_n "checking for non-GNU ld... " >&6; }
+fi
+if ${lt_cv_path_LD+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -z "$LD"; then
+ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+ for ac_dir in $PATH; do
+ IFS="$lt_save_ifs"
+ test -z "$ac_dir" && ac_dir=.
+ if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+ lt_cv_path_LD="$ac_dir/$ac_prog"
+ # Check to see if the program is GNU ld. I'd rather use --version,
+ # but apparently some variants of GNU ld only accept -v.
+ # Break only if it was the GNU/non-GNU ld that we prefer.
+ case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
+ *GNU* | *'with BFD'*)
+ test "$with_gnu_ld" != no && break
+ ;;
+ *)
+ test "$with_gnu_ld" != yes && break
+ ;;
+ esac
+ fi
+ done
+ IFS="$lt_save_ifs"
+else
+ lt_cv_path_LD="$LD" # Let the user override the test with a path.
+fi
+fi
+
+LD="$lt_cv_path_LD"
+if test -n "$LD"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LD" >&5
+$as_echo "$LD" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5
+$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; }
+if ${lt_cv_prog_gnu_ld+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ # I'd rather use --version here, but apparently some GNU lds only accept -v.
+case `$LD -v 2>&1 </dev/null` in
+*GNU* | *'with BFD'*)
+ lt_cv_prog_gnu_ld=yes
+ ;;
+*)
+ lt_cv_prog_gnu_ld=no
+ ;;
+esac
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_gnu_ld" >&5
+$as_echo "$lt_cv_prog_gnu_ld" >&6; }
+with_gnu_ld=$lt_cv_prog_gnu_ld
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5
+$as_echo_n "checking for BSD- or MS-compatible name lister (nm)... " >&6; }
+if ${lt_cv_path_NM+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$NM"; then
+ # Let the user override the test.
+ lt_cv_path_NM="$NM"
+else
+ lt_nm_to_check="${ac_tool_prefix}nm"
+ if test -n "$ac_tool_prefix" && test "$build" = "$host"; then
+ lt_nm_to_check="$lt_nm_to_check nm"
+ fi
+ for lt_tmp_nm in $lt_nm_to_check; do
+ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+ for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do
+ IFS="$lt_save_ifs"
+ test -z "$ac_dir" && ac_dir=.
+ tmp_nm="$ac_dir/$lt_tmp_nm"
+ if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then
+ # Check to see if the nm accepts a BSD-compat flag.
+ # Adding the `sed 1q' prevents false positives on HP-UX, which says:
+ # nm: unknown option "B" ignored
+ # Tru64's nm complains that /dev/null is an invalid object file
+ case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in
+ */dev/null* | *'Invalid file or object type'*)
+ lt_cv_path_NM="$tmp_nm -B"
+ break
+ ;;
+ *)
+ case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in
+ */dev/null*)
+ lt_cv_path_NM="$tmp_nm -p"
+ break
+ ;;
+ *)
+ lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
+ continue # so that we can try to find one that supports BSD flags
+ ;;
+ esac
+ ;;
+ esac
+ fi
+ done
+ IFS="$lt_save_ifs"
+ done
+ : ${lt_cv_path_NM=no}
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5
+$as_echo "$lt_cv_path_NM" >&6; }
+if test "$lt_cv_path_NM" != "no"; then
+ NM="$lt_cv_path_NM"
+else
+ # Didn't find any BSD compatible name lister, look for dumpbin.
+ if test -n "$DUMPBIN"; then :
+ # Let the user override the test.
+ else
+ if test -n "$ac_tool_prefix"; then
+ for ac_prog in dumpbin "link -dump"
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_DUMPBIN+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$DUMPBIN"; then
+ ac_cv_prog_DUMPBIN="$DUMPBIN" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+DUMPBIN=$ac_cv_prog_DUMPBIN
+if test -n "$DUMPBIN"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5
+$as_echo "$DUMPBIN" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$DUMPBIN" && break
+ done
+fi
+if test -z "$DUMPBIN"; then
+ ac_ct_DUMPBIN=$DUMPBIN
+ for ac_prog in dumpbin "link -dump"
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_DUMPBIN+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_DUMPBIN"; then
+ ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_DUMPBIN="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN
+if test -n "$ac_ct_DUMPBIN"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5
+$as_echo "$ac_ct_DUMPBIN" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$ac_ct_DUMPBIN" && break
+done
+
+ if test "x$ac_ct_DUMPBIN" = x; then
+ DUMPBIN=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ DUMPBIN=$ac_ct_DUMPBIN
+ fi
+fi
+
+ case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in
+ *COFF*)
+ DUMPBIN="$DUMPBIN -symbols"
+ ;;
+ *)
+ DUMPBIN=:
+ ;;
+ esac
+ fi
+
+ if test "$DUMPBIN" != ":"; then
+ NM="$DUMPBIN"
+ fi
+fi
+test -z "$NM" && NM=nm
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5
+$as_echo_n "checking the name lister ($NM) interface... " >&6; }
+if ${lt_cv_nm_interface+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_nm_interface="BSD nm"
+ echo "int some_variable = 0;" > conftest.$ac_ext
+ (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&5)
+ (eval "$ac_compile" 2>conftest.err)
+ cat conftest.err >&5
+ (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
+ (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
+ cat conftest.err >&5
+ (eval echo "\"\$as_me:$LINENO: output\"" >&5)
+ cat conftest.out >&5
+ if $GREP 'External.*some_variable' conftest.out > /dev/null; then
+ lt_cv_nm_interface="MS dumpbin"
+ fi
+ rm -f conftest*
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5
+$as_echo "$lt_cv_nm_interface" >&6; }
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5
+$as_echo_n "checking whether ln -s works... " >&6; }
+LN_S=$as_ln_s
+if test "$LN_S" = "ln -s"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5
+$as_echo "no, using $LN_S" >&6; }
+fi
+
+# find the maximum length of command line arguments
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5
+$as_echo_n "checking the maximum length of command line arguments... " >&6; }
+if ${lt_cv_sys_max_cmd_len+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ i=0
+ teststring="ABCD"
+
+ case $build_os in
+ msdosdjgpp*)
+ # On DJGPP, this test can blow up pretty badly due to problems in libc
+ # (any single argument exceeding 2000 bytes causes a buffer overrun
+ # during glob expansion). Even if it were fixed, the result of this
+ # check would be larger than it should be.
+ lt_cv_sys_max_cmd_len=12288; # 12K is about right
+ ;;
+
+ gnu*)
+ # Under GNU Hurd, this test is not required because there is
+ # no limit to the length of command line arguments.
+ # Libtool will interpret -1 as no limit whatsoever
+ lt_cv_sys_max_cmd_len=-1;
+ ;;
+
+ cygwin* | mingw* | cegcc*)
+ # On Win9x/ME, this test blows up -- it succeeds, but takes
+ # about 5 minutes as the teststring grows exponentially.
+ # Worse, since 9x/ME are not pre-emptively multitasking,
+ # you end up with a "frozen" computer, even though with patience
+ # the test eventually succeeds (with a max line length of 256k).
+ # Instead, let's just punt: use the minimum linelength reported by
+ # all of the supported platforms: 8192 (on NT/2K/XP).
+ lt_cv_sys_max_cmd_len=8192;
+ ;;
+
+ mint*)
+ # On MiNT this can take a long time and run out of memory.
+ lt_cv_sys_max_cmd_len=8192;
+ ;;
+
+ amigaos*)
+ # On AmigaOS with pdksh, this test takes hours, literally.
+ # So we just punt and use a minimum line length of 8192.
+ lt_cv_sys_max_cmd_len=8192;
+ ;;
+
+ netbsd* | freebsd* | openbsd* | darwin* | dragonfly*)
+ # This has been around since 386BSD, at least. Likely further.
+ if test -x /sbin/sysctl; then
+ lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax`
+ elif test -x /usr/sbin/sysctl; then
+ lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax`
+ else
+ lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs
+ fi
+ # And add a safety zone
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+ ;;
+
+ interix*)
+ # We know the value 262144 and hardcode it with a safety zone (like BSD)
+ lt_cv_sys_max_cmd_len=196608
+ ;;
+
+ os2*)
+ # The test takes a long time on OS/2.
+ lt_cv_sys_max_cmd_len=8192
+ ;;
+
+ osf*)
+ # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure
+ # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not
+ # nice to cause kernel panics so lets avoid the loop below.
+ # First set a reasonable default.
+ lt_cv_sys_max_cmd_len=16384
+ #
+ if test -x /sbin/sysconfig; then
+ case `/sbin/sysconfig -q proc exec_disable_arg_limit` in
+ *1*) lt_cv_sys_max_cmd_len=-1 ;;
+ esac
+ fi
+ ;;
+ sco3.2v5*)
+ lt_cv_sys_max_cmd_len=102400
+ ;;
+ sysv5* | sco5v6* | sysv4.2uw2*)
+ kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null`
+ if test -n "$kargmax"; then
+ lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ ]//'`
+ else
+ lt_cv_sys_max_cmd_len=32768
+ fi
+ ;;
+ *)
+ lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null`
+ if test -n "$lt_cv_sys_max_cmd_len"; then
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+ else
+ # Make teststring a little bigger before we do anything with it.
+ # a 1K string should be a reasonable start.
+ for i in 1 2 3 4 5 6 7 8 ; do
+ teststring=$teststring$teststring
+ done
+ SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}}
+ # If test is not a shell built-in, we'll probably end up computing a
+ # maximum length that is only half of the actual maximum length, but
+ # we can't tell.
+ while { test "X"`env echo "$teststring$teststring" 2>/dev/null` \
+ = "X$teststring$teststring"; } >/dev/null 2>&1 &&
+ test $i != 17 # 1/2 MB should be enough
+ do
+ i=`expr $i + 1`
+ teststring=$teststring$teststring
+ done
+ # Only check the string length outside the loop.
+ lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1`
+ teststring=
+ # Add a significant safety factor because C++ compilers can tack on
+ # massive amounts of additional arguments before passing them to the
+ # linker. It appears as though 1/2 is a usable value.
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2`
+ fi
+ ;;
+ esac
+
+fi
+
+if test -n $lt_cv_sys_max_cmd_len ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5
+$as_echo "$lt_cv_sys_max_cmd_len" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5
+$as_echo "none" >&6; }
+fi
+max_cmd_len=$lt_cv_sys_max_cmd_len
+
+
+
+
+
+
+: ${CP="cp -f"}
+: ${MV="mv -f"}
+: ${RM="rm -f"}
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands some XSI constructs" >&5
+$as_echo_n "checking whether the shell understands some XSI constructs... " >&6; }
+# Try some XSI features
+xsi_shell=no
+( _lt_dummy="a/b/c"
+ test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \
+ = c,a/b,b/c, \
+ && eval 'test $(( 1 + 1 )) -eq 2 \
+ && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \
+ && xsi_shell=yes
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $xsi_shell" >&5
+$as_echo "$xsi_shell" >&6; }
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands \"+=\"" >&5
+$as_echo_n "checking whether the shell understands \"+=\"... " >&6; }
+lt_shell_append=no
+( foo=bar; set foo baz; eval "$1+=\$2" && test "$foo" = barbaz ) \
+ >/dev/null 2>&1 \
+ && lt_shell_append=yes
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_shell_append" >&5
+$as_echo "$lt_shell_append" >&6; }
+
+
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+ lt_unset=unset
+else
+ lt_unset=false
+fi
+
+
+
+
+
+# test EBCDIC or ASCII
+case `echo X|tr X '\101'` in
+ A) # ASCII based system
+ # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr
+ lt_SP2NL='tr \040 \012'
+ lt_NL2SP='tr \015\012 \040\040'
+ ;;
+ *) # EBCDIC based system
+ lt_SP2NL='tr \100 \n'
+ lt_NL2SP='tr \r\n \100\100'
+ ;;
+esac
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to $host format" >&5
+$as_echo_n "checking how to convert $build file names to $host format... " >&6; }
+if ${lt_cv_to_host_file_cmd+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $host in
+ *-*-mingw* )
+ case $build in
+ *-*-mingw* ) # actually msys
+ lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32
+ ;;
+ *-*-cygwin* )
+ lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32
+ ;;
+ * ) # otherwise, assume *nix
+ lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32
+ ;;
+ esac
+ ;;
+ *-*-cygwin* )
+ case $build in
+ *-*-mingw* ) # actually msys
+ lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin
+ ;;
+ *-*-cygwin* )
+ lt_cv_to_host_file_cmd=func_convert_file_noop
+ ;;
+ * ) # otherwise, assume *nix
+ lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin
+ ;;
+ esac
+ ;;
+ * ) # unhandled hosts (and "normal" native builds)
+ lt_cv_to_host_file_cmd=func_convert_file_noop
+ ;;
+esac
+
+fi
+
+to_host_file_cmd=$lt_cv_to_host_file_cmd
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_host_file_cmd" >&5
+$as_echo "$lt_cv_to_host_file_cmd" >&6; }
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to toolchain format" >&5
+$as_echo_n "checking how to convert $build file names to toolchain format... " >&6; }
+if ${lt_cv_to_tool_file_cmd+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ #assume ordinary cross tools, or native build.
+lt_cv_to_tool_file_cmd=func_convert_file_noop
+case $host in
+ *-*-mingw* )
+ case $build in
+ *-*-mingw* ) # actually msys
+ lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32
+ ;;
+ esac
+ ;;
+esac
+
+fi
+
+to_tool_file_cmd=$lt_cv_to_tool_file_cmd
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_tool_file_cmd" >&5
+$as_echo "$lt_cv_to_tool_file_cmd" >&6; }
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5
+$as_echo_n "checking for $LD option to reload object files... " >&6; }
+if ${lt_cv_ld_reload_flag+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_ld_reload_flag='-r'
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5
+$as_echo "$lt_cv_ld_reload_flag" >&6; }
+reload_flag=$lt_cv_ld_reload_flag
+case $reload_flag in
+"" | " "*) ;;
+*) reload_flag=" $reload_flag" ;;
+esac
+reload_cmds='$LD$reload_flag -o $output$reload_objs'
+case $host_os in
+ cygwin* | mingw* | pw32* | cegcc*)
+ if test "$GCC" != yes; then
+ reload_cmds=false
+ fi
+ ;;
+ darwin*)
+ if test "$GCC" = yes; then
+ reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs'
+ else
+ reload_cmds='$LD$reload_flag -o $output$reload_objs'
+ fi
+ ;;
+esac
+
+
+
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args.
+set dummy ${ac_tool_prefix}objdump; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_OBJDUMP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$OBJDUMP"; then
+ ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+OBJDUMP=$ac_cv_prog_OBJDUMP
+if test -n "$OBJDUMP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5
+$as_echo "$OBJDUMP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_OBJDUMP"; then
+ ac_ct_OBJDUMP=$OBJDUMP
+ # Extract the first word of "objdump", so it can be a program name with args.
+set dummy objdump; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_OBJDUMP"; then
+ ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_OBJDUMP="objdump"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP
+if test -n "$ac_ct_OBJDUMP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5
+$as_echo "$ac_ct_OBJDUMP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_OBJDUMP" = x; then
+ OBJDUMP="false"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ OBJDUMP=$ac_ct_OBJDUMP
+ fi
+else
+ OBJDUMP="$ac_cv_prog_OBJDUMP"
+fi
+
+test -z "$OBJDUMP" && OBJDUMP=objdump
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5
+$as_echo_n "checking how to recognize dependent libraries... " >&6; }
+if ${lt_cv_deplibs_check_method+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_file_magic_cmd='$MAGIC_CMD'
+lt_cv_file_magic_test_file=
+lt_cv_deplibs_check_method='unknown'
+# Need to set the preceding variable on all platforms that support
+# interlibrary dependencies.
+# 'none' -- dependencies not supported.
+# `unknown' -- same as none, but documents that we really don't know.
+# 'pass_all' -- all dependencies passed with no checks.
+# 'test_compile' -- check by making test program.
+# 'file_magic [[regex]]' -- check by looking for files in library path
+# which responds to the $file_magic_cmd with a given extended regex.
+# If you have `file' or equivalent on your system and you're not sure
+# whether `pass_all' will *always* work, you probably want this one.
+
+case $host_os in
+aix[4-9]*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+beos*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+bsdi[45]*)
+ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)'
+ lt_cv_file_magic_cmd='/usr/bin/file -L'
+ lt_cv_file_magic_test_file=/shlib/libc.so
+ ;;
+
+cygwin*)
+ # func_win32_libid is a shell function defined in ltmain.sh
+ lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+ lt_cv_file_magic_cmd='func_win32_libid'
+ ;;
+
+mingw* | pw32*)
+ # Base MSYS/MinGW do not provide the 'file' command needed by
+ # func_win32_libid shell function, so use a weaker test based on 'objdump',
+ # unless we find 'file', for example because we are cross-compiling.
+ # func_win32_libid assumes BSD nm, so disallow it if using MS dumpbin.
+ if ( test "$lt_cv_nm_interface" = "BSD nm" && file / ) >/dev/null 2>&1; then
+ lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+ lt_cv_file_magic_cmd='func_win32_libid'
+ else
+ # Keep this pattern in sync with the one in func_win32_libid.
+ lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)'
+ lt_cv_file_magic_cmd='$OBJDUMP -f'
+ fi
+ ;;
+
+cegcc*)
+ # use the weaker test based on 'objdump'. See mingw*.
+ lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?'
+ lt_cv_file_magic_cmd='$OBJDUMP -f'
+ ;;
+
+darwin* | rhapsody*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+freebsd* | dragonfly*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
+ case $host_cpu in
+ i*86 )
+ # Not sure whether the presence of OpenBSD here was a mistake.
+ # Let's accept both of them until this is cleared up.
+ lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library'
+ lt_cv_file_magic_cmd=/usr/bin/file
+ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
+ ;;
+ esac
+ else
+ lt_cv_deplibs_check_method=pass_all
+ fi
+ ;;
+
+gnu*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+haiku*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+hpux10.20* | hpux11*)
+ lt_cv_file_magic_cmd=/usr/bin/file
+ case $host_cpu in
+ ia64*)
+ lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64'
+ lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so
+ ;;
+ hppa*64*)
+ lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]'
+ lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl
+ ;;
+ *)
+ lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9]\.[0-9]) shared library'
+ lt_cv_file_magic_test_file=/usr/lib/libc.sl
+ ;;
+ esac
+ ;;
+
+interix[3-9]*)
+ # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here
+ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$'
+ ;;
+
+irix5* | irix6* | nonstopux*)
+ case $LD in
+ *-32|*"-32 ") libmagic=32-bit;;
+ *-n32|*"-n32 ") libmagic=N32;;
+ *-64|*"-64 ") libmagic=64-bit;;
+ *) libmagic=never-match;;
+ esac
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+# This must be glibc/ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+netbsd*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
+ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$'
+ else
+ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$'
+ fi
+ ;;
+
+newos6*)
+ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)'
+ lt_cv_file_magic_cmd=/usr/bin/file
+ lt_cv_file_magic_test_file=/usr/lib/libnls.so
+ ;;
+
+*nto* | *qnx*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+openbsd*)
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$'
+ else
+ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$'
+ fi
+ ;;
+
+osf3* | osf4* | osf5*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+rdos*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+solaris*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+sysv4 | sysv4.3*)
+ case $host_vendor in
+ motorola)
+ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]'
+ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*`
+ ;;
+ ncr)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ sequent)
+ lt_cv_file_magic_cmd='/bin/file'
+ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )'
+ ;;
+ sni)
+ lt_cv_file_magic_cmd='/bin/file'
+ lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib"
+ lt_cv_file_magic_test_file=/lib/libc.so
+ ;;
+ siemens)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ pc)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ esac
+ ;;
+
+tpf*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+esac
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5
+$as_echo "$lt_cv_deplibs_check_method" >&6; }
+
+file_magic_glob=
+want_nocaseglob=no
+if test "$build" = "$host"; then
+ case $host_os in
+ mingw* | pw32*)
+ if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then
+ want_nocaseglob=yes
+ else
+ file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[\1]\/[\1]\/g;/g"`
+ fi
+ ;;
+ esac
+fi
+
+file_magic_cmd=$lt_cv_file_magic_cmd
+deplibs_check_method=$lt_cv_deplibs_check_method
+test -z "$deplibs_check_method" && deplibs_check_method=unknown
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args.
+set dummy ${ac_tool_prefix}dlltool; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_DLLTOOL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$DLLTOOL"; then
+ ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+DLLTOOL=$ac_cv_prog_DLLTOOL
+if test -n "$DLLTOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5
+$as_echo "$DLLTOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_DLLTOOL"; then
+ ac_ct_DLLTOOL=$DLLTOOL
+ # Extract the first word of "dlltool", so it can be a program name with args.
+set dummy dlltool; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_DLLTOOL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_DLLTOOL"; then
+ ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_DLLTOOL="dlltool"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL
+if test -n "$ac_ct_DLLTOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5
+$as_echo "$ac_ct_DLLTOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_DLLTOOL" = x; then
+ DLLTOOL="false"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ DLLTOOL=$ac_ct_DLLTOOL
+ fi
+else
+ DLLTOOL="$ac_cv_prog_DLLTOOL"
+fi
+
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to associate runtime and link libraries" >&5
+$as_echo_n "checking how to associate runtime and link libraries... " >&6; }
+if ${lt_cv_sharedlib_from_linklib_cmd+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_sharedlib_from_linklib_cmd='unknown'
+
+case $host_os in
+cygwin* | mingw* | pw32* | cegcc*)
+ # two different shell functions defined in ltmain.sh
+ # decide which to use based on capabilities of $DLLTOOL
+ case `$DLLTOOL --help 2>&1` in
+ *--identify-strict*)
+ lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib
+ ;;
+ *)
+ lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback
+ ;;
+ esac
+ ;;
+*)
+ # fallback: assume linklib IS sharedlib
+ lt_cv_sharedlib_from_linklib_cmd="$ECHO"
+ ;;
+esac
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sharedlib_from_linklib_cmd" >&5
+$as_echo "$lt_cv_sharedlib_from_linklib_cmd" >&6; }
+sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd
+test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO
+
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+ for ac_prog in ar
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_AR+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$AR"; then
+ ac_cv_prog_AR="$AR" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_AR="$ac_tool_prefix$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+AR=$ac_cv_prog_AR
+if test -n "$AR"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5
+$as_echo "$AR" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$AR" && break
+ done
+fi
+if test -z "$AR"; then
+ ac_ct_AR=$AR
+ for ac_prog in ar
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_AR+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_AR"; then
+ ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_AR="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_AR=$ac_cv_prog_ac_ct_AR
+if test -n "$ac_ct_AR"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5
+$as_echo "$ac_ct_AR" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$ac_ct_AR" && break
+done
+
+ if test "x$ac_ct_AR" = x; then
+ AR="false"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ AR=$ac_ct_AR
+ fi
+fi
+
+: ${AR=ar}
+: ${AR_FLAGS=cru}
+
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for archiver @FILE support" >&5
+$as_echo_n "checking for archiver @FILE support... " >&6; }
+if ${lt_cv_ar_at_file+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_ar_at_file=no
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ echo conftest.$ac_objext > conftest.lst
+ lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&5'
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5
+ (eval $lt_ar_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ if test "$ac_status" -eq 0; then
+ # Ensure the archiver fails upon bogus file names.
+ rm -f conftest.$ac_objext libconftest.a
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5
+ (eval $lt_ar_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ if test "$ac_status" -ne 0; then
+ lt_cv_ar_at_file=@
+ fi
+ fi
+ rm -f conftest.* libconftest.a
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5
+$as_echo "$lt_cv_ar_at_file" >&6; }
+
+if test "x$lt_cv_ar_at_file" = xno; then
+ archiver_list_spec=
+else
+ archiver_list_spec=$lt_cv_ar_at_file
+fi
+
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
+set dummy ${ac_tool_prefix}strip; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_STRIP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$STRIP"; then
+ ac_cv_prog_STRIP="$STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_STRIP="${ac_tool_prefix}strip"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+STRIP=$ac_cv_prog_STRIP
+if test -n "$STRIP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5
+$as_echo "$STRIP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_STRIP"; then
+ ac_ct_STRIP=$STRIP
+ # Extract the first word of "strip", so it can be a program name with args.
+set dummy strip; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_STRIP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_STRIP"; then
+ ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_STRIP="strip"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP
+if test -n "$ac_ct_STRIP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5
+$as_echo "$ac_ct_STRIP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_STRIP" = x; then
+ STRIP=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ STRIP=$ac_ct_STRIP
+ fi
+else
+ STRIP="$ac_cv_prog_STRIP"
+fi
+
+test -z "$STRIP" && STRIP=:
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ranlib; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_RANLIB+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$RANLIB"; then
+ ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+RANLIB=$ac_cv_prog_RANLIB
+if test -n "$RANLIB"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5
+$as_echo "$RANLIB" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_RANLIB"; then
+ ac_ct_RANLIB=$RANLIB
+ # Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_RANLIB+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_RANLIB"; then
+ ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_RANLIB="ranlib"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
+if test -n "$ac_ct_RANLIB"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5
+$as_echo "$ac_ct_RANLIB" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_RANLIB" = x; then
+ RANLIB=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ RANLIB=$ac_ct_RANLIB
+ fi
+else
+ RANLIB="$ac_cv_prog_RANLIB"
+fi
+
+test -z "$RANLIB" && RANLIB=:
+
+
+
+
+
+
+# Determine commands to create old-style static archives.
+old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs'
+old_postinstall_cmds='chmod 644 $oldlib'
+old_postuninstall_cmds=
+
+if test -n "$RANLIB"; then
+ case $host_os in
+ openbsd*)
+ old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib"
+ ;;
+ *)
+ old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib"
+ ;;
+ esac
+ old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib"
+fi
+
+case $host_os in
+ darwin*)
+ lock_old_archive_extraction=yes ;;
+ *)
+ lock_old_archive_extraction=no ;;
+esac
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+
+
+# Check for command to grab the raw symbol name followed by C symbol from nm.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5
+$as_echo_n "checking command to parse $NM output from $compiler object... " >&6; }
+if ${lt_cv_sys_global_symbol_pipe+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+# These are sane defaults that work on at least a few old systems.
+# [They come from Ultrix. What could be older than Ultrix?!! ;)]
+
+# Character class describing NM global symbol codes.
+symcode='[BCDEGRST]'
+
+# Regexp to match symbols that can be accessed directly from C.
+sympat='\([_A-Za-z][_A-Za-z0-9]*\)'
+
+# Define system-specific variables.
+case $host_os in
+aix*)
+ symcode='[BCDT]'
+ ;;
+cygwin* | mingw* | pw32* | cegcc*)
+ symcode='[ABCDGISTW]'
+ ;;
+hpux*)
+ if test "$host_cpu" = ia64; then
+ symcode='[ABCDEGRST]'
+ fi
+ ;;
+irix* | nonstopux*)
+ symcode='[BCDEGRST]'
+ ;;
+osf*)
+ symcode='[BCDEGQRST]'
+ ;;
+solaris*)
+ symcode='[BDRT]'
+ ;;
+sco3.2v5*)
+ symcode='[DT]'
+ ;;
+sysv4.2uw2*)
+ symcode='[DT]'
+ ;;
+sysv5* | sco5v6* | unixware* | OpenUNIX*)
+ symcode='[ABDT]'
+ ;;
+sysv4)
+ symcode='[DFNSTU]'
+ ;;
+esac
+
+# If we're using GNU nm, then use its standard symbol codes.
+case `$NM -V 2>&1` in
+*GNU* | *'with BFD'*)
+ symcode='[ABCDGIRSTW]' ;;
+esac
+
+# Transform an extracted symbol line into a proper C declaration.
+# Some systems (esp. on ia64) link data and code symbols differently,
+# so use this general approach.
+lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'"
+
+# Transform an extracted symbol line into symbol name and symbol address
+lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\)[ ]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"\2\", (void *) \&\2},/p'"
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([^ ]*\)[ ]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \(lib[^ ]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"lib\2\", (void *) \&\2},/p'"
+
+# Handle CRLF in mingw tool chain
+opt_cr=
+case $build_os in
+mingw*)
+ opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp
+ ;;
+esac
+
+# Try without a prefix underscore, then with it.
+for ac_symprfx in "" "_"; do
+
+ # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol.
+ symxfrm="\\1 $ac_symprfx\\2 \\2"
+
+ # Write the raw and C identifiers.
+ if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+ # Fake it for dumpbin and say T for any non-static function
+ # and D for any global variable.
+ # Also find C++ and __fastcall symbols from MSVC++,
+ # which start with @ or ?.
+ lt_cv_sys_global_symbol_pipe="$AWK '"\
+" {last_section=section; section=\$ 3};"\
+" /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\
+" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\
+" \$ 0!~/External *\|/{next};"\
+" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\
+" {if(hide[section]) next};"\
+" {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\
+" {split(\$ 0, a, /\||\r/); split(a[2], s)};"\
+" s[1]~/^[@?]/{print s[1], s[1]; next};"\
+" s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\
+" ' prfx=^$ac_symprfx"
+ else
+ lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'"
+ fi
+ lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'"
+
+ # Check to see that the pipe works correctly.
+ pipe_works=no
+
+ rm -f conftest*
+ cat > conftest.$ac_ext <<_LT_EOF
+#ifdef __cplusplus
+extern "C" {
+#endif
+char nm_test_var;
+void nm_test_func(void);
+void nm_test_func(void){}
+#ifdef __cplusplus
+}
+#endif
+int main(){nm_test_var='a';nm_test_func();return(0);}
+_LT_EOF
+
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ # Now try to grab the symbols.
+ nlist=conftest.nm
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist\""; } >&5
+ (eval $NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && test -s "$nlist"; then
+ # Try sorting and uniquifying the output.
+ if sort "$nlist" | uniq > "$nlist"T; then
+ mv -f "$nlist"T "$nlist"
+ else
+ rm -f "$nlist"T
+ fi
+
+ # Make sure that we snagged all the symbols we need.
+ if $GREP ' nm_test_var$' "$nlist" >/dev/null; then
+ if $GREP ' nm_test_func$' "$nlist" >/dev/null; then
+ cat <<_LT_EOF > conftest.$ac_ext
+/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */
+#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE)
+/* DATA imports from DLLs on WIN32 con't be const, because runtime
+ relocations are performed -- see ld's documentation on pseudo-relocs. */
+# define LT_DLSYM_CONST
+#elif defined(__osf__)
+/* This system does not cope well with relocations in const data. */
+# define LT_DLSYM_CONST
+#else
+# define LT_DLSYM_CONST const
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+_LT_EOF
+ # Now generate the symbol file.
+ eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext'
+
+ cat <<_LT_EOF >> conftest.$ac_ext
+
+/* The mapping between symbol names and symbols. */
+LT_DLSYM_CONST struct {
+ const char *name;
+ void *address;
+}
+lt__PROGRAM__LTX_preloaded_symbols[] =
+{
+ { "@PROGRAM@", (void *) 0 },
+_LT_EOF
+ $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext
+ cat <<\_LT_EOF >> conftest.$ac_ext
+ {0, (void *) 0}
+};
+
+/* This works around a problem in FreeBSD linker */
+#ifdef FREEBSD_WORKAROUND
+static const void *lt_preloaded_setup() {
+ return lt__PROGRAM__LTX_preloaded_symbols;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+_LT_EOF
+ # Now try linking the two files.
+ mv conftest.$ac_objext conftstm.$ac_objext
+ lt_globsym_save_LIBS=$LIBS
+ lt_globsym_save_CFLAGS=$CFLAGS
+ LIBS="conftstm.$ac_objext"
+ CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag"
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && test -s conftest${ac_exeext}; then
+ pipe_works=yes
+ fi
+ LIBS=$lt_globsym_save_LIBS
+ CFLAGS=$lt_globsym_save_CFLAGS
+ else
+ echo "cannot find nm_test_func in $nlist" >&5
+ fi
+ else
+ echo "cannot find nm_test_var in $nlist" >&5
+ fi
+ else
+ echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5
+ fi
+ else
+ echo "$progname: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ fi
+ rm -rf conftest* conftst*
+
+ # Do not use the global_symbol_pipe unless it works.
+ if test "$pipe_works" = yes; then
+ break
+ else
+ lt_cv_sys_global_symbol_pipe=
+ fi
+done
+
+fi
+
+if test -z "$lt_cv_sys_global_symbol_pipe"; then
+ lt_cv_sys_global_symbol_to_cdecl=
+fi
+if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5
+$as_echo "failed" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5
+$as_echo "ok" >&6; }
+fi
+
+# Response file support.
+if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+ nm_file_list_spec='@'
+elif $NM --help 2>/dev/null | grep '[@]FILE' >/dev/null; then
+ nm_file_list_spec='@'
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5
+$as_echo_n "checking for sysroot... " >&6; }
+
+# Check whether --with-sysroot was given.
+if test "${with_sysroot+set}" = set; then :
+ withval=$with_sysroot;
+else
+ with_sysroot=no
+fi
+
+
+lt_sysroot=
+case ${with_sysroot} in #(
+ yes)
+ if test "$GCC" = yes; then
+ lt_sysroot=`$CC --print-sysroot 2>/dev/null`
+ fi
+ ;; #(
+ /*)
+ lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"`
+ ;; #(
+ no|'')
+ ;; #(
+ *)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${with_sysroot}" >&5
+$as_echo "${with_sysroot}" >&6; }
+ as_fn_error $? "The sysroot must be an absolute path." "$LINENO" 5
+ ;;
+esac
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${lt_sysroot:-no}" >&5
+$as_echo "${lt_sysroot:-no}" >&6; }
+
+
+
+
+
+# Check whether --enable-libtool-lock was given.
+if test "${enable_libtool_lock+set}" = set; then :
+ enableval=$enable_libtool_lock;
+fi
+
+test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case $host in
+ia64-*-hpux*)
+ # Find out which ABI we are using.
+ echo 'int i;' > conftest.$ac_ext
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ case `/usr/bin/file conftest.$ac_objext` in
+ *ELF-32*)
+ HPUX_IA64_MODE="32"
+ ;;
+ *ELF-64*)
+ HPUX_IA64_MODE="64"
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+*-*-irix6*)
+ # Find out which ABI we are using.
+ echo '#line '$LINENO' "configure"' > conftest.$ac_ext
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ if test "$lt_cv_prog_gnu_ld" = yes; then
+ case `/usr/bin/file conftest.$ac_objext` in
+ *32-bit*)
+ LD="${LD-ld} -melf32bsmip"
+ ;;
+ *N32*)
+ LD="${LD-ld} -melf32bmipn32"
+ ;;
+ *64-bit*)
+ LD="${LD-ld} -melf64bmip"
+ ;;
+ esac
+ else
+ case `/usr/bin/file conftest.$ac_objext` in
+ *32-bit*)
+ LD="${LD-ld} -32"
+ ;;
+ *N32*)
+ LD="${LD-ld} -n32"
+ ;;
+ *64-bit*)
+ LD="${LD-ld} -64"
+ ;;
+ esac
+ fi
+ fi
+ rm -rf conftest*
+ ;;
+
+x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \
+s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
+ # Find out which ABI we are using.
+ echo 'int i;' > conftest.$ac_ext
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ case `/usr/bin/file conftest.o` in
+ *32-bit*)
+ case $host in
+ x86_64-*kfreebsd*-gnu)
+ LD="${LD-ld} -m elf_i386_fbsd"
+ ;;
+ x86_64-*linux*)
+ LD="${LD-ld} -m elf_i386"
+ ;;
+ ppc64-*linux*|powerpc64-*linux*)
+ LD="${LD-ld} -m elf32ppclinux"
+ ;;
+ s390x-*linux*)
+ LD="${LD-ld} -m elf_s390"
+ ;;
+ sparc64-*linux*)
+ LD="${LD-ld} -m elf32_sparc"
+ ;;
+ esac
+ ;;
+ *64-bit*)
+ case $host in
+ x86_64-*kfreebsd*-gnu)
+ LD="${LD-ld} -m elf_x86_64_fbsd"
+ ;;
+ x86_64-*linux*)
+ LD="${LD-ld} -m elf_x86_64"
+ ;;
+ ppc*-*linux*|powerpc*-*linux*)
+ LD="${LD-ld} -m elf64ppc"
+ ;;
+ s390*-*linux*|s390*-*tpf*)
+ LD="${LD-ld} -m elf64_s390"
+ ;;
+ sparc*-*linux*)
+ LD="${LD-ld} -m elf64_sparc"
+ ;;
+ esac
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+
+*-*-sco3.2v5*)
+ # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+ SAVE_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -belf"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5
+$as_echo_n "checking whether the C compiler needs -belf... " >&6; }
+if ${lt_cv_cc_needs_belf+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ lt_cv_cc_needs_belf=yes
+else
+ lt_cv_cc_needs_belf=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5
+$as_echo "$lt_cv_cc_needs_belf" >&6; }
+ if test x"$lt_cv_cc_needs_belf" != x"yes"; then
+ # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
+ CFLAGS="$SAVE_CFLAGS"
+ fi
+ ;;
+*-*solaris*)
+ # Find out which ABI we are using.
+ echo 'int i;' > conftest.$ac_ext
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ case `/usr/bin/file conftest.o` in
+ *64-bit*)
+ case $lt_cv_prog_gnu_ld in
+ yes*)
+ case $host in
+ i?86-*-solaris*)
+ LD="${LD-ld} -m elf_x86_64"
+ ;;
+ sparc*-*-solaris*)
+ LD="${LD-ld} -m elf64_sparc"
+ ;;
+ esac
+ # GNU ld 2.21 introduced _sol2 emulations. Use them if available.
+ if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then
+ LD="${LD-ld}_sol2"
+ fi
+ ;;
+ *)
+ if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then
+ LD="${LD-ld} -64"
+ fi
+ ;;
+ esac
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+esac
+
+need_locks="$enable_libtool_lock"
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}mt", so it can be a program name with args.
+set dummy ${ac_tool_prefix}mt; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_MANIFEST_TOOL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$MANIFEST_TOOL"; then
+ ac_cv_prog_MANIFEST_TOOL="$MANIFEST_TOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_MANIFEST_TOOL="${ac_tool_prefix}mt"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+MANIFEST_TOOL=$ac_cv_prog_MANIFEST_TOOL
+if test -n "$MANIFEST_TOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MANIFEST_TOOL" >&5
+$as_echo "$MANIFEST_TOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_MANIFEST_TOOL"; then
+ ac_ct_MANIFEST_TOOL=$MANIFEST_TOOL
+ # Extract the first word of "mt", so it can be a program name with args.
+set dummy mt; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_MANIFEST_TOOL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_MANIFEST_TOOL"; then
+ ac_cv_prog_ac_ct_MANIFEST_TOOL="$ac_ct_MANIFEST_TOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_MANIFEST_TOOL="mt"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_MANIFEST_TOOL=$ac_cv_prog_ac_ct_MANIFEST_TOOL
+if test -n "$ac_ct_MANIFEST_TOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_MANIFEST_TOOL" >&5
+$as_echo "$ac_ct_MANIFEST_TOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_MANIFEST_TOOL" = x; then
+ MANIFEST_TOOL=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ MANIFEST_TOOL=$ac_ct_MANIFEST_TOOL
+ fi
+else
+ MANIFEST_TOOL="$ac_cv_prog_MANIFEST_TOOL"
+fi
+
+test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $MANIFEST_TOOL is a manifest tool" >&5
+$as_echo_n "checking if $MANIFEST_TOOL is a manifest tool... " >&6; }
+if ${lt_cv_path_mainfest_tool+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_path_mainfest_tool=no
+ echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&5
+ $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out
+ cat conftest.err >&5
+ if $GREP 'Manifest Tool' conftest.out > /dev/null; then
+ lt_cv_path_mainfest_tool=yes
+ fi
+ rm -f conftest*
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5
+$as_echo "$lt_cv_path_mainfest_tool" >&6; }
+if test "x$lt_cv_path_mainfest_tool" != xyes; then
+ MANIFEST_TOOL=:
+fi
+
+
+
+
+
+
+ case $host_os in
+ rhapsody* | darwin*)
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args.
+set dummy ${ac_tool_prefix}dsymutil; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_DSYMUTIL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$DSYMUTIL"; then
+ ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+DSYMUTIL=$ac_cv_prog_DSYMUTIL
+if test -n "$DSYMUTIL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5
+$as_echo "$DSYMUTIL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_DSYMUTIL"; then
+ ac_ct_DSYMUTIL=$DSYMUTIL
+ # Extract the first word of "dsymutil", so it can be a program name with args.
+set dummy dsymutil; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_DSYMUTIL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_DSYMUTIL"; then
+ ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_DSYMUTIL="dsymutil"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL
+if test -n "$ac_ct_DSYMUTIL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5
+$as_echo "$ac_ct_DSYMUTIL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_DSYMUTIL" = x; then
+ DSYMUTIL=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ DSYMUTIL=$ac_ct_DSYMUTIL
+ fi
+else
+ DSYMUTIL="$ac_cv_prog_DSYMUTIL"
+fi
+
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args.
+set dummy ${ac_tool_prefix}nmedit; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_NMEDIT+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$NMEDIT"; then
+ ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+NMEDIT=$ac_cv_prog_NMEDIT
+if test -n "$NMEDIT"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5
+$as_echo "$NMEDIT" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_NMEDIT"; then
+ ac_ct_NMEDIT=$NMEDIT
+ # Extract the first word of "nmedit", so it can be a program name with args.
+set dummy nmedit; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_NMEDIT+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_NMEDIT"; then
+ ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_NMEDIT="nmedit"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT
+if test -n "$ac_ct_NMEDIT"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5
+$as_echo "$ac_ct_NMEDIT" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_NMEDIT" = x; then
+ NMEDIT=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ NMEDIT=$ac_ct_NMEDIT
+ fi
+else
+ NMEDIT="$ac_cv_prog_NMEDIT"
+fi
+
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args.
+set dummy ${ac_tool_prefix}lipo; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_LIPO+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$LIPO"; then
+ ac_cv_prog_LIPO="$LIPO" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_LIPO="${ac_tool_prefix}lipo"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+LIPO=$ac_cv_prog_LIPO
+if test -n "$LIPO"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5
+$as_echo "$LIPO" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_LIPO"; then
+ ac_ct_LIPO=$LIPO
+ # Extract the first word of "lipo", so it can be a program name with args.
+set dummy lipo; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_LIPO+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_LIPO"; then
+ ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_LIPO="lipo"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO
+if test -n "$ac_ct_LIPO"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5
+$as_echo "$ac_ct_LIPO" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_LIPO" = x; then
+ LIPO=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ LIPO=$ac_ct_LIPO
+ fi
+else
+ LIPO="$ac_cv_prog_LIPO"
+fi
+
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args.
+set dummy ${ac_tool_prefix}otool; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_OTOOL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$OTOOL"; then
+ ac_cv_prog_OTOOL="$OTOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_OTOOL="${ac_tool_prefix}otool"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+OTOOL=$ac_cv_prog_OTOOL
+if test -n "$OTOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5
+$as_echo "$OTOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_OTOOL"; then
+ ac_ct_OTOOL=$OTOOL
+ # Extract the first word of "otool", so it can be a program name with args.
+set dummy otool; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_OTOOL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_OTOOL"; then
+ ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_OTOOL="otool"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL
+if test -n "$ac_ct_OTOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5
+$as_echo "$ac_ct_OTOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_OTOOL" = x; then
+ OTOOL=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ OTOOL=$ac_ct_OTOOL
+ fi
+else
+ OTOOL="$ac_cv_prog_OTOOL"
+fi
+
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args.
+set dummy ${ac_tool_prefix}otool64; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_OTOOL64+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$OTOOL64"; then
+ ac_cv_prog_OTOOL64="$OTOOL64" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+OTOOL64=$ac_cv_prog_OTOOL64
+if test -n "$OTOOL64"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5
+$as_echo "$OTOOL64" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_OTOOL64"; then
+ ac_ct_OTOOL64=$OTOOL64
+ # Extract the first word of "otool64", so it can be a program name with args.
+set dummy otool64; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_OTOOL64+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_OTOOL64"; then
+ ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_OTOOL64="otool64"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64
+if test -n "$ac_ct_OTOOL64"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5
+$as_echo "$ac_ct_OTOOL64" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_OTOOL64" = x; then
+ OTOOL64=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ OTOOL64=$ac_ct_OTOOL64
+ fi
+else
+ OTOOL64="$ac_cv_prog_OTOOL64"
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5
+$as_echo_n "checking for -single_module linker flag... " >&6; }
+if ${lt_cv_apple_cc_single_mod+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_apple_cc_single_mod=no
+ if test -z "${LT_MULTI_MODULE}"; then
+ # By default we will add the -single_module flag. You can override
+ # by either setting the environment variable LT_MULTI_MODULE
+ # non-empty at configure time, or by adding -multi_module to the
+ # link flags.
+ rm -rf libconftest.dylib*
+ echo "int foo(void){return 1;}" > conftest.c
+ echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
+-dynamiclib -Wl,-single_module conftest.c" >&5
+ $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
+ -dynamiclib -Wl,-single_module conftest.c 2>conftest.err
+ _lt_result=$?
+ # If there is a non-empty error log, and "single_module"
+ # appears in it, assume the flag caused a linker warning
+ if test -s conftest.err && $GREP single_module conftest.err; then
+ cat conftest.err >&5
+ # Otherwise, if the output was created with a 0 exit code from
+ # the compiler, it worked.
+ elif test -f libconftest.dylib && test $_lt_result -eq 0; then
+ lt_cv_apple_cc_single_mod=yes
+ else
+ cat conftest.err >&5
+ fi
+ rm -rf libconftest.dylib*
+ rm -f conftest.*
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5
+$as_echo "$lt_cv_apple_cc_single_mod" >&6; }
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5
+$as_echo_n "checking for -exported_symbols_list linker flag... " >&6; }
+if ${lt_cv_ld_exported_symbols_list+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_ld_exported_symbols_list=no
+ save_LDFLAGS=$LDFLAGS
+ echo "_main" > conftest.sym
+ LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ lt_cv_ld_exported_symbols_list=yes
+else
+ lt_cv_ld_exported_symbols_list=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ LDFLAGS="$save_LDFLAGS"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5
+$as_echo "$lt_cv_ld_exported_symbols_list" >&6; }
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5
+$as_echo_n "checking for -force_load linker flag... " >&6; }
+if ${lt_cv_ld_force_load+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_ld_force_load=no
+ cat > conftest.c << _LT_EOF
+int forced_loaded() { return 2;}
+_LT_EOF
+ echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5
+ $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5
+ echo "$AR cru libconftest.a conftest.o" >&5
+ $AR cru libconftest.a conftest.o 2>&5
+ echo "$RANLIB libconftest.a" >&5
+ $RANLIB libconftest.a 2>&5
+ cat > conftest.c << _LT_EOF
+int main() { return 0;}
+_LT_EOF
+ echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5
+ $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err
+ _lt_result=$?
+ if test -s conftest.err && $GREP force_load conftest.err; then
+ cat conftest.err >&5
+ elif test -f conftest && test $_lt_result -eq 0 && $GREP forced_load conftest >/dev/null 2>&1 ; then
+ lt_cv_ld_force_load=yes
+ else
+ cat conftest.err >&5
+ fi
+ rm -f conftest.err libconftest.a conftest conftest.c
+ rm -rf conftest.dSYM
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5
+$as_echo "$lt_cv_ld_force_load" >&6; }
+ case $host_os in
+ rhapsody* | darwin1.[012])
+ _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;;
+ darwin1.*)
+ _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
+ darwin*) # darwin 5.x on
+ # if running on 10.5 or later, the deployment target defaults
+ # to the OS version, if on x86, and 10.4, the deployment
+ # target defaults to 10.4. Don't you love it?
+ case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in
+ 10.0,*86*-darwin8*|10.0,*-darwin[91]*)
+ _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
+ 10.[012]*)
+ _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
+ 10.*)
+ _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
+ esac
+ ;;
+ esac
+ if test "$lt_cv_apple_cc_single_mod" = "yes"; then
+ _lt_dar_single_mod='$single_module'
+ fi
+ if test "$lt_cv_ld_exported_symbols_list" = "yes"; then
+ _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym'
+ else
+ _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}'
+ fi
+ if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then
+ _lt_dsymutil='~$DSYMUTIL $lib || :'
+ else
+ _lt_dsymutil=
+ fi
+ ;;
+ esac
+
+for ac_header in dlfcn.h
+do :
+ ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default
+"
+if test "x$ac_cv_header_dlfcn_h" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_DLFCN_H 1
+_ACEOF
+
+fi
+
+done
+
+
+
+
+
+# Set options
+
+
+
+ enable_dlopen=no
+
+
+ enable_win32_dll=no
+
+
+ # Check whether --enable-shared was given.
+if test "${enable_shared+set}" = set; then :
+ enableval=$enable_shared; p=${PACKAGE-default}
+ case $enableval in
+ yes) enable_shared=yes ;;
+ no) enable_shared=no ;;
+ *)
+ enable_shared=no
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+ for pkg in $enableval; do
+ IFS="$lt_save_ifs"
+ if test "X$pkg" = "X$p"; then
+ enable_shared=yes
+ fi
+ done
+ IFS="$lt_save_ifs"
+ ;;
+ esac
+else
+ enable_shared=yes
+fi
+
+
+
+
+
+
+
+
+
+ # Check whether --enable-static was given.
+if test "${enable_static+set}" = set; then :
+ enableval=$enable_static; p=${PACKAGE-default}
+ case $enableval in
+ yes) enable_static=yes ;;
+ no) enable_static=no ;;
+ *)
+ enable_static=no
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+ for pkg in $enableval; do
+ IFS="$lt_save_ifs"
+ if test "X$pkg" = "X$p"; then
+ enable_static=yes
+ fi
+ done
+ IFS="$lt_save_ifs"
+ ;;
+ esac
+else
+ enable_static=yes
+fi
+
+
+
+
+
+
+
+
+
+
+# Check whether --with-pic was given.
+if test "${with_pic+set}" = set; then :
+ withval=$with_pic; lt_p=${PACKAGE-default}
+ case $withval in
+ yes|no) pic_mode=$withval ;;
+ *)
+ pic_mode=default
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+ for lt_pkg in $withval; do
+ IFS="$lt_save_ifs"
+ if test "X$lt_pkg" = "X$lt_p"; then
+ pic_mode=yes
+ fi
+ done
+ IFS="$lt_save_ifs"
+ ;;
+ esac
+else
+ pic_mode=default
+fi
+
+
+test -z "$pic_mode" && pic_mode=default
+
+
+
+
+
+
+
+ # Check whether --enable-fast-install was given.
+if test "${enable_fast_install+set}" = set; then :
+ enableval=$enable_fast_install; p=${PACKAGE-default}
+ case $enableval in
+ yes) enable_fast_install=yes ;;
+ no) enable_fast_install=no ;;
+ *)
+ enable_fast_install=no
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+ for pkg in $enableval; do
+ IFS="$lt_save_ifs"
+ if test "X$pkg" = "X$p"; then
+ enable_fast_install=yes
+ fi
+ done
+ IFS="$lt_save_ifs"
+ ;;
+ esac
+else
+ enable_fast_install=yes
+fi
+
+
+
+
+
+
+
+
+
+
+
+# This can be used to rebuild libtool when needed
+LIBTOOL_DEPS="$ltmain"
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+test -z "$LN_S" && LN_S="ln -s"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+if test -n "${ZSH_VERSION+set}" ; then
+ setopt NO_GLOB_SUBST
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5
+$as_echo_n "checking for objdir... " >&6; }
+if ${lt_cv_objdir+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ rm -f .libs 2>/dev/null
+mkdir .libs 2>/dev/null
+if test -d .libs; then
+ lt_cv_objdir=.libs
+else
+ # MS-DOS does not allow filenames that begin with a dot.
+ lt_cv_objdir=_libs
+fi
+rmdir .libs 2>/dev/null
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5
+$as_echo "$lt_cv_objdir" >&6; }
+objdir=$lt_cv_objdir
+
+
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define LT_OBJDIR "$lt_cv_objdir/"
+_ACEOF
+
+
+
+
+case $host_os in
+aix3*)
+ # AIX sometimes has problems with the GCC collect2 program. For some
+ # reason, if we set the COLLECT_NAMES environment variable, the problems
+ # vanish in a puff of smoke.
+ if test "X${COLLECT_NAMES+set}" != Xset; then
+ COLLECT_NAMES=
+ export COLLECT_NAMES
+ fi
+ ;;
+esac
+
+# Global variables:
+ofile=libtool
+can_build_shared=yes
+
+# All known linkers require a `.a' archive for static linking (except MSVC,
+# which needs '.lib').
+libext=a
+
+with_gnu_ld="$lt_cv_prog_gnu_ld"
+
+old_CC="$CC"
+old_CFLAGS="$CFLAGS"
+
+# Set sane defaults for various variables
+test -z "$CC" && CC=cc
+test -z "$LTCC" && LTCC=$CC
+test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS
+test -z "$LD" && LD=ld
+test -z "$ac_objext" && ac_objext=o
+
+for cc_temp in $compiler""; do
+ case $cc_temp in
+ compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
+ distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
+ \-*) ;;
+ *) break;;
+ esac
+done
+cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"`
+
+
+# Only perform the check for file, if the check method requires it
+test -z "$MAGIC_CMD" && MAGIC_CMD=file
+case $deplibs_check_method in
+file_magic*)
+ if test "$file_magic_cmd" = '$MAGIC_CMD'; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5
+$as_echo_n "checking for ${ac_tool_prefix}file... " >&6; }
+if ${lt_cv_path_MAGIC_CMD+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $MAGIC_CMD in
+[\\/*] | ?:[\\/]*)
+ lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
+ ;;
+*)
+ lt_save_MAGIC_CMD="$MAGIC_CMD"
+ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+ ac_dummy="/usr/bin$PATH_SEPARATOR$PATH"
+ for ac_dir in $ac_dummy; do
+ IFS="$lt_save_ifs"
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/${ac_tool_prefix}file; then
+ lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file"
+ if test -n "$file_magic_test_file"; then
+ case $deplibs_check_method in
+ "file_magic "*)
+ file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
+ MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+ if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+ $EGREP "$file_magic_regex" > /dev/null; then
+ :
+ else
+ cat <<_LT_EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such. This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem. Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+_LT_EOF
+ fi ;;
+ esac
+ fi
+ break
+ fi
+ done
+ IFS="$lt_save_ifs"
+ MAGIC_CMD="$lt_save_MAGIC_CMD"
+ ;;
+esac
+fi
+
+MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+if test -n "$MAGIC_CMD"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5
+$as_echo "$MAGIC_CMD" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+
+
+
+if test -z "$lt_cv_path_MAGIC_CMD"; then
+ if test -n "$ac_tool_prefix"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for file" >&5
+$as_echo_n "checking for file... " >&6; }
+if ${lt_cv_path_MAGIC_CMD+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $MAGIC_CMD in
+[\\/*] | ?:[\\/]*)
+ lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
+ ;;
+*)
+ lt_save_MAGIC_CMD="$MAGIC_CMD"
+ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+ ac_dummy="/usr/bin$PATH_SEPARATOR$PATH"
+ for ac_dir in $ac_dummy; do
+ IFS="$lt_save_ifs"
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/file; then
+ lt_cv_path_MAGIC_CMD="$ac_dir/file"
+ if test -n "$file_magic_test_file"; then
+ case $deplibs_check_method in
+ "file_magic "*)
+ file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
+ MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+ if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+ $EGREP "$file_magic_regex" > /dev/null; then
+ :
+ else
+ cat <<_LT_EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such. This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem. Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+_LT_EOF
+ fi ;;
+ esac
+ fi
+ break
+ fi
+ done
+ IFS="$lt_save_ifs"
+ MAGIC_CMD="$lt_save_MAGIC_CMD"
+ ;;
+esac
+fi
+
+MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+if test -n "$MAGIC_CMD"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5
+$as_echo "$MAGIC_CMD" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ else
+ MAGIC_CMD=:
+ fi
+fi
+
+ fi
+ ;;
+esac
+
+# Use C for the default configuration in the libtool script
+
+lt_save_CC="$CC"
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+# Source file extension for C test sources.
+ac_ext=c
+
+# Object file extension for compiled C test sources.
+objext=o
+objext=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="int some_variable = 0;"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='int main(){return(0);}'
+
+
+
+
+
+
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+
+# Save the default compiler, since it gets overwritten when the other
+# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP.
+compiler_DEFAULT=$CC
+
+# save warnings/boilerplate of simple test code
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_compile_test_code" >conftest.$ac_ext
+eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_compiler_boilerplate=`cat conftest.err`
+$RM conftest*
+
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_link_test_code" >conftest.$ac_ext
+eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_linker_boilerplate=`cat conftest.err`
+$RM -r conftest*
+
+
+## CAVEAT EMPTOR:
+## There is no encapsulation within the following macros, do not change
+## the running order or otherwise move them around unless you know exactly
+## what you are doing...
+if test -n "$compiler"; then
+
+lt_prog_compiler_no_builtin_flag=
+
+if test "$GCC" = yes; then
+ case $cc_basename in
+ nvcc*)
+ lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;;
+ *)
+ lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;;
+ esac
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5
+$as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; }
+if ${lt_cv_prog_compiler_rtti_exceptions+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_rtti_exceptions=no
+ ac_outfile=conftest.$ac_objext
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+ lt_compiler_flag="-fno-rtti -fno-exceptions"
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ # The option is referenced via a variable to avoid confusing sed.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>conftest.err)
+ ac_status=$?
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s "$ac_outfile"; then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings other than the usual output.
+ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_rtti_exceptions=yes
+ fi
+ fi
+ $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5
+$as_echo "$lt_cv_prog_compiler_rtti_exceptions" >&6; }
+
+if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then
+ lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions"
+else
+ :
+fi
+
+fi
+
+
+
+
+
+
+ lt_prog_compiler_wl=
+lt_prog_compiler_pic=
+lt_prog_compiler_static=
+
+
+ if test "$GCC" = yes; then
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_static='-static'
+
+ case $host_os in
+ aix*)
+ # All AIX code is PIC.
+ if test "$host_cpu" = ia64; then
+ # AIX 5 now supports IA64 processor
+ lt_prog_compiler_static='-Bstatic'
+ fi
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ lt_prog_compiler_pic='-fPIC'
+ ;;
+ m68k)
+ # FIXME: we need at least 68020 code to build shared libraries, but
+ # adding the `-m68020' flag to GCC prevents building anything better,
+ # like `-m68040'.
+ lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4'
+ ;;
+ esac
+ ;;
+
+ beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+ # PIC is the default for these OSes.
+ ;;
+
+ mingw* | cygwin* | pw32* | os2* | cegcc*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ # Although the cygwin gcc ignores -fPIC, still need this for old-style
+ # (--disable-auto-import) libraries
+ lt_prog_compiler_pic='-DDLL_EXPORT'
+ ;;
+
+ darwin* | rhapsody*)
+ # PIC is the default on this platform
+ # Common symbols not allowed in MH_DYLIB files
+ lt_prog_compiler_pic='-fno-common'
+ ;;
+
+ haiku*)
+ # PIC is the default for Haiku.
+ # The "-static" flag exists, but is broken.
+ lt_prog_compiler_static=
+ ;;
+
+ hpux*)
+ # PIC is the default for 64-bit PA HP-UX, but not for 32-bit
+ # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag
+ # sets the default TLS model and affects inlining.
+ case $host_cpu in
+ hppa*64*)
+ # +Z the default
+ ;;
+ *)
+ lt_prog_compiler_pic='-fPIC'
+ ;;
+ esac
+ ;;
+
+ interix[3-9]*)
+ # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+ # Instead, we relocate shared libraries at runtime.
+ ;;
+
+ msdosdjgpp*)
+ # Just because we use GCC doesn't mean we suddenly get shared libraries
+ # on systems that don't support them.
+ lt_prog_compiler_can_build_shared=no
+ enable_shared=no
+ ;;
+
+ *nto* | *qnx*)
+ # QNX uses GNU C++, but need to define -shared option too, otherwise
+ # it will coredump.
+ lt_prog_compiler_pic='-fPIC -shared'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ lt_prog_compiler_pic=-Kconform_pic
+ fi
+ ;;
+
+ *)
+ lt_prog_compiler_pic='-fPIC'
+ ;;
+ esac
+
+ case $cc_basename in
+ nvcc*) # Cuda Compiler Driver 2.2
+ lt_prog_compiler_wl='-Xlinker '
+ if test -n "$lt_prog_compiler_pic"; then
+ lt_prog_compiler_pic="-Xcompiler $lt_prog_compiler_pic"
+ fi
+ ;;
+ esac
+ else
+ # PORTME Check for flag to pass linker flags through the system compiler.
+ case $host_os in
+ aix*)
+ lt_prog_compiler_wl='-Wl,'
+ if test "$host_cpu" = ia64; then
+ # AIX 5 now supports IA64 processor
+ lt_prog_compiler_static='-Bstatic'
+ else
+ lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp'
+ fi
+ ;;
+
+ mingw* | cygwin* | pw32* | os2* | cegcc*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ lt_prog_compiler_pic='-DDLL_EXPORT'
+ ;;
+
+ hpux9* | hpux10* | hpux11*)
+ lt_prog_compiler_wl='-Wl,'
+ # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
+ # not for PA HP-UX.
+ case $host_cpu in
+ hppa*64*|ia64*)
+ # +Z the default
+ ;;
+ *)
+ lt_prog_compiler_pic='+Z'
+ ;;
+ esac
+ # Is there a better lt_prog_compiler_static that works with the bundled CC?
+ lt_prog_compiler_static='${wl}-a ${wl}archive'
+ ;;
+
+ irix5* | irix6* | nonstopux*)
+ lt_prog_compiler_wl='-Wl,'
+ # PIC (with -KPIC) is the default.
+ lt_prog_compiler_static='-non_shared'
+ ;;
+
+ linux* | k*bsd*-gnu | kopensolaris*-gnu)
+ case $cc_basename in
+ # old Intel for x86_64 which still supported -KPIC.
+ ecc*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-static'
+ ;;
+ # icc used to be incompatible with GCC.
+ # ICC 10 doesn't accept -KPIC any more.
+ icc* | ifort*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-fPIC'
+ lt_prog_compiler_static='-static'
+ ;;
+ # Lahey Fortran 8.1.
+ lf95*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='--shared'
+ lt_prog_compiler_static='--static'
+ ;;
+ nagfor*)
+ # NAG Fortran compiler
+ lt_prog_compiler_wl='-Wl,-Wl,,'
+ lt_prog_compiler_pic='-PIC'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+ pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*)
+ # Portland Group compilers (*not* the Pentium gcc compiler,
+ # which looks to be a dead project)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-fpic'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+ ccc*)
+ lt_prog_compiler_wl='-Wl,'
+ # All Alpha code is PIC.
+ lt_prog_compiler_static='-non_shared'
+ ;;
+ xl* | bgxl* | bgf* | mpixl*)
+ # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-qpic'
+ lt_prog_compiler_static='-qstaticlink'
+ ;;
+ *)
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [1-7].* | *Sun*Fortran*\ 8.[0-3]*)
+ # Sun Fortran 8.3 passes all unrecognized flags to the linker
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ lt_prog_compiler_wl=''
+ ;;
+ *Sun\ F* | *Sun*Fortran*)
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ lt_prog_compiler_wl='-Qoption ld '
+ ;;
+ *Sun\ C*)
+ # Sun C 5.9
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ lt_prog_compiler_wl='-Wl,'
+ ;;
+ *Intel*\ [CF]*Compiler*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-fPIC'
+ lt_prog_compiler_static='-static'
+ ;;
+ *Portland\ Group*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-fpic'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+ esac
+ ;;
+ esac
+ ;;
+
+ newsos6)
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+
+ *nto* | *qnx*)
+ # QNX uses GNU C++, but need to define -shared option too, otherwise
+ # it will coredump.
+ lt_prog_compiler_pic='-fPIC -shared'
+ ;;
+
+ osf3* | osf4* | osf5*)
+ lt_prog_compiler_wl='-Wl,'
+ # All OSF/1 code is PIC.
+ lt_prog_compiler_static='-non_shared'
+ ;;
+
+ rdos*)
+ lt_prog_compiler_static='-non_shared'
+ ;;
+
+ solaris*)
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ case $cc_basename in
+ f77* | f90* | f95* | sunf77* | sunf90* | sunf95*)
+ lt_prog_compiler_wl='-Qoption ld ';;
+ *)
+ lt_prog_compiler_wl='-Wl,';;
+ esac
+ ;;
+
+ sunos4*)
+ lt_prog_compiler_wl='-Qoption ld '
+ lt_prog_compiler_pic='-PIC'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+
+ sysv4 | sysv4.2uw2* | sysv4.3*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec ;then
+ lt_prog_compiler_pic='-Kconform_pic'
+ lt_prog_compiler_static='-Bstatic'
+ fi
+ ;;
+
+ sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+
+ unicos*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_can_build_shared=no
+ ;;
+
+ uts4*)
+ lt_prog_compiler_pic='-pic'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+
+ *)
+ lt_prog_compiler_can_build_shared=no
+ ;;
+ esac
+ fi
+
+case $host_os in
+ # For platforms which do not support PIC, -DPIC is meaningless:
+ *djgpp*)
+ lt_prog_compiler_pic=
+ ;;
+ *)
+ lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC"
+ ;;
+esac
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5
+$as_echo_n "checking for $compiler option to produce PIC... " >&6; }
+if ${lt_cv_prog_compiler_pic+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_pic=$lt_prog_compiler_pic
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic" >&5
+$as_echo "$lt_cv_prog_compiler_pic" >&6; }
+lt_prog_compiler_pic=$lt_cv_prog_compiler_pic
+
+#
+# Check to make sure the PIC flag actually works.
+#
+if test -n "$lt_prog_compiler_pic"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5
+$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; }
+if ${lt_cv_prog_compiler_pic_works+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_pic_works=no
+ ac_outfile=conftest.$ac_objext
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+ lt_compiler_flag="$lt_prog_compiler_pic -DPIC"
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ # The option is referenced via a variable to avoid confusing sed.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>conftest.err)
+ ac_status=$?
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s "$ac_outfile"; then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings other than the usual output.
+ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_pic_works=yes
+ fi
+ fi
+ $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5
+$as_echo "$lt_cv_prog_compiler_pic_works" >&6; }
+
+if test x"$lt_cv_prog_compiler_pic_works" = xyes; then
+ case $lt_prog_compiler_pic in
+ "" | " "*) ;;
+ *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;;
+ esac
+else
+ lt_prog_compiler_pic=
+ lt_prog_compiler_can_build_shared=no
+fi
+
+fi
+
+
+
+
+
+
+
+
+
+
+
+#
+# Check to make sure the static flag actually works.
+#
+wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5
+$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; }
+if ${lt_cv_prog_compiler_static_works+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_static_works=no
+ save_LDFLAGS="$LDFLAGS"
+ LDFLAGS="$LDFLAGS $lt_tmp_static_flag"
+ echo "$lt_simple_link_test_code" > conftest.$ac_ext
+ if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+ # The linker can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ if test -s conftest.err; then
+ # Append any errors to the config.log.
+ cat conftest.err 1>&5
+ $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if diff conftest.exp conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_static_works=yes
+ fi
+ else
+ lt_cv_prog_compiler_static_works=yes
+ fi
+ fi
+ $RM -r conftest*
+ LDFLAGS="$save_LDFLAGS"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5
+$as_echo "$lt_cv_prog_compiler_static_works" >&6; }
+
+if test x"$lt_cv_prog_compiler_static_works" = xyes; then
+ :
+else
+ lt_prog_compiler_static=
+fi
+
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5
+$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; }
+if ${lt_cv_prog_compiler_c_o+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_c_o=no
+ $RM -r conftest 2>/dev/null
+ mkdir conftest
+ cd conftest
+ mkdir out
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+ lt_compiler_flag="-o out/conftest2.$ac_objext"
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>out/conftest.err)
+ ac_status=$?
+ cat out/conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s out/conftest2.$ac_objext
+ then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp
+ $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+ if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_c_o=yes
+ fi
+ fi
+ chmod u+w . 2>&5
+ $RM conftest*
+ # SGI C++ compiler will create directory out/ii_files/ for
+ # template instantiation
+ test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
+ $RM out/* && rmdir out
+ cd ..
+ $RM -r conftest
+ $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5
+$as_echo "$lt_cv_prog_compiler_c_o" >&6; }
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5
+$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; }
+if ${lt_cv_prog_compiler_c_o+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_c_o=no
+ $RM -r conftest 2>/dev/null
+ mkdir conftest
+ cd conftest
+ mkdir out
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+ lt_compiler_flag="-o out/conftest2.$ac_objext"
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>out/conftest.err)
+ ac_status=$?
+ cat out/conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s out/conftest2.$ac_objext
+ then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp
+ $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+ if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_c_o=yes
+ fi
+ fi
+ chmod u+w . 2>&5
+ $RM conftest*
+ # SGI C++ compiler will create directory out/ii_files/ for
+ # template instantiation
+ test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
+ $RM out/* && rmdir out
+ cd ..
+ $RM -r conftest
+ $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5
+$as_echo "$lt_cv_prog_compiler_c_o" >&6; }
+
+
+
+
+hard_links="nottested"
+if test "$lt_cv_prog_compiler_c_o" = no && test "$need_locks" != no; then
+ # do not overwrite the value of need_locks provided by the user
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5
+$as_echo_n "checking if we can lock with hard links... " >&6; }
+ hard_links=yes
+ $RM conftest*
+ ln conftest.a conftest.b 2>/dev/null && hard_links=no
+ touch conftest.a
+ ln conftest.a conftest.b 2>&5 || hard_links=no
+ ln conftest.a conftest.b 2>/dev/null && hard_links=no
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5
+$as_echo "$hard_links" >&6; }
+ if test "$hard_links" = no; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5
+$as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;}
+ need_locks=warn
+ fi
+else
+ need_locks=no
+fi
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5
+$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; }
+
+ runpath_var=
+ allow_undefined_flag=
+ always_export_symbols=no
+ archive_cmds=
+ archive_expsym_cmds=
+ compiler_needs_object=no
+ enable_shared_with_static_runtimes=no
+ export_dynamic_flag_spec=
+ export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+ hardcode_automatic=no
+ hardcode_direct=no
+ hardcode_direct_absolute=no
+ hardcode_libdir_flag_spec=
+ hardcode_libdir_separator=
+ hardcode_minus_L=no
+ hardcode_shlibpath_var=unsupported
+ inherit_rpath=no
+ link_all_deplibs=unknown
+ module_cmds=
+ module_expsym_cmds=
+ old_archive_from_new_cmds=
+ old_archive_from_expsyms_cmds=
+ thread_safe_flag_spec=
+ whole_archive_flag_spec=
+ # include_expsyms should be a list of space-separated symbols to be *always*
+ # included in the symbol list
+ include_expsyms=
+ # exclude_expsyms can be an extended regexp of symbols to exclude
+ # it will be wrapped by ` (' and `)$', so one must not match beginning or
+ # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc',
+ # as well as any symbol that contains `d'.
+ exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'
+ # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
+ # platforms (ab)use it in PIC code, but their linkers get confused if
+ # the symbol is explicitly referenced. Since portable code cannot
+ # rely on this symbol name, it's probably fine to never include it in
+ # preloaded symbol tables.
+ # Exclude shared library initialization/finalization symbols.
+ extract_expsyms_cmds=
+
+ case $host_os in
+ cygwin* | mingw* | pw32* | cegcc*)
+ # FIXME: the MSVC++ port hasn't been tested in a loooong time
+ # When not using gcc, we currently assume that we are using
+ # Microsoft Visual C++.
+ if test "$GCC" != yes; then
+ with_gnu_ld=no
+ fi
+ ;;
+ interix*)
+ # we just hope/assume this is gcc and not c89 (= MSVC++)
+ with_gnu_ld=yes
+ ;;
+ openbsd*)
+ with_gnu_ld=no
+ ;;
+ esac
+
+ ld_shlibs=yes
+
+ # On some targets, GNU ld is compatible enough with the native linker
+ # that we're better off using the native interface for both.
+ lt_use_gnu_ld_interface=no
+ if test "$with_gnu_ld" = yes; then
+ case $host_os in
+ aix*)
+ # The AIX port of GNU ld has always aspired to compatibility
+ # with the native linker. However, as the warning in the GNU ld
+ # block says, versions before 2.19.5* couldn't really create working
+ # shared libraries, regardless of the interface used.
+ case `$LD -v 2>&1` in
+ *\ \(GNU\ Binutils\)\ 2.19.5*) ;;
+ *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;;
+ *\ \(GNU\ Binutils\)\ [3-9]*) ;;
+ *)
+ lt_use_gnu_ld_interface=yes
+ ;;
+ esac
+ ;;
+ *)
+ lt_use_gnu_ld_interface=yes
+ ;;
+ esac
+ fi
+
+ if test "$lt_use_gnu_ld_interface" = yes; then
+ # If archive_cmds runs LD, not CC, wlarc should be empty
+ wlarc='${wl}'
+
+ # Set some defaults for GNU ld with shared library support. These
+ # are reset later if shared libraries are not supported. Putting them
+ # here allows them to be overridden if necessary.
+ runpath_var=LD_RUN_PATH
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ export_dynamic_flag_spec='${wl}--export-dynamic'
+ # ancient GNU ld didn't support --whole-archive et. al.
+ if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then
+ whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+ else
+ whole_archive_flag_spec=
+ fi
+ supports_anon_versioning=no
+ case `$LD -v 2>&1` in
+ *GNU\ gold*) supports_anon_versioning=yes ;;
+ *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11
+ *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
+ *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...
+ *\ 2.11.*) ;; # other 2.11 versions
+ *) supports_anon_versioning=yes ;;
+ esac
+
+ # See if GNU ld supports shared libraries.
+ case $host_os in
+ aix[3-9]*)
+ # On AIX/PPC, the GNU linker is very broken
+ if test "$host_cpu" != ia64; then
+ ld_shlibs=no
+ cat <<_LT_EOF 1>&2
+
+*** Warning: the GNU linker, at least up to release 2.19, is reported
+*** to be unable to reliably create shared libraries on AIX.
+*** Therefore, libtool is disabling shared libraries support. If you
+*** really care for shared libraries, you may want to install binutils
+*** 2.20 or above, or modify your PATH so that a non-GNU linker is found.
+*** You will then need to restart the configuration process.
+
+_LT_EOF
+ fi
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds=''
+ ;;
+ m68k)
+ archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ ;;
+ esac
+ ;;
+
+ beos*)
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ allow_undefined_flag=unsupported
+ # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+ # support --undefined. This deserves some investigation. FIXME
+ archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+
+ cygwin* | mingw* | pw32* | cegcc*)
+ # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless,
+ # as there is no search path for DLLs.
+ hardcode_libdir_flag_spec='-L$libdir'
+ export_dynamic_flag_spec='${wl}--export-all-symbols'
+ allow_undefined_flag=unsupported
+ always_export_symbols=no
+ enable_shared_with_static_runtimes=yes
+ export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols'
+ exclude_expsyms='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'
+
+ if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ # If the export-symbols file already is a .def file (1st line
+ # is EXPORTS), use it as is; otherwise, prepend...
+ archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+ cp $export_symbols $output_objdir/$soname.def;
+ else
+ echo EXPORTS > $output_objdir/$soname.def;
+ cat $export_symbols >> $output_objdir/$soname.def;
+ fi~
+ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+
+ haiku*)
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ link_all_deplibs=yes
+ ;;
+
+ interix[3-9]*)
+ hardcode_direct=no
+ hardcode_shlibpath_var=no
+ hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+ export_dynamic_flag_spec='${wl}-E'
+ # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+ # Instead, shared libraries are loaded at an image base (0x10000000 by
+ # default) and relocated if they conflict, which is a slow very memory
+ # consuming and fragmenting process. To avoid this, we pick a random,
+ # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+ # time. Moving up from 0x10000000 also allows more sbrk(2) space.
+ archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ archive_expsym_cmds='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ ;;
+
+ gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu)
+ tmp_diet=no
+ if test "$host_os" = linux-dietlibc; then
+ case $cc_basename in
+ diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn)
+ esac
+ fi
+ if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \
+ && test "$tmp_diet" = no
+ then
+ tmp_addflag=' $pic_flag'
+ tmp_sharedflag='-shared'
+ case $cc_basename,$host_cpu in
+ pgcc*) # Portland Group C compiler
+ whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+ tmp_addflag=' $pic_flag'
+ ;;
+ pgf77* | pgf90* | pgf95* | pgfortran*)
+ # Portland Group f77 and f90 compilers
+ whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+ tmp_addflag=' $pic_flag -Mnomain' ;;
+ ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64
+ tmp_addflag=' -i_dynamic' ;;
+ efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64
+ tmp_addflag=' -i_dynamic -nofor_main' ;;
+ ifc* | ifort*) # Intel Fortran compiler
+ tmp_addflag=' -nofor_main' ;;
+ lf95*) # Lahey Fortran 8.1
+ whole_archive_flag_spec=
+ tmp_sharedflag='--shared' ;;
+ xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below)
+ tmp_sharedflag='-qmkshrobj'
+ tmp_addflag= ;;
+ nvcc*) # Cuda Compiler Driver 2.2
+ whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+ compiler_needs_object=yes
+ ;;
+ esac
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ C*) # Sun C 5.9
+ whole_archive_flag_spec='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+ compiler_needs_object=yes
+ tmp_sharedflag='-G' ;;
+ *Sun\ F*) # Sun Fortran 8.3
+ tmp_sharedflag='-G' ;;
+ esac
+ archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+
+ if test "x$supports_anon_versioning" = xyes; then
+ archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~
+ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+ echo "local: *; };" >> $output_objdir/$libname.ver~
+ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
+ fi
+
+ case $cc_basename in
+ xlf* | bgf* | bgxlf* | mpixlf*)
+ # IBM XL Fortran 10.1 on PPC cannot create shared libs itself
+ whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive'
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib'
+ if test "x$supports_anon_versioning" = xyes; then
+ archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~
+ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+ echo "local: *; };" >> $output_objdir/$libname.ver~
+ $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
+ fi
+ ;;
+ esac
+ else
+ ld_shlibs=no
+ fi
+ ;;
+
+ netbsd*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
+ wlarc=
+ else
+ archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ fi
+ ;;
+
+ solaris*)
+ if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then
+ ld_shlibs=no
+ cat <<_LT_EOF 1>&2
+
+*** Warning: The releases 2.8.* of the GNU linker cannot reliably
+*** create shared libraries on Solaris systems. Therefore, libtool
+*** is disabling shared libraries support. We urge you to upgrade GNU
+*** binutils to release 2.9.1 or newer. Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+ elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+
+ sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
+ case `$LD -v 2>&1` in
+ *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*)
+ ld_shlibs=no
+ cat <<_LT_EOF 1>&2
+
+*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not
+*** reliably create shared libraries on SCO systems. Therefore, libtool
+*** is disabling shared libraries support. We urge you to upgrade GNU
+*** binutils to release 2.16.91.0.3 or newer. Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+ ;;
+ *)
+ # For security reasons, it is highly recommended that you always
+ # use absolute paths for naming shared libraries, and exclude the
+ # DT_RUNPATH tag from executables and libraries. But doing so
+ # requires that you compile everything twice, which is a pain.
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ esac
+ ;;
+
+ sunos4*)
+ archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ wlarc=
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ *)
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ esac
+
+ if test "$ld_shlibs" = no; then
+ runpath_var=
+ hardcode_libdir_flag_spec=
+ export_dynamic_flag_spec=
+ whole_archive_flag_spec=
+ fi
+ else
+ # PORTME fill in a description of your system's linker (not GNU ld)
+ case $host_os in
+ aix3*)
+ allow_undefined_flag=unsupported
+ always_export_symbols=yes
+ archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname'
+ # Note: this linker hardcodes the directories in LIBPATH if there
+ # are no directories specified by -L.
+ hardcode_minus_L=yes
+ if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then
+ # Neither direct hardcoding nor static linking is supported with a
+ # broken collect2.
+ hardcode_direct=unsupported
+ fi
+ ;;
+
+ aix[4-9]*)
+ if test "$host_cpu" = ia64; then
+ # On IA64, the linker does run time linking by default, so we don't
+ # have to do anything special.
+ aix_use_runtimelinking=no
+ exp_sym_flag='-Bexport'
+ no_entry_flag=""
+ else
+ # If we're using GNU nm, then we don't want the "-C" option.
+ # -C means demangle to AIX nm, but means don't demangle with GNU nm
+ # Also, AIX nm treats weak defined symbols like other global
+ # defined symbols, whereas GNU nm marks them as "W".
+ if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
+ export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+ else
+ export_symbols_cmds='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+ fi
+ aix_use_runtimelinking=no
+
+ # Test if we are trying to use run time linking or normal
+ # AIX style linking. If -brtl is somewhere in LDFLAGS, we
+ # need to do runtime linking.
+ case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*)
+ for ld_flag in $LDFLAGS; do
+ if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
+ aix_use_runtimelinking=yes
+ break
+ fi
+ done
+ ;;
+ esac
+
+ exp_sym_flag='-bexport'
+ no_entry_flag='-bnoentry'
+ fi
+
+ # When large executables or shared objects are built, AIX ld can
+ # have problems creating the table of contents. If linking a library
+ # or program results in "error TOC overflow" add -mminimal-toc to
+ # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not
+ # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+ archive_cmds=''
+ hardcode_direct=yes
+ hardcode_direct_absolute=yes
+ hardcode_libdir_separator=':'
+ link_all_deplibs=yes
+ file_list_spec='${wl}-f,'
+
+ if test "$GCC" = yes; then
+ case $host_os in aix4.[012]|aix4.[012].*)
+ # We only want to do this on AIX 4.2 and lower, the check
+ # below for broken collect2 doesn't work under 4.3+
+ collect2name=`${CC} -print-prog-name=collect2`
+ if test -f "$collect2name" &&
+ strings "$collect2name" | $GREP resolve_lib_name >/dev/null
+ then
+ # We have reworked collect2
+ :
+ else
+ # We have old collect2
+ hardcode_direct=unsupported
+ # It fails to find uninstalled libraries when the uninstalled
+ # path is not listed in the libpath. Setting hardcode_minus_L
+ # to unsupported forces relinking
+ hardcode_minus_L=yes
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_libdir_separator=
+ fi
+ ;;
+ esac
+ shared_flag='-shared'
+ if test "$aix_use_runtimelinking" = yes; then
+ shared_flag="$shared_flag "'${wl}-G'
+ fi
+ else
+ # not using gcc
+ if test "$host_cpu" = ia64; then
+ # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+ # chokes on -Wl,-G. The following line is correct:
+ shared_flag='-G'
+ else
+ if test "$aix_use_runtimelinking" = yes; then
+ shared_flag='${wl}-G'
+ else
+ shared_flag='${wl}-bM:SRE'
+ fi
+ fi
+ fi
+
+ export_dynamic_flag_spec='${wl}-bexpall'
+ # It seems that -bexpall does not export symbols beginning with
+ # underscore (_), so it is better to generate a list of symbols to export.
+ always_export_symbols=yes
+ if test "$aix_use_runtimelinking" = yes; then
+ # Warning - without using the other runtime loading flags (-brtl),
+ # -berok will link without error, but may produce a broken library.
+ allow_undefined_flag='-berok'
+ # Determine the default libpath from the value encoded in an
+ # empty executable.
+ if test "${lt_cv_aix_libpath+set}" = set; then
+ aix_libpath=$lt_cv_aix_libpath
+else
+ if ${lt_cv_aix_libpath_+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+
+ lt_aix_libpath_sed='
+ /Import File Strings/,/^$/ {
+ /^0/ {
+ s/^0 *\([^ ]*\) *$/\1/
+ p
+ }
+ }'
+ lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+ # Check for a 64-bit object if we didn't find anything.
+ if test -z "$lt_cv_aix_libpath_"; then
+ lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+ fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ if test -z "$lt_cv_aix_libpath_"; then
+ lt_cv_aix_libpath_="/usr/lib:/lib"
+ fi
+
+fi
+
+ aix_libpath=$lt_cv_aix_libpath_
+fi
+
+ hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
+ archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+ else
+ if test "$host_cpu" = ia64; then
+ hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib'
+ allow_undefined_flag="-z nodefs"
+ archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
+ else
+ # Determine the default libpath from the value encoded in an
+ # empty executable.
+ if test "${lt_cv_aix_libpath+set}" = set; then
+ aix_libpath=$lt_cv_aix_libpath
+else
+ if ${lt_cv_aix_libpath_+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+
+ lt_aix_libpath_sed='
+ /Import File Strings/,/^$/ {
+ /^0/ {
+ s/^0 *\([^ ]*\) *$/\1/
+ p
+ }
+ }'
+ lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+ # Check for a 64-bit object if we didn't find anything.
+ if test -z "$lt_cv_aix_libpath_"; then
+ lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+ fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ if test -z "$lt_cv_aix_libpath_"; then
+ lt_cv_aix_libpath_="/usr/lib:/lib"
+ fi
+
+fi
+
+ aix_libpath=$lt_cv_aix_libpath_
+fi
+
+ hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
+ # Warning - without using the other run time loading flags,
+ # -berok will link without error, but may produce a broken library.
+ no_undefined_flag=' ${wl}-bernotok'
+ allow_undefined_flag=' ${wl}-berok'
+ if test "$with_gnu_ld" = yes; then
+ # We only use this code for GNU lds that support --whole-archive.
+ whole_archive_flag_spec='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
+ else
+ # Exported symbols can be pulled into shared objects from archives
+ whole_archive_flag_spec='$convenience'
+ fi
+ archive_cmds_need_lc=yes
+ # This is similar to how AIX traditionally builds its shared libraries.
+ archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+ fi
+ fi
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds=''
+ ;;
+ m68k)
+ archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ ;;
+ esac
+ ;;
+
+ bsdi[45]*)
+ export_dynamic_flag_spec=-rdynamic
+ ;;
+
+ cygwin* | mingw* | pw32* | cegcc*)
+ # When not using gcc, we currently assume that we are using
+ # Microsoft Visual C++.
+ # hardcode_libdir_flag_spec is actually meaningless, as there is
+ # no search path for DLLs.
+ case $cc_basename in
+ cl*)
+ # Native MSVC
+ hardcode_libdir_flag_spec=' '
+ allow_undefined_flag=unsupported
+ always_export_symbols=yes
+ file_list_spec='@'
+ # Tell ltmain to make .lib files, not .a files.
+ libext=lib
+ # Tell ltmain to make .dll files, not .so files.
+ shrext_cmds=".dll"
+ # FIXME: Setting linknames here is a bad hack.
+ archive_cmds='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames='
+ archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+ sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp;
+ else
+ sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp;
+ fi~
+ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
+ linknames='
+ # The linker will not automatically build a static lib if we build a DLL.
+ # _LT_TAGVAR(old_archive_from_new_cmds, )='true'
+ enable_shared_with_static_runtimes=yes
+ exclude_expsyms='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*'
+ export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1,DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols'
+ # Don't use ranlib
+ old_postinstall_cmds='chmod 644 $oldlib'
+ postlink_cmds='lt_outputfile="@OUTPUT@"~
+ lt_tool_outputfile="@TOOL_OUTPUT@"~
+ case $lt_outputfile in
+ *.exe|*.EXE) ;;
+ *)
+ lt_outputfile="$lt_outputfile.exe"
+ lt_tool_outputfile="$lt_tool_outputfile.exe"
+ ;;
+ esac~
+ if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then
+ $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
+ $RM "$lt_outputfile.manifest";
+ fi'
+ ;;
+ *)
+ # Assume MSVC wrapper
+ hardcode_libdir_flag_spec=' '
+ allow_undefined_flag=unsupported
+ # Tell ltmain to make .lib files, not .a files.
+ libext=lib
+ # Tell ltmain to make .dll files, not .so files.
+ shrext_cmds=".dll"
+ # FIXME: Setting linknames here is a bad hack.
+ archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames='
+ # The linker will automatically build a .lib file if we build a DLL.
+ old_archive_from_new_cmds='true'
+ # FIXME: Should let the user specify the lib program.
+ old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs'
+ enable_shared_with_static_runtimes=yes
+ ;;
+ esac
+ ;;
+
+ darwin* | rhapsody*)
+
+
+ archive_cmds_need_lc=no
+ hardcode_direct=no
+ hardcode_automatic=yes
+ hardcode_shlibpath_var=unsupported
+ if test "$lt_cv_ld_force_load" = "yes"; then
+ whole_archive_flag_spec='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`'
+
+ else
+ whole_archive_flag_spec=''
+ fi
+ link_all_deplibs=yes
+ allow_undefined_flag="$_lt_dar_allow_undefined"
+ case $cc_basename in
+ ifort*) _lt_dar_can_shared=yes ;;
+ *) _lt_dar_can_shared=$GCC ;;
+ esac
+ if test "$_lt_dar_can_shared" = "yes"; then
+ output_verbose_link_cmd=func_echo_all
+ archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}"
+ module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}"
+ archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}"
+ module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}"
+
+ else
+ ld_shlibs=no
+ fi
+
+ ;;
+
+ dgux*)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_shlibpath_var=no
+ ;;
+
+ # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
+ # support. Future versions do this automatically, but an explicit c++rt0.o
+ # does not break anything, and helps significantly (at the cost of a little
+ # extra space).
+ freebsd2.2*)
+ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o'
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ # Unfortunately, older versions of FreeBSD 2 do not have this feature.
+ freebsd2.*)
+ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_direct=yes
+ hardcode_minus_L=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
+ freebsd* | dragonfly*)
+ archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ hpux9*)
+ if test "$GCC" = yes; then
+ archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+ else
+ archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+ fi
+ hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+ hardcode_libdir_separator=:
+ hardcode_direct=yes
+
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ hardcode_minus_L=yes
+ export_dynamic_flag_spec='${wl}-E'
+ ;;
+
+ hpux10*)
+ if test "$GCC" = yes && test "$with_gnu_ld" = no; then
+ archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+ fi
+ if test "$with_gnu_ld" = no; then
+ hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+ hardcode_libdir_separator=:
+ hardcode_direct=yes
+ hardcode_direct_absolute=yes
+ export_dynamic_flag_spec='${wl}-E'
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ hardcode_minus_L=yes
+ fi
+ ;;
+
+ hpux11*)
+ if test "$GCC" = yes && test "$with_gnu_ld" = no; then
+ case $host_cpu in
+ hppa*64*)
+ archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ ia64*)
+ archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ *)
+ archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ esac
+ else
+ case $host_cpu in
+ hppa*64*)
+ archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ ia64*)
+ archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ *)
+
+ # Older versions of the 11.00 compiler do not understand -b yet
+ # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5
+$as_echo_n "checking if $CC understands -b... " >&6; }
+if ${lt_cv_prog_compiler__b+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler__b=no
+ save_LDFLAGS="$LDFLAGS"
+ LDFLAGS="$LDFLAGS -b"
+ echo "$lt_simple_link_test_code" > conftest.$ac_ext
+ if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+ # The linker can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ if test -s conftest.err; then
+ # Append any errors to the config.log.
+ cat conftest.err 1>&5
+ $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if diff conftest.exp conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler__b=yes
+ fi
+ else
+ lt_cv_prog_compiler__b=yes
+ fi
+ fi
+ $RM -r conftest*
+ LDFLAGS="$save_LDFLAGS"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5
+$as_echo "$lt_cv_prog_compiler__b" >&6; }
+
+if test x"$lt_cv_prog_compiler__b" = xyes; then
+ archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+else
+ archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+fi
+
+ ;;
+ esac
+ fi
+ if test "$with_gnu_ld" = no; then
+ hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+ hardcode_libdir_separator=:
+
+ case $host_cpu in
+ hppa*64*|ia64*)
+ hardcode_direct=no
+ hardcode_shlibpath_var=no
+ ;;
+ *)
+ hardcode_direct=yes
+ hardcode_direct_absolute=yes
+ export_dynamic_flag_spec='${wl}-E'
+
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ hardcode_minus_L=yes
+ ;;
+ esac
+ fi
+ ;;
+
+ irix5* | irix6* | nonstopux*)
+ if test "$GCC" = yes; then
+ archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ # Try to use the -exported_symbol ld option, if it does not
+ # work, assume that -exports_file does not work either and
+ # implicitly export all symbols.
+ # This should be the same for all languages, so no per-tag cache variable.
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $host_os linker accepts -exported_symbol" >&5
+$as_echo_n "checking whether the $host_os linker accepts -exported_symbol... " >&6; }
+if ${lt_cv_irix_exported_symbol+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ save_LDFLAGS="$LDFLAGS"
+ LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+int foo (void) { return 0; }
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ lt_cv_irix_exported_symbol=yes
+else
+ lt_cv_irix_exported_symbol=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ LDFLAGS="$save_LDFLAGS"
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol" >&5
+$as_echo "$lt_cv_irix_exported_symbol" >&6; }
+ if test "$lt_cv_irix_exported_symbol" = yes; then
+ archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib'
+ fi
+ else
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib'
+ fi
+ archive_cmds_need_lc='no'
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ hardcode_libdir_separator=:
+ inherit_rpath=yes
+ link_all_deplibs=yes
+ ;;
+
+ netbsd*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out
+ else
+ archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF
+ fi
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ newsos6)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_direct=yes
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ hardcode_libdir_separator=:
+ hardcode_shlibpath_var=no
+ ;;
+
+ *nto* | *qnx*)
+ ;;
+
+ openbsd*)
+ if test -f /usr/libexec/ld.so; then
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ hardcode_direct_absolute=yes
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols'
+ hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+ export_dynamic_flag_spec='${wl}-E'
+ else
+ case $host_os in
+ openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*)
+ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_libdir_flag_spec='-R$libdir'
+ ;;
+ *)
+ archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+ ;;
+ esac
+ fi
+ else
+ ld_shlibs=no
+ fi
+ ;;
+
+ os2*)
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ allow_undefined_flag=unsupported
+ archive_cmds='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def'
+ old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def'
+ ;;
+
+ osf3*)
+ if test "$GCC" = yes; then
+ allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
+ archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ else
+ allow_undefined_flag=' -expect_unresolved \*'
+ archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+ fi
+ archive_cmds_need_lc='no'
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ hardcode_libdir_separator=:
+ ;;
+
+ osf4* | osf5*) # as osf3* with the addition of -msym flag
+ if test "$GCC" = yes; then
+ allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
+ archive_cmds='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ else
+ allow_undefined_flag=' -expect_unresolved \*'
+ archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+ archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~
+ $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp'
+
+ # Both c and cxx compiler support -rpath directly
+ hardcode_libdir_flag_spec='-rpath $libdir'
+ fi
+ archive_cmds_need_lc='no'
+ hardcode_libdir_separator=:
+ ;;
+
+ solaris*)
+ no_undefined_flag=' -z defs'
+ if test "$GCC" = yes; then
+ wlarc='${wl}'
+ archive_cmds='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+ else
+ case `$CC -V 2>&1` in
+ *"Compilers 5.0"*)
+ wlarc=''
+ archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp'
+ ;;
+ *)
+ wlarc='${wl}'
+ archive_cmds='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+ ;;
+ esac
+ fi
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_shlibpath_var=no
+ case $host_os in
+ solaris2.[0-5] | solaris2.[0-5].*) ;;
+ *)
+ # The compiler driver will combine and reorder linker options,
+ # but understands `-z linker_flag'. GCC discards it without `$wl',
+ # but is careful enough not to reorder.
+ # Supported since Solaris 2.6 (maybe 2.5.1?)
+ if test "$GCC" = yes; then
+ whole_archive_flag_spec='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
+ else
+ whole_archive_flag_spec='-z allextract$convenience -z defaultextract'
+ fi
+ ;;
+ esac
+ link_all_deplibs=yes
+ ;;
+
+ sunos4*)
+ if test "x$host_vendor" = xsequent; then
+ # Use $CC to link under sequent, because it throws in some extra .o
+ # files that make .init and .fini sections work.
+ archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'
+ fi
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_direct=yes
+ hardcode_minus_L=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ sysv4)
+ case $host_vendor in
+ sni)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_direct=yes # is this really true???
+ ;;
+ siemens)
+ ## LD is ld it makes a PLAMLIB
+ ## CC just makes a GrossModule.
+ archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags'
+ reload_cmds='$CC -r -o $output$reload_objs'
+ hardcode_direct=no
+ ;;
+ motorola)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_direct=no #Motorola manual says yes, but my tests say they lie
+ ;;
+ esac
+ runpath_var='LD_RUN_PATH'
+ hardcode_shlibpath_var=no
+ ;;
+
+ sysv4.3*)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_shlibpath_var=no
+ export_dynamic_flag_spec='-Bexport'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_shlibpath_var=no
+ runpath_var=LD_RUN_PATH
+ hardcode_runpath_var=yes
+ ld_shlibs=yes
+ fi
+ ;;
+
+ sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*)
+ no_undefined_flag='${wl}-z,text'
+ archive_cmds_need_lc=no
+ hardcode_shlibpath_var=no
+ runpath_var='LD_RUN_PATH'
+
+ if test "$GCC" = yes; then
+ archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ fi
+ ;;
+
+ sysv5* | sco3.2v5* | sco5v6*)
+ # Note: We can NOT use -z defs as we might desire, because we do not
+ # link with -lc, and that would cause any symbols used from libc to
+ # always be unresolved, which means just about no library would
+ # ever link correctly. If we're not using GNU ld we use -z text
+ # though, which does catch some bad symbols but isn't as heavy-handed
+ # as -z defs.
+ no_undefined_flag='${wl}-z,text'
+ allow_undefined_flag='${wl}-z,nodefs'
+ archive_cmds_need_lc=no
+ hardcode_shlibpath_var=no
+ hardcode_libdir_flag_spec='${wl}-R,$libdir'
+ hardcode_libdir_separator=':'
+ link_all_deplibs=yes
+ export_dynamic_flag_spec='${wl}-Bexport'
+ runpath_var='LD_RUN_PATH'
+
+ if test "$GCC" = yes; then
+ archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ fi
+ ;;
+
+ uts4*)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_shlibpath_var=no
+ ;;
+
+ *)
+ ld_shlibs=no
+ ;;
+ esac
+
+ if test x$host_vendor = xsni; then
+ case $host in
+ sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+ export_dynamic_flag_spec='${wl}-Blargedynsym'
+ ;;
+ esac
+ fi
+ fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5
+$as_echo "$ld_shlibs" >&6; }
+test "$ld_shlibs" = no && can_build_shared=no
+
+with_gnu_ld=$with_gnu_ld
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+#
+# Do we need to explicitly link libc?
+#
+case "x$archive_cmds_need_lc" in
+x|xyes)
+ # Assume -lc should be added
+ archive_cmds_need_lc=yes
+
+ if test "$enable_shared" = yes && test "$GCC" = yes; then
+ case $archive_cmds in
+ *'~'*)
+ # FIXME: we may have to deal with multi-command sequences.
+ ;;
+ '$CC '*)
+ # Test whether the compiler implicitly links with -lc since on some
+ # systems, -lgcc has to come before -lc. If gcc already passes -lc
+ # to ld, don't add -lc before -lgcc.
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5
+$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; }
+if ${lt_cv_archive_cmds_need_lc+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ $RM conftest*
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } 2>conftest.err; then
+ soname=conftest
+ lib=conftest
+ libobjs=conftest.$ac_objext
+ deplibs=
+ wl=$lt_prog_compiler_wl
+ pic_flag=$lt_prog_compiler_pic
+ compiler_flags=-v
+ linker_flags=-v
+ verstring=
+ output_objdir=.
+ libname=conftest
+ lt_save_allow_undefined_flag=$allow_undefined_flag
+ allow_undefined_flag=
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5
+ (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ then
+ lt_cv_archive_cmds_need_lc=no
+ else
+ lt_cv_archive_cmds_need_lc=yes
+ fi
+ allow_undefined_flag=$lt_save_allow_undefined_flag
+ else
+ cat conftest.err 1>&5
+ fi
+ $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5
+$as_echo "$lt_cv_archive_cmds_need_lc" >&6; }
+ archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc
+ ;;
+ esac
+ fi
+ ;;
+esac
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5
+$as_echo_n "checking dynamic linker characteristics... " >&6; }
+
+if test "$GCC" = yes; then
+ case $host_os in
+ darwin*) lt_awk_arg="/^libraries:/,/LR/" ;;
+ *) lt_awk_arg="/^libraries:/" ;;
+ esac
+ case $host_os in
+ mingw* | cegcc*) lt_sed_strip_eq="s,=\([A-Za-z]:\),\1,g" ;;
+ *) lt_sed_strip_eq="s,=/,/,g" ;;
+ esac
+ lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq`
+ case $lt_search_path_spec in
+ *\;*)
+ # if the path contains ";" then we assume it to be the separator
+ # otherwise default to the standard path separator (i.e. ":") - it is
+ # assumed that no part of a normal pathname contains ";" but that should
+ # okay in the real world where ";" in dirpaths is itself problematic.
+ lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'`
+ ;;
+ *)
+ lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"`
+ ;;
+ esac
+ # Ok, now we have the path, separated by spaces, we can step through it
+ # and add multilib dir if necessary.
+ lt_tmp_lt_search_path_spec=
+ lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null`
+ for lt_sys_path in $lt_search_path_spec; do
+ if test -d "$lt_sys_path/$lt_multi_os_dir"; then
+ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir"
+ else
+ test -d "$lt_sys_path" && \
+ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path"
+ fi
+ done
+ lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk '
+BEGIN {RS=" "; FS="/|\n";} {
+ lt_foo="";
+ lt_count=0;
+ for (lt_i = NF; lt_i > 0; lt_i--) {
+ if ($lt_i != "" && $lt_i != ".") {
+ if ($lt_i == "..") {
+ lt_count++;
+ } else {
+ if (lt_count == 0) {
+ lt_foo="/" $lt_i lt_foo;
+ } else {
+ lt_count--;
+ }
+ }
+ }
+ }
+ if (lt_foo != "") { lt_freq[lt_foo]++; }
+ if (lt_freq[lt_foo] == 1) { print lt_foo; }
+}'`
+ # AWK program above erroneously prepends '/' to C:/dos/paths
+ # for these hosts.
+ case $host_os in
+ mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\
+ $SED 's,/\([A-Za-z]:\),\1,g'` ;;
+ esac
+ sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP`
+else
+ sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+fi
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+shrext_cmds=".so"
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+shlibpath_overrides_runpath=unknown
+version_type=none
+dynamic_linker="$host_os ld.so"
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+need_lib_prefix=unknown
+hardcode_into_libs=no
+
+# when you set need_version to no, make sure it does not cause -set_version
+# flags to be left without arguments
+need_version=unknown
+
+case $host_os in
+aix3*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'
+ shlibpath_var=LIBPATH
+
+ # AIX 3 has no versioning support, so we append a major version to the name.
+ soname_spec='${libname}${release}${shared_ext}$major'
+ ;;
+
+aix[4-9]*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ hardcode_into_libs=yes
+ if test "$host_cpu" = ia64; then
+ # AIX 5 supports IA64
+ library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}'
+ shlibpath_var=LD_LIBRARY_PATH
+ else
+ # With GCC up to 2.95.x, collect2 would create an import file
+ # for dependence libraries. The import file would start with
+ # the line `#! .'. This would cause the generated library to
+ # depend on `.', always an invalid library. This was fixed in
+ # development snapshots of GCC prior to 3.0.
+ case $host_os in
+ aix4 | aix4.[01] | aix4.[01].*)
+ if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
+ echo ' yes '
+ echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then
+ :
+ else
+ can_build_shared=no
+ fi
+ ;;
+ esac
+ # AIX (on Power*) has no versioning support, so currently we can not hardcode correct
+ # soname into executable. Probably we can add versioning support to
+ # collect2, so additional links can be useful in future.
+ if test "$aix_use_runtimelinking" = yes; then
+ # If using run time linking (on AIX 4.2 or later) use lib<name>.so
+ # instead of lib<name>.a to let people know that these are not
+ # typical AIX shared libraries.
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ else
+ # We preserve .a as extension for shared libraries through AIX4.2
+ # and later when we are not doing run time linking.
+ library_names_spec='${libname}${release}.a $libname.a'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ fi
+ shlibpath_var=LIBPATH
+ fi
+ ;;
+
+amigaos*)
+ case $host_cpu in
+ powerpc)
+ # Since July 2007 AmigaOS4 officially supports .so libraries.
+ # When compiling the executable, add -use-dynld -Lsobjs: to the compileline.
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ ;;
+ m68k)
+ library_names_spec='$libname.ixlibrary $libname.a'
+ # Create ${libname}_ixlibrary.a entries in /sys/libs.
+ finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
+ ;;
+ esac
+ ;;
+
+beos*)
+ library_names_spec='${libname}${shared_ext}'
+ dynamic_linker="$host_os ld.so"
+ shlibpath_var=LIBRARY_PATH
+ ;;
+
+bsdi[45]*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
+ sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
+ # the default ld.so.conf also contains /usr/contrib/lib and
+ # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
+ # libtool to hard-code these into programs
+ ;;
+
+cygwin* | mingw* | pw32* | cegcc*)
+ version_type=windows
+ shrext_cmds=".dll"
+ need_version=no
+ need_lib_prefix=no
+
+ case $GCC,$cc_basename in
+ yes,*)
+ # gcc
+ library_names_spec='$libname.dll.a'
+ # DLL is installed to $(libdir)/../bin by postinstall_cmds
+ postinstall_cmds='base_file=`basename \${file}`~
+ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
+ dldir=$destdir/`dirname \$dlpath`~
+ test -d \$dldir || mkdir -p \$dldir~
+ $install_prog $dir/$dlname \$dldir/$dlname~
+ chmod a+x \$dldir/$dlname~
+ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then
+ eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;
+ fi'
+ postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+ dlpath=$dir/\$dldll~
+ $RM \$dlpath'
+ shlibpath_overrides_runpath=yes
+
+ case $host_os in
+ cygwin*)
+ # Cygwin DLLs use 'cyg' prefix rather than 'lib'
+ soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+
+ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"
+ ;;
+ mingw* | cegcc*)
+ # MinGW DLLs use traditional 'lib' prefix
+ soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+ ;;
+ pw32*)
+ # pw32 DLLs use 'pw' prefix rather than 'lib'
+ library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+ ;;
+ esac
+ dynamic_linker='Win32 ld.exe'
+ ;;
+
+ *,cl*)
+ # Native MSVC
+ libname_spec='$name'
+ soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+ library_names_spec='${libname}.dll.lib'
+
+ case $build_os in
+ mingw*)
+ sys_lib_search_path_spec=
+ lt_save_ifs=$IFS
+ IFS=';'
+ for lt_path in $LIB
+ do
+ IFS=$lt_save_ifs
+ # Let DOS variable expansion print the short 8.3 style file name.
+ lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"`
+ sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path"
+ done
+ IFS=$lt_save_ifs
+ # Convert to MSYS style.
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'`
+ ;;
+ cygwin*)
+ # Convert to unix form, then to dos form, then back to unix form
+ # but this time dos style (no spaces!) so that the unix form looks
+ # like /cygdrive/c/PROGRA~1:/cygdr...
+ sys_lib_search_path_spec=`cygpath --path --unix "$LIB"`
+ sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null`
+ sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+ ;;
+ *)
+ sys_lib_search_path_spec="$LIB"
+ if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then
+ # It is most probably a Windows format PATH.
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+ else
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+ fi
+ # FIXME: find the short name or the path components, as spaces are
+ # common. (e.g. "Program Files" -> "PROGRA~1")
+ ;;
+ esac
+
+ # DLL is installed to $(libdir)/../bin by postinstall_cmds
+ postinstall_cmds='base_file=`basename \${file}`~
+ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
+ dldir=$destdir/`dirname \$dlpath`~
+ test -d \$dldir || mkdir -p \$dldir~
+ $install_prog $dir/$dlname \$dldir/$dlname'
+ postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+ dlpath=$dir/\$dldll~
+ $RM \$dlpath'
+ shlibpath_overrides_runpath=yes
+ dynamic_linker='Win32 link.exe'
+ ;;
+
+ *)
+ # Assume MSVC wrapper
+ library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib'
+ dynamic_linker='Win32 ld.exe'
+ ;;
+ esac
+ # FIXME: first we should search . and the directory the executable is in
+ shlibpath_var=PATH
+ ;;
+
+darwin* | rhapsody*)
+ dynamic_linker="$host_os dyld"
+ version_type=darwin
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext'
+ soname_spec='${libname}${release}${major}$shared_ext'
+ shlibpath_overrides_runpath=yes
+ shlibpath_var=DYLD_LIBRARY_PATH
+ shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
+
+ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"
+ sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
+ ;;
+
+dgux*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+freebsd* | dragonfly*)
+ # DragonFly does not have aout. When/if they implement a new
+ # versioning mechanism, adjust this.
+ if test -x /usr/bin/objformat; then
+ objformat=`/usr/bin/objformat`
+ else
+ case $host_os in
+ freebsd[23].*) objformat=aout ;;
+ *) objformat=elf ;;
+ esac
+ fi
+ version_type=freebsd-$objformat
+ case $version_type in
+ freebsd-elf*)
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+ need_version=no
+ need_lib_prefix=no
+ ;;
+ freebsd-*)
+ library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix'
+ need_version=yes
+ ;;
+ esac
+ shlibpath_var=LD_LIBRARY_PATH
+ case $host_os in
+ freebsd2.*)
+ shlibpath_overrides_runpath=yes
+ ;;
+ freebsd3.[01]* | freebsdelf3.[01]*)
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+ freebsd3.[2-9]* | freebsdelf3.[2-9]* | \
+ freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1)
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+ *) # from 4.6 on, and DragonFly
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+ esac
+ ;;
+
+gnu*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+
+haiku*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ dynamic_linker="$host_os runtime_loader"
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib'
+ hardcode_into_libs=yes
+ ;;
+
+hpux9* | hpux10* | hpux11*)
+ # Give a soname corresponding to the major version so that dld.sl refuses to
+ # link against other versions.
+ version_type=sunos
+ need_lib_prefix=no
+ need_version=no
+ case $host_cpu in
+ ia64*)
+ shrext_cmds='.so'
+ hardcode_into_libs=yes
+ dynamic_linker="$host_os dld.so"
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ if test "X$HPUX_IA64_MODE" = X32; then
+ sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
+ else
+ sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
+ fi
+ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+ ;;
+ hppa*64*)
+ shrext_cmds='.sl'
+ hardcode_into_libs=yes
+ dynamic_linker="$host_os dld.sl"
+ shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
+ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
+ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+ ;;
+ *)
+ shrext_cmds='.sl'
+ dynamic_linker="$host_os dld.sl"
+ shlibpath_var=SHLIB_PATH
+ shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ ;;
+ esac
+ # HP-UX runs *really* slowly unless shared libraries are mode 555, ...
+ postinstall_cmds='chmod 555 $lib'
+ # or fails outright, so override atomically:
+ install_override_mode=555
+ ;;
+
+interix[3-9]*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+
+irix5* | irix6* | nonstopux*)
+ case $host_os in
+ nonstopux*) version_type=nonstopux ;;
+ *)
+ if test "$lt_cv_prog_gnu_ld" = yes; then
+ version_type=linux # correct to gnu/linux during the next big refactor
+ else
+ version_type=irix
+ fi ;;
+ esac
+ need_lib_prefix=no
+ need_version=no
+ soname_spec='${libname}${release}${shared_ext}$major'
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}'
+ case $host_os in
+ irix5* | nonstopux*)
+ libsuff= shlibsuff=
+ ;;
+ *)
+ case $LD in # libtool.m4 will add one of these switches to LD
+ *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ")
+ libsuff= shlibsuff= libmagic=32-bit;;
+ *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")
+ libsuff=32 shlibsuff=N32 libmagic=N32;;
+ *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ")
+ libsuff=64 shlibsuff=64 libmagic=64-bit;;
+ *) libsuff= shlibsuff= libmagic=never-match;;
+ esac
+ ;;
+ esac
+ shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
+ shlibpath_overrides_runpath=no
+ sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
+ sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
+ hardcode_into_libs=yes
+ ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux*oldld* | linux*aout* | linux*coff*)
+ dynamic_linker=no
+ ;;
+
+# This must be glibc/ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+
+ # Some binutils ld are patched to set DT_RUNPATH
+ if ${lt_cv_shlibpath_overrides_runpath+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_shlibpath_overrides_runpath=no
+ save_LDFLAGS=$LDFLAGS
+ save_libdir=$libdir
+ eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \
+ LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\""
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then :
+ lt_cv_shlibpath_overrides_runpath=yes
+fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ LDFLAGS=$save_LDFLAGS
+ libdir=$save_libdir
+
+fi
+
+ shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath
+
+ # This implies no fast_install, which is unacceptable.
+ # Some rework will be needed to allow for fast_install
+ # before this can be enabled.
+ hardcode_into_libs=yes
+
+ # Add ABI-specific directories to the system library path.
+ sys_lib_dlsearch_path_spec="/lib64 /usr/lib64 /lib /usr/lib"
+
+ # Append ld.so.conf contents to the search path
+ if test -f /etc/ld.so.conf; then
+ lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '`
+ sys_lib_dlsearch_path_spec="$sys_lib_dlsearch_path_spec $lt_ld_extra"
+
+ fi
+
+ # We used to test for /lib/ld.so.1 and disable shared libraries on
+ # powerpc, because MkLinux only supported shared libraries with the
+ # GNU dynamic linker. Since this was broken with cross compilers,
+ # most powerpc-linux boxes support dynamic linking these days and
+ # people can always --disable-shared, the test was removed, and we
+ # assume the GNU/Linux dynamic linker is in use.
+ dynamic_linker='GNU/Linux ld.so'
+ ;;
+
+netbsd*)
+ version_type=sunos
+ need_lib_prefix=no
+ need_version=no
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+ dynamic_linker='NetBSD (a.out) ld.so'
+ else
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ dynamic_linker='NetBSD ld.elf_so'
+ fi
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+
+newsos6)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ ;;
+
+*nto* | *qnx*)
+ version_type=qnx
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ dynamic_linker='ldqnx.so'
+ ;;
+
+openbsd*)
+ version_type=sunos
+ sys_lib_dlsearch_path_spec="/usr/lib"
+ need_lib_prefix=no
+ # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs.
+ case $host_os in
+ openbsd3.3 | openbsd3.3.*) need_version=yes ;;
+ *) need_version=no ;;
+ esac
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ case $host_os in
+ openbsd2.[89] | openbsd2.[89].*)
+ shlibpath_overrides_runpath=no
+ ;;
+ *)
+ shlibpath_overrides_runpath=yes
+ ;;
+ esac
+ else
+ shlibpath_overrides_runpath=yes
+ fi
+ ;;
+
+os2*)
+ libname_spec='$name'
+ shrext_cmds=".dll"
+ need_lib_prefix=no
+ library_names_spec='$libname${shared_ext} $libname.a'
+ dynamic_linker='OS/2 ld.exe'
+ shlibpath_var=LIBPATH
+ ;;
+
+osf3* | osf4* | osf5*)
+ version_type=osf
+ need_lib_prefix=no
+ need_version=no
+ soname_spec='${libname}${release}${shared_ext}$major'
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ shlibpath_var=LD_LIBRARY_PATH
+ sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
+ sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
+ ;;
+
+rdos*)
+ dynamic_linker=no
+ ;;
+
+solaris*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ # ldd complains unless libraries are executable
+ postinstall_cmds='chmod +x $lib'
+ ;;
+
+sunos4*)
+ version_type=sunos
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+ finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ if test "$with_gnu_ld" = yes; then
+ need_lib_prefix=no
+ fi
+ need_version=yes
+ ;;
+
+sysv4 | sysv4.3*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ case $host_vendor in
+ sni)
+ shlibpath_overrides_runpath=no
+ need_lib_prefix=no
+ runpath_var=LD_RUN_PATH
+ ;;
+ siemens)
+ need_lib_prefix=no
+ ;;
+ motorola)
+ need_lib_prefix=no
+ need_version=no
+ shlibpath_overrides_runpath=no
+ sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
+ ;;
+ esac
+ ;;
+
+sysv4*MP*)
+ if test -d /usr/nec ;then
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'
+ soname_spec='$libname${shared_ext}.$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ fi
+ ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+ version_type=freebsd-elf
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ if test "$with_gnu_ld" = yes; then
+ sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
+ else
+ sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
+ case $host_os in
+ sco3.2v5*)
+ sys_lib_search_path_spec="$sys_lib_search_path_spec /lib"
+ ;;
+ esac
+ fi
+ sys_lib_dlsearch_path_spec='/usr/lib'
+ ;;
+
+tpf*)
+ # TPF is a cross-target only. Preferred cross-host = GNU/Linux.
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+
+uts4*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+*)
+ dynamic_linker=no
+ ;;
+esac
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5
+$as_echo "$dynamic_linker" >&6; }
+test "$dynamic_linker" = no && can_build_shared=no
+
+variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
+if test "$GCC" = yes; then
+ variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
+fi
+
+if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then
+ sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec"
+fi
+if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then
+ sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec"
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5
+$as_echo_n "checking how to hardcode library paths into programs... " >&6; }
+hardcode_action=
+if test -n "$hardcode_libdir_flag_spec" ||
+ test -n "$runpath_var" ||
+ test "X$hardcode_automatic" = "Xyes" ; then
+
+ # We can hardcode non-existent directories.
+ if test "$hardcode_direct" != no &&
+ # If the only mechanism to avoid hardcoding is shlibpath_var, we
+ # have to relink, otherwise we might link with an installed library
+ # when we should be linking with a yet-to-be-installed one
+ ## test "$_LT_TAGVAR(hardcode_shlibpath_var, )" != no &&
+ test "$hardcode_minus_L" != no; then
+ # Linking always hardcodes the temporary library directory.
+ hardcode_action=relink
+ else
+ # We can link without hardcoding, and we can hardcode nonexisting dirs.
+ hardcode_action=immediate
+ fi
+else
+ # We cannot hardcode anything, or else we can only hardcode existing
+ # directories.
+ hardcode_action=unsupported
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5
+$as_echo "$hardcode_action" >&6; }
+
+if test "$hardcode_action" = relink ||
+ test "$inherit_rpath" = yes; then
+ # Fast installation is not supported
+ enable_fast_install=no
+elif test "$shlibpath_overrides_runpath" = yes ||
+ test "$enable_shared" = no; then
+ # Fast installation is not necessary
+ enable_fast_install=needless
+fi
+
+
+
+
+
+
+ if test "x$enable_dlopen" != xyes; then
+ enable_dlopen=unknown
+ enable_dlopen_self=unknown
+ enable_dlopen_self_static=unknown
+else
+ lt_cv_dlopen=no
+ lt_cv_dlopen_libs=
+
+ case $host_os in
+ beos*)
+ lt_cv_dlopen="load_add_on"
+ lt_cv_dlopen_libs=
+ lt_cv_dlopen_self=yes
+ ;;
+
+ mingw* | pw32* | cegcc*)
+ lt_cv_dlopen="LoadLibrary"
+ lt_cv_dlopen_libs=
+ ;;
+
+ cygwin*)
+ lt_cv_dlopen="dlopen"
+ lt_cv_dlopen_libs=
+ ;;
+
+ darwin*)
+ # if libdl is installed we need to link against it
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5
+$as_echo_n "checking for dlopen in -ldl... " >&6; }
+if ${ac_cv_lib_dl_dlopen+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldl $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen ();
+int
+main ()
+{
+return dlopen ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_dl_dlopen=yes
+else
+ ac_cv_lib_dl_dlopen=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5
+$as_echo "$ac_cv_lib_dl_dlopen" >&6; }
+if test "x$ac_cv_lib_dl_dlopen" = xyes; then :
+ lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"
+else
+
+ lt_cv_dlopen="dyld"
+ lt_cv_dlopen_libs=
+ lt_cv_dlopen_self=yes
+
+fi
+
+ ;;
+
+ *)
+ ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load"
+if test "x$ac_cv_func_shl_load" = xyes; then :
+ lt_cv_dlopen="shl_load"
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5
+$as_echo_n "checking for shl_load in -ldld... " >&6; }
+if ${ac_cv_lib_dld_shl_load+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldld $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char shl_load ();
+int
+main ()
+{
+return shl_load ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_dld_shl_load=yes
+else
+ ac_cv_lib_dld_shl_load=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5
+$as_echo "$ac_cv_lib_dld_shl_load" >&6; }
+if test "x$ac_cv_lib_dld_shl_load" = xyes; then :
+ lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"
+else
+ ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen"
+if test "x$ac_cv_func_dlopen" = xyes; then :
+ lt_cv_dlopen="dlopen"
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5
+$as_echo_n "checking for dlopen in -ldl... " >&6; }
+if ${ac_cv_lib_dl_dlopen+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldl $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen ();
+int
+main ()
+{
+return dlopen ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_dl_dlopen=yes
+else
+ ac_cv_lib_dl_dlopen=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5
+$as_echo "$ac_cv_lib_dl_dlopen" >&6; }
+if test "x$ac_cv_lib_dl_dlopen" = xyes; then :
+ lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5
+$as_echo_n "checking for dlopen in -lsvld... " >&6; }
+if ${ac_cv_lib_svld_dlopen+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsvld $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen ();
+int
+main ()
+{
+return dlopen ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_svld_dlopen=yes
+else
+ ac_cv_lib_svld_dlopen=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5
+$as_echo "$ac_cv_lib_svld_dlopen" >&6; }
+if test "x$ac_cv_lib_svld_dlopen" = xyes; then :
+ lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5
+$as_echo_n "checking for dld_link in -ldld... " >&6; }
+if ${ac_cv_lib_dld_dld_link+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldld $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dld_link ();
+int
+main ()
+{
+return dld_link ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_dld_dld_link=yes
+else
+ ac_cv_lib_dld_dld_link=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5
+$as_echo "$ac_cv_lib_dld_dld_link" >&6; }
+if test "x$ac_cv_lib_dld_dld_link" = xyes; then :
+ lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+ ;;
+ esac
+
+ if test "x$lt_cv_dlopen" != xno; then
+ enable_dlopen=yes
+ else
+ enable_dlopen=no
+ fi
+
+ case $lt_cv_dlopen in
+ dlopen)
+ save_CPPFLAGS="$CPPFLAGS"
+ test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
+
+ save_LDFLAGS="$LDFLAGS"
+ wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
+
+ save_LIBS="$LIBS"
+ LIBS="$lt_cv_dlopen_libs $LIBS"
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5
+$as_echo_n "checking whether a program can dlopen itself... " >&6; }
+if ${lt_cv_dlopen_self+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "$cross_compiling" = yes; then :
+ lt_cv_dlopen_self=cross
+else
+ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+ lt_status=$lt_dlunknown
+ cat > conftest.$ac_ext <<_LT_EOF
+#line $LINENO "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+# define LT_DLGLOBAL RTLD_GLOBAL
+#else
+# ifdef DL_GLOBAL
+# define LT_DLGLOBAL DL_GLOBAL
+# else
+# define LT_DLGLOBAL 0
+# endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+ find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+# ifdef RTLD_LAZY
+# define LT_DLLAZY_OR_NOW RTLD_LAZY
+# else
+# ifdef DL_LAZY
+# define LT_DLLAZY_OR_NOW DL_LAZY
+# else
+# ifdef RTLD_NOW
+# define LT_DLLAZY_OR_NOW RTLD_NOW
+# else
+# ifdef DL_NOW
+# define LT_DLLAZY_OR_NOW DL_NOW
+# else
+# define LT_DLLAZY_OR_NOW 0
+# endif
+# endif
+# endif
+# endif
+#endif
+
+/* When -fvisbility=hidden is used, assume the code has been annotated
+ correspondingly for the symbols needed. */
+#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
+int fnord () __attribute__((visibility("default")));
+#endif
+
+int fnord () { return 42; }
+int main ()
+{
+ void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+ int status = $lt_dlunknown;
+
+ if (self)
+ {
+ if (dlsym (self,"fnord")) status = $lt_dlno_uscore;
+ else
+ {
+ if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
+ else puts (dlerror ());
+ }
+ /* dlclose (self); */
+ }
+ else
+ puts (dlerror ());
+
+ return status;
+}
+_LT_EOF
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then
+ (./conftest; exit; ) >&5 2>/dev/null
+ lt_status=$?
+ case x$lt_status in
+ x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;;
+ x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;;
+ x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;;
+ esac
+ else :
+ # compilation failed
+ lt_cv_dlopen_self=no
+ fi
+fi
+rm -fr conftest*
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5
+$as_echo "$lt_cv_dlopen_self" >&6; }
+
+ if test "x$lt_cv_dlopen_self" = xyes; then
+ wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5
+$as_echo_n "checking whether a statically linked program can dlopen itself... " >&6; }
+if ${lt_cv_dlopen_self_static+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "$cross_compiling" = yes; then :
+ lt_cv_dlopen_self_static=cross
+else
+ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+ lt_status=$lt_dlunknown
+ cat > conftest.$ac_ext <<_LT_EOF
+#line $LINENO "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+# define LT_DLGLOBAL RTLD_GLOBAL
+#else
+# ifdef DL_GLOBAL
+# define LT_DLGLOBAL DL_GLOBAL
+# else
+# define LT_DLGLOBAL 0
+# endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+ find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+# ifdef RTLD_LAZY
+# define LT_DLLAZY_OR_NOW RTLD_LAZY
+# else
+# ifdef DL_LAZY
+# define LT_DLLAZY_OR_NOW DL_LAZY
+# else
+# ifdef RTLD_NOW
+# define LT_DLLAZY_OR_NOW RTLD_NOW
+# else
+# ifdef DL_NOW
+# define LT_DLLAZY_OR_NOW DL_NOW
+# else
+# define LT_DLLAZY_OR_NOW 0
+# endif
+# endif
+# endif
+# endif
+#endif
+
+/* When -fvisbility=hidden is used, assume the code has been annotated
+ correspondingly for the symbols needed. */
+#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
+int fnord () __attribute__((visibility("default")));
+#endif
+
+int fnord () { return 42; }
+int main ()
+{
+ void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+ int status = $lt_dlunknown;
+
+ if (self)
+ {
+ if (dlsym (self,"fnord")) status = $lt_dlno_uscore;
+ else
+ {
+ if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
+ else puts (dlerror ());
+ }
+ /* dlclose (self); */
+ }
+ else
+ puts (dlerror ());
+
+ return status;
+}
+_LT_EOF
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then
+ (./conftest; exit; ) >&5 2>/dev/null
+ lt_status=$?
+ case x$lt_status in
+ x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;;
+ x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;;
+ x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;;
+ esac
+ else :
+ # compilation failed
+ lt_cv_dlopen_self_static=no
+ fi
+fi
+rm -fr conftest*
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5
+$as_echo "$lt_cv_dlopen_self_static" >&6; }
+ fi
+
+ CPPFLAGS="$save_CPPFLAGS"
+ LDFLAGS="$save_LDFLAGS"
+ LIBS="$save_LIBS"
+ ;;
+ esac
+
+ case $lt_cv_dlopen_self in
+ yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;;
+ *) enable_dlopen_self=unknown ;;
+ esac
+
+ case $lt_cv_dlopen_self_static in
+ yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;;
+ *) enable_dlopen_self_static=unknown ;;
+ esac
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+striplib=
+old_striplib=
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5
+$as_echo_n "checking whether stripping libraries is possible... " >&6; }
+if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then
+ test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
+ test -z "$striplib" && striplib="$STRIP --strip-unneeded"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+# FIXME - insert some real tests, host_os isn't really good enough
+ case $host_os in
+ darwin*)
+ if test -n "$STRIP" ; then
+ striplib="$STRIP -x"
+ old_striplib="$STRIP -S"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ fi
+ ;;
+ *)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ ;;
+ esac
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+ # Report which library types will actually be built
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5
+$as_echo_n "checking if libtool supports shared libraries... " >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5
+$as_echo "$can_build_shared" >&6; }
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5
+$as_echo_n "checking whether to build shared libraries... " >&6; }
+ test "$can_build_shared" = "no" && enable_shared=no
+
+ # On AIX, shared libraries and static libraries use the same namespace, and
+ # are all built from PIC.
+ case $host_os in
+ aix3*)
+ test "$enable_shared" = yes && enable_static=no
+ if test -n "$RANLIB"; then
+ archive_cmds="$archive_cmds~\$RANLIB \$lib"
+ postinstall_cmds='$RANLIB $lib'
+ fi
+ ;;
+
+ aix[4-9]*)
+ if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+ test "$enable_shared" = yes && enable_static=no
+ fi
+ ;;
+ esac
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5
+$as_echo "$enable_shared" >&6; }
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5
+$as_echo_n "checking whether to build static libraries... " >&6; }
+ # Make sure either enable_shared or enable_static is yes.
+ test "$enable_shared" = yes || enable_static=yes
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5
+$as_echo "$enable_static" >&6; }
+
+
+
+
+fi
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+CC="$lt_save_CC"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ac_config_commands="$ac_config_commands libtool"
+
+
+
+
+# Only expand once:
+
+
+
+# Check whether --enable-silent-rules was given.
+if test "${enable_silent_rules+set}" = set; then :
+ enableval=$enable_silent_rules;
+fi
+
+case $enable_silent_rules in # (((
+ yes) AM_DEFAULT_VERBOSITY=0;;
+ no) AM_DEFAULT_VERBOSITY=1;;
+ *) AM_DEFAULT_VERBOSITY=0;;
+esac
+am_make=${MAKE-make}
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5
+$as_echo_n "checking whether $am_make supports nested variables... " >&6; }
+if ${am_cv_make_support_nested_variables+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if $as_echo 'TRUE=$(BAR$(V))
+BAR0=false
+BAR1=true
+V=1
+am__doit:
+ @$(TRUE)
+.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then
+ am_cv_make_support_nested_variables=yes
+else
+ am_cv_make_support_nested_variables=no
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5
+$as_echo "$am_cv_make_support_nested_variables" >&6; }
+if test $am_cv_make_support_nested_variables = yes; then
+ AM_V='$(V)'
+ AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)'
+else
+ AM_V=$AM_DEFAULT_VERBOSITY
+ AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY
+fi
+AM_BACKSLASH='\'
+
+
+
+ac_config_headers="$ac_config_headers include/corosync/config.h"
+
+
+
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+WITH_LIST=""
+
+
+#Enable inter-library dependencies
+# Check whether --enable-interlib-deps was given.
+if test "${enable_interlib_deps+set}" = set; then :
+ enableval=$enable_interlib_deps; enable_interlib_deps="$enableval"
+else
+ enable_interlib_deps="yes"
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: enable inter-library dependencies: $enable_interlib_deps" >&5
+$as_echo "$as_me: enable inter-library dependencies: $enable_interlib_deps" >&6;}
+if test "x${enable_interlib_deps}" = "xyes"; then
+ link_all_deplibs=yes
+ link_all_deplibs_CXX=yes
+else
+ link_all_deplibs=no
+ link_all_deplibs_CXX=no
+fi
+
+# Check whether --enable-rust-bindings was given.
+if test "${enable_rust_bindings+set}" = set; then :
+ enableval=$enable_rust_bindings;
+else
+ enable_rust_bindings="no"
+fi
+
+ if test x$enable_rust_bindings = xyes; then
+ BUILD_RUST_BINDINGS_TRUE=
+ BUILD_RUST_BINDINGS_FALSE='#'
+else
+ BUILD_RUST_BINDINGS_TRUE='#'
+ BUILD_RUST_BINDINGS_FALSE=
+fi
+
+corosyncrustver="`echo ${VERSION} | sed 's/\(.*\)\./\1-/'`"
+
+
+systemddir=${prefix}/lib/systemd/system
+
+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 "$systemddir" = "NONE/lib/systemd/system"; then
+ systemddir=/lib/systemd/system
+ fi
+ if test "$libdir" = "\${exec_prefix}/lib"; then
+ if test -e /usr/lib64; then
+ libdir="/usr/lib64"
+ else
+ libdir="/usr/lib"
+ fi
+ fi
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: Sanitizing exec_prefix: ${exec_prefix}" >&5
+$as_echo "$as_me: Sanitizing exec_prefix: ${exec_prefix}" >&6;}
+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
+ as_fn_error $? "you don't seem to have GNU make; it is required" "$LINENO" 5
+fi
+
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="${ac_tool_prefix}gcc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+ ac_ct_CC=$CC
+ # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_CC="gcc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_CC" = x; then
+ CC=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ CC=$ac_ct_CC
+ fi
+else
+ CC="$ac_cv_prog_CC"
+fi
+
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="${ac_tool_prefix}cc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ fi
+fi
+if test -z "$CC"; then
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+ ac_prog_rejected=yes
+ continue
+ fi
+ ac_cv_prog_CC="cc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+if test $ac_prog_rejected = yes; then
+ # We found a bogon in the path, so make sure we never use it.
+ set dummy $ac_cv_prog_CC
+ shift
+ if test $# != 0; then
+ # We chose a different compiler from the bogus one.
+ # However, it has the same basename, so the bogon will be chosen
+ # first if we set CC to just the basename; use the full file name.
+ shift
+ ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+ fi
+fi
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ for ac_prog in cl.exe
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$CC" && break
+ done
+fi
+if test -z "$CC"; then
+ ac_ct_CC=$CC
+ for ac_prog in cl.exe
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_CC="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$ac_ct_CC" && break
+done
+
+ if test "x$ac_ct_CC" = x; then
+ CC=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ CC=$ac_ct_CC
+ fi
+fi
+
+fi
+
+
+test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "no acceptable C compiler found in \$PATH
+See \`config.log' for more details" "$LINENO" 5; }
+
+# Provide some information about the compiler.
+$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+for ac_option in --version -v -V -qversion; do
+ { { ac_try="$ac_compiler $ac_option >&5"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compiler $ac_option >&5") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ sed '10a\
+... rest of stderr output deleted ...
+ 10q' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ fi
+ rm -f conftest.er1 conftest.err
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+done
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5
+$as_echo_n "checking whether we are using the GNU C compiler... " >&6; }
+if ${ac_cv_c_compiler_gnu+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+#ifndef __GNUC__
+ choke me
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_compiler_gnu=yes
+else
+ ac_compiler_gnu=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5
+$as_echo "$ac_cv_c_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+ GCC=yes
+else
+ GCC=
+fi
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5
+$as_echo_n "checking whether $CC accepts -g... " >&6; }
+if ${ac_cv_prog_cc_g+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_save_c_werror_flag=$ac_c_werror_flag
+ ac_c_werror_flag=yes
+ ac_cv_prog_cc_g=no
+ CFLAGS="-g"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_g=yes
+else
+ CFLAGS=""
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+else
+ ac_c_werror_flag=$ac_save_c_werror_flag
+ CFLAGS="-g"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_g=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_c_werror_flag=$ac_save_c_werror_flag
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5
+$as_echo "$ac_cv_prog_cc_g" >&6; }
+if test "$ac_test_CFLAGS" = set; then
+ CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+ if test "$GCC" = yes; then
+ CFLAGS="-g -O2"
+ else
+ CFLAGS="-g"
+ fi
+else
+ if test "$GCC" = yes; then
+ CFLAGS="-O2"
+ else
+ CFLAGS=
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5
+$as_echo_n "checking for $CC option to accept ISO C89... " >&6; }
+if ${ac_cv_prog_cc_c89+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_prog_cc_c89=no
+ac_save_CC=$CC
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdarg.h>
+#include <stdio.h>
+struct stat;
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+ char **p;
+ int i;
+{
+ return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+ char *s;
+ va_list v;
+ va_start (v,p);
+ s = g (p, va_arg (v,int));
+ va_end (v);
+ return s;
+}
+
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has
+ function prototypes and stuff, but not '\xHH' hex character constants.
+ These don't provoke an error unfortunately, instead are silently treated
+ as 'x'. The following induces an error, until -std is added to get
+ proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an
+ array size at least. It's necessary to write '\x00'==0 to get something
+ that's true only with -std. */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+
+/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
+ inside strings and character constants. */
+#define FOO(x) 'x'
+int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
+
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1];
+ ;
+ return 0;
+}
+_ACEOF
+for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
+ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+ CC="$ac_save_CC $ac_arg"
+ if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_c89=$ac_arg
+fi
+rm -f core conftest.err conftest.$ac_objext
+ test "x$ac_cv_prog_cc_c89" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CC=$ac_save_CC
+
+fi
+# AC_CACHE_VAL
+case "x$ac_cv_prog_cc_c89" in
+ x)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+$as_echo "none needed" >&6; } ;;
+ xno)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+$as_echo "unsupported" >&6; } ;;
+ *)
+ CC="$CC $ac_cv_prog_cc_c89"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
+$as_echo "$ac_cv_prog_cc_c89" >&6; } ;;
+esac
+if test "x$ac_cv_prog_cc_c89" != xno; then :
+
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C99" >&5
+$as_echo_n "checking for $CC option to accept ISO C99... " >&6; }
+if ${ac_cv_prog_cc_c99+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_prog_cc_c99=no
+ac_save_CC=$CC
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <wchar.h>
+#include <stdio.h>
+
+// Check varargs macros. These examples are taken from C99 6.10.3.5.
+#define debug(...) fprintf (stderr, __VA_ARGS__)
+#define showlist(...) puts (#__VA_ARGS__)
+#define report(test,...) ((test) ? puts (#test) : printf (__VA_ARGS__))
+static void
+test_varargs_macros (void)
+{
+ int x = 1234;
+ int y = 5678;
+ debug ("Flag");
+ debug ("X = %d\n", x);
+ showlist (The first, second, and third items.);
+ report (x>y, "x is %d but y is %d", x, y);
+}
+
+// Check long long types.
+#define BIG64 18446744073709551615ull
+#define BIG32 4294967295ul
+#define BIG_OK (BIG64 / BIG32 == 4294967297ull && BIG64 % BIG32 == 0)
+#if !BIG_OK
+ your preprocessor is broken;
+#endif
+#if BIG_OK
+#else
+ your preprocessor is broken;
+#endif
+static long long int bignum = -9223372036854775807LL;
+static unsigned long long int ubignum = BIG64;
+
+struct incomplete_array
+{
+ int datasize;
+ double data[];
+};
+
+struct named_init {
+ int number;
+ const wchar_t *name;
+ double average;
+};
+
+typedef const char *ccp;
+
+static inline int
+test_restrict (ccp restrict text)
+{
+ // See if C++-style comments work.
+ // Iterate through items via the restricted pointer.
+ // Also check for declarations in for loops.
+ for (unsigned int i = 0; *(text+i) != '\0'; ++i)
+ continue;
+ return 0;
+}
+
+// Check varargs and va_copy.
+static void
+test_varargs (const char *format, ...)
+{
+ va_list args;
+ va_start (args, format);
+ va_list args_copy;
+ va_copy (args_copy, args);
+
+ const char *str;
+ int number;
+ float fnumber;
+
+ while (*format)
+ {
+ switch (*format++)
+ {
+ case 's': // string
+ str = va_arg (args_copy, const char *);
+ break;
+ case 'd': // int
+ number = va_arg (args_copy, int);
+ break;
+ case 'f': // float
+ fnumber = va_arg (args_copy, double);
+ break;
+ default:
+ break;
+ }
+ }
+ va_end (args_copy);
+ va_end (args);
+}
+
+int
+main ()
+{
+
+ // Check bool.
+ _Bool success = false;
+
+ // Check restrict.
+ if (test_restrict ("String literal") == 0)
+ success = true;
+ char *restrict newvar = "Another string";
+
+ // Check varargs.
+ test_varargs ("s, d' f .", "string", 65, 34.234);
+ test_varargs_macros ();
+
+ // Check flexible array members.
+ struct incomplete_array *ia =
+ malloc (sizeof (struct incomplete_array) + (sizeof (double) * 10));
+ ia->datasize = 10;
+ for (int i = 0; i < ia->datasize; ++i)
+ ia->data[i] = i * 1.234;
+
+ // Check named initializers.
+ struct named_init ni = {
+ .number = 34,
+ .name = L"Test wide string",
+ .average = 543.34343,
+ };
+
+ ni.number = 58;
+
+ int dynamic_array[ni.number];
+ dynamic_array[ni.number - 1] = 543;
+
+ // work around unused variable warnings
+ return (!success || bignum == 0LL || ubignum == 0uLL || newvar[0] == 'x'
+ || dynamic_array[ni.number - 1] != 543);
+
+ ;
+ return 0;
+}
+_ACEOF
+for ac_arg in '' -std=gnu99 -std=c99 -c99 -AC99 -D_STDC_C99= -qlanglvl=extc99
+do
+ CC="$ac_save_CC $ac_arg"
+ if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_c99=$ac_arg
+fi
+rm -f core conftest.err conftest.$ac_objext
+ test "x$ac_cv_prog_cc_c99" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CC=$ac_save_CC
+
+fi
+# AC_CACHE_VAL
+case "x$ac_cv_prog_cc_c99" in
+ x)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+$as_echo "none needed" >&6; } ;;
+ xno)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+$as_echo "unsupported" >&6; } ;;
+ *)
+ CC="$CC $ac_cv_prog_cc_c99"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c99" >&5
+$as_echo "$ac_cv_prog_cc_c99" >&6; } ;;
+esac
+if test "x$ac_cv_prog_cc_c99" != xno; then :
+
+fi
+
+
+if test "x$ac_cv_prog_cc_c99" = "xno"; then
+ as_fn_error $? "\"C99 support is required\"" "$LINENO" 5
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5
+$as_echo_n "checking whether ln -s works... " >&6; }
+LN_S=$as_ln_s
+if test "$LN_S" = "ln -s"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5
+$as_echo "no, using $LN_S" >&6; }
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5
+$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; }
+set x ${MAKE-make}
+ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'`
+if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat >conftest.make <<\_ACEOF
+SHELL = /bin/sh
+all:
+ @echo '@@@%%%=$(MAKE)=@@@%%%'
+_ACEOF
+# GNU make sometimes prints "make[1]: Entering ...", which would confuse us.
+case `${MAKE-make} -f conftest.make 2>/dev/null` in
+ *@@@%%%=?*=@@@%%%*)
+ eval ac_cv_prog_make_${ac_make}_set=yes;;
+ *)
+ eval ac_cv_prog_make_${ac_make}_set=no;;
+esac
+rm -f conftest.make
+fi
+if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ SET_MAKE=
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5
+$as_echo_n "checking for a sed that does not truncate output... " >&6; }
+if ${ac_cv_path_SED+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/
+ for ac_i in 1 2 3 4 5 6 7; do
+ ac_script="$ac_script$as_nl$ac_script"
+ done
+ echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed
+ { ac_script=; unset ac_script;}
+ if test -z "$SED"; then
+ ac_path_SED_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in sed gsed; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_SED="$as_dir/$ac_prog$ac_exec_ext"
+ as_fn_executable_p "$ac_path_SED" || continue
+# Check for GNU ac_path_SED and select it if it is found.
+ # Check for GNU $ac_path_SED
+case `"$ac_path_SED" --version 2>&1` in
+*GNU*)
+ ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;;
+*)
+ ac_count=0
+ $as_echo_n 0123456789 >"conftest.in"
+ while :
+ do
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
+ mv "conftest.tmp" "conftest.in"
+ cp "conftest.in" "conftest.nl"
+ $as_echo '' >> "conftest.nl"
+ "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break
+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+ as_fn_arith $ac_count + 1 && ac_count=$as_val
+ if test $ac_count -gt ${ac_path_SED_max-0}; then
+ # Best one so far, save it but keep looking for a better one
+ ac_cv_path_SED="$ac_path_SED"
+ ac_path_SED_max=$ac_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test $ac_count -gt 10 && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+ $ac_path_SED_found && break 3
+ done
+ done
+ done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_SED"; then
+ as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5
+ fi
+else
+ ac_cv_path_SED=$SED
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5
+$as_echo "$ac_cv_path_SED" >&6; }
+ SED="$ac_cv_path_SED"
+ rm -f conftest.sed
+
+
+
+
+
+
+
+
+if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args.
+set dummy ${ac_tool_prefix}pkg-config; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_PKG_CONFIG+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $PKG_CONFIG in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+fi
+PKG_CONFIG=$ac_cv_path_PKG_CONFIG
+if test -n "$PKG_CONFIG"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5
+$as_echo "$PKG_CONFIG" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_path_PKG_CONFIG"; then
+ ac_pt_PKG_CONFIG=$PKG_CONFIG
+ # Extract the first word of "pkg-config", so it can be a program name with args.
+set dummy pkg-config; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_ac_pt_PKG_CONFIG+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $ac_pt_PKG_CONFIG in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+fi
+ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG
+if test -n "$ac_pt_PKG_CONFIG"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5
+$as_echo "$ac_pt_PKG_CONFIG" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_pt_PKG_CONFIG" = x; then
+ PKG_CONFIG=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ PKG_CONFIG=$ac_pt_PKG_CONFIG
+ fi
+else
+ PKG_CONFIG="$ac_cv_path_PKG_CONFIG"
+fi
+
+fi
+if test -n "$PKG_CONFIG"; then
+ _pkg_min_version=0.9.0
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking pkg-config is at least version $_pkg_min_version" >&5
+$as_echo_n "checking pkg-config is at least version $_pkg_min_version... " >&6; }
+ if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ PKG_CONFIG=""
+ fi
+fi
+
+for ac_prog in groff
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_GROFF+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$GROFF"; then
+ ac_cv_prog_GROFF="$GROFF" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_GROFF="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+GROFF=$ac_cv_prog_GROFF
+if test -n "$GROFF"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GROFF" >&5
+$as_echo "$GROFF" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$GROFF" && break
+done
+
+for ac_prog in augtool
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_AUGTOOL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$AUGTOOL"; then
+ ac_cv_prog_AUGTOOL="$AUGTOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_AUGTOOL="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+AUGTOOL=$ac_cv_prog_AUGTOOL
+if test -n "$AUGTOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AUGTOOL" >&5
+$as_echo "$AUGTOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$AUGTOOL" && break
+done
+
+for ac_prog in dot
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_DOT+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$DOT"; then
+ ac_cv_prog_DOT="$DOT" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_DOT="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+DOT=$ac_cv_prog_DOT
+if test -n "$DOT"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DOT" >&5
+$as_echo "$DOT" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$DOT" && break
+done
+
+for ac_prog in doxygen
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_DOXYGEN+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$DOXYGEN"; then
+ ac_cv_prog_DOXYGEN="$DOXYGEN" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_DOXYGEN="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+DOXYGEN=$ac_cv_prog_DOXYGEN
+if test -n "$DOXYGEN"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DOXYGEN" >&5
+$as_echo "$DOXYGEN" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$DOXYGEN" && break
+done
+
+for ac_prog in awk
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_AWK+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$AWK"; then
+ ac_cv_prog_AWK="$AWK" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_AWK="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+AWK=$ac_cv_prog_AWK
+if test -n "$AWK"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5
+$as_echo "$AWK" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$AWK" && break
+done
+
+# Extract the first word of "bash", so it can be a program name with args.
+set dummy bash; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_BASHPATH+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $BASHPATH in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_BASHPATH="$BASHPATH" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_BASHPATH="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+fi
+BASHPATH=$ac_cv_path_BASHPATH
+if test -n "$BASHPATH"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $BASHPATH" >&5
+$as_echo "$BASHPATH" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+
+# Checks for compiler characteristics.
+if test $ac_cv_c_compiler_gnu = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC needs -traditional" >&5
+$as_echo_n "checking whether $CC needs -traditional... " >&6; }
+if ${ac_cv_prog_gcc_traditional+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_pattern="Autoconf.*'x'"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sgtty.h>
+Autoconf TIOCGETP
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "$ac_pattern" >/dev/null 2>&1; then :
+ ac_cv_prog_gcc_traditional=yes
+else
+ ac_cv_prog_gcc_traditional=no
+fi
+rm -f conftest*
+
+
+ if test $ac_cv_prog_gcc_traditional = no; then
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <termio.h>
+Autoconf TCGETA
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "$ac_pattern" >/dev/null 2>&1; then :
+ ac_cv_prog_gcc_traditional=yes
+fi
+rm -f conftest*
+
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_gcc_traditional" >&5
+$as_echo "$ac_cv_prog_gcc_traditional" >&6; }
+ if test $ac_cv_prog_gcc_traditional = yes; then
+ CC="$CC -traditional"
+ fi
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5
+$as_echo_n "checking for an ANSI C-conforming const... " >&6; }
+if ${ac_cv_c_const+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+#ifndef __cplusplus
+ /* Ultrix mips cc rejects this sort of thing. */
+ typedef int charset[2];
+ const charset cs = { 0, 0 };
+ /* SunOS 4.1.1 cc rejects this. */
+ char const *const *pcpcc;
+ char **ppc;
+ /* NEC SVR4.0.2 mips cc rejects this. */
+ struct point {int x, y;};
+ static struct point const zero = {0,0};
+ /* AIX XL C 1.02.0.0 rejects this.
+ It does not let you subtract one const X* pointer from another in
+ an arm of an if-expression whose if-part is not a constant
+ expression */
+ const char *g = "string";
+ pcpcc = &g + (g ? g-g : 0);
+ /* HPUX 7.0 cc rejects these. */
+ ++pcpcc;
+ ppc = (char**) pcpcc;
+ pcpcc = (char const *const *) ppc;
+ { /* SCO 3.2v4 cc rejects this sort of thing. */
+ char tx;
+ char *t = &tx;
+ char const *s = 0 ? (char *) 0 : (char const *) 0;
+
+ *t++ = 0;
+ if (s) return 0;
+ }
+ { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */
+ int x[] = {25, 17};
+ const int *foo = &x[0];
+ ++foo;
+ }
+ { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */
+ typedef const int *iptr;
+ iptr p = 0;
+ ++p;
+ }
+ { /* AIX XL C 1.02.0.0 rejects this sort of thing, saying
+ "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */
+ struct s { int j; const int *ap[3]; } bx;
+ struct s *b = &bx; b->j = 5;
+ }
+ { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */
+ const int foo = 10;
+ if (!foo) return 0;
+ }
+ return !cs[0] && !zero.x;
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_c_const=yes
+else
+ ac_cv_c_const=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_const" >&5
+$as_echo "$ac_cv_c_const" >&6; }
+if test $ac_cv_c_const = no; then
+
+$as_echo "#define const /**/" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for inline" >&5
+$as_echo_n "checking for inline... " >&6; }
+if ${ac_cv_c_inline+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_c_inline=no
+for ac_kw in inline __inline__ __inline; do
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#ifndef __cplusplus
+typedef int foo_t;
+static $ac_kw foo_t static_foo () {return 0; }
+$ac_kw foo_t foo () {return 0; }
+#endif
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_c_inline=$ac_kw
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ test "$ac_cv_c_inline" != no && break
+done
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_inline" >&5
+$as_echo "$ac_cv_c_inline" >&6; }
+
+case $ac_cv_c_inline in
+ inline | yes) ;;
+ *)
+ case $ac_cv_c_inline in
+ no) ac_val=;;
+ *) ac_val=$ac_cv_c_inline;;
+ esac
+ cat >>confdefs.h <<_ACEOF
+#ifndef __cplusplus
+#define inline $ac_val
+#endif
+_ACEOF
+ ;;
+esac
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for working volatile" >&5
+$as_echo_n "checking for working volatile... " >&6; }
+if ${ac_cv_c_volatile+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+volatile int x;
+int * volatile y = (int *) 0;
+return !x && !y;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_c_volatile=yes
+else
+ ac_cv_c_volatile=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_volatile" >&5
+$as_echo "$ac_cv_c_volatile" >&6; }
+if test $ac_cv_c_volatile = no; then
+
+$as_echo "#define volatile /**/" >>confdefs.h
+
+fi
+
+
+# Checks for header files.
+ac_header_dirent=no
+for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h; do
+ as_ac_Header=`$as_echo "ac_cv_header_dirent_$ac_hdr" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_hdr that defines DIR" >&5
+$as_echo_n "checking for $ac_hdr that defines DIR... " >&6; }
+if eval \${$as_ac_Header+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sys/types.h>
+#include <$ac_hdr>
+
+int
+main ()
+{
+if ((DIR *) 0)
+return 0;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ eval "$as_ac_Header=yes"
+else
+ eval "$as_ac_Header=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$as_ac_Header
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_hdr" | $as_tr_cpp` 1
+_ACEOF
+
+ac_header_dirent=$ac_hdr; break
+fi
+
+done
+# Two versions of opendir et al. are in -ldir and -lx on SCO Xenix.
+if test $ac_header_dirent = dirent.h; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing opendir" >&5
+$as_echo_n "checking for library containing opendir... " >&6; }
+if ${ac_cv_search_opendir+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char opendir ();
+int
+main ()
+{
+return opendir ();
+ ;
+ return 0;
+}
+_ACEOF
+for ac_lib in '' dir; do
+ if test -z "$ac_lib"; then
+ ac_res="none required"
+ else
+ ac_res=-l$ac_lib
+ LIBS="-l$ac_lib $ac_func_search_save_LIBS"
+ fi
+ if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_search_opendir=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext
+ if ${ac_cv_search_opendir+:} false; then :
+ break
+fi
+done
+if ${ac_cv_search_opendir+:} false; then :
+
+else
+ ac_cv_search_opendir=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_opendir" >&5
+$as_echo "$ac_cv_search_opendir" >&6; }
+ac_res=$ac_cv_search_opendir
+if test "$ac_res" != no; then :
+ test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+fi
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing opendir" >&5
+$as_echo_n "checking for library containing opendir... " >&6; }
+if ${ac_cv_search_opendir+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char opendir ();
+int
+main ()
+{
+return opendir ();
+ ;
+ return 0;
+}
+_ACEOF
+for ac_lib in '' x; do
+ if test -z "$ac_lib"; then
+ ac_res="none required"
+ else
+ ac_res=-l$ac_lib
+ LIBS="-l$ac_lib $ac_func_search_save_LIBS"
+ fi
+ if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_search_opendir=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext
+ if ${ac_cv_search_opendir+:} false; then :
+ break
+fi
+done
+if ${ac_cv_search_opendir+:} false; then :
+
+else
+ ac_cv_search_opendir=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_opendir" >&5
+$as_echo "$ac_cv_search_opendir" >&6; }
+ac_res=$ac_cv_search_opendir
+if test "$ac_res" != no; then :
+ test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+fi
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sys/wait.h that is POSIX.1 compatible" >&5
+$as_echo_n "checking for sys/wait.h that is POSIX.1 compatible... " >&6; }
+if ${ac_cv_header_sys_wait_h+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sys/types.h>
+#include <sys/wait.h>
+#ifndef WEXITSTATUS
+# define WEXITSTATUS(stat_val) ((unsigned int) (stat_val) >> 8)
+#endif
+#ifndef WIFEXITED
+# define WIFEXITED(stat_val) (((stat_val) & 255) == 0)
+#endif
+
+int
+main ()
+{
+ int s;
+ wait (&s);
+ s = WIFEXITED (s) ? WEXITSTATUS (s) : 1;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_header_sys_wait_h=yes
+else
+ ac_cv_header_sys_wait_h=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_sys_wait_h" >&5
+$as_echo "$ac_cv_header_sys_wait_h" >&6; }
+if test $ac_cv_header_sys_wait_h = yes; then
+
+$as_echo "#define HAVE_SYS_WAIT_H 1" >>confdefs.h
+
+fi
+
+for ac_header in arpa/inet.h fcntl.h limits.h netdb.h netinet/in.h stdint.h \
+ stdlib.h string.h sys/ioctl.h sys/param.h sys/socket.h \
+ sys/time.h syslog.h unistd.h sys/types.h getopt.h malloc.h \
+ utmpx.h ifaddrs.h stddef.h sys/file.h sys/uio.h
+do :
+ as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+# Check entries in specific structs
+ac_fn_c_check_member "$LINENO" "struct sockaddr_in" "sin_len" "ac_cv_member_struct_sockaddr_in_sin_len" "#include <netinet/in.h>
+"
+if test "x$ac_cv_member_struct_sockaddr_in_sin_len" = xyes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_SOCK_SIN_LEN 1
+_ACEOF
+
+fi
+
+ac_fn_c_check_member "$LINENO" "struct sockaddr_in6" "sin6_len" "ac_cv_member_struct_sockaddr_in6_sin6_len" "#include <netinet/in.h>
+"
+if test "x$ac_cv_member_struct_sockaddr_in6_sin6_len" = xyes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_SOCK_SIN6_LEN 1
+_ACEOF
+
+fi
+
+ac_fn_c_check_member "$LINENO" "struct msghdr" "msg_control" "ac_cv_member_struct_msghdr_msg_control" "#include <sys/socket.h>
+"
+if test "x$ac_cv_member_struct_msghdr_msg_control" = xyes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_MSGHDR_CONTROL 1
+_ACEOF
+
+fi
+
+ac_fn_c_check_member "$LINENO" "struct msghdr" "msg_controllen" "ac_cv_member_struct_msghdr_msg_controllen" "#include <sys/socket.h>
+"
+if test "x$ac_cv_member_struct_msghdr_msg_controllen" = xyes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_MSGHDR_CONTROLLEN 1
+_ACEOF
+
+fi
+
+ac_fn_c_check_member "$LINENO" "struct msghdr" "msg_flags" "ac_cv_member_struct_msghdr_msg_flags" "#include <sys/socket.h>
+"
+if test "x$ac_cv_member_struct_msghdr_msg_flags" = xyes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_MSGHDR_FLAGS 1
+_ACEOF
+
+fi
+
+ac_fn_c_check_member "$LINENO" "struct msghdr" "msg_accrights" "ac_cv_member_struct_msghdr_msg_accrights" "#include <sys/socket.h>
+"
+if test "x$ac_cv_member_struct_msghdr_msg_accrights" = xyes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_MSGHDR_ACCRIGHTS 1
+_ACEOF
+
+fi
+
+ac_fn_c_check_member "$LINENO" "struct msghdr" "msg_accrightslen" "ac_cv_member_struct_msghdr_msg_accrightslen" "#include <sys/socket.h>
+"
+if test "x$ac_cv_member_struct_msghdr_msg_accrightslen" = xyes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_MSGHDR_ACCRIGHTSLEN 1
+_ACEOF
+
+fi
+
+
+# Checks for typedefs.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for uid_t in sys/types.h" >&5
+$as_echo_n "checking for uid_t in sys/types.h... " >&6; }
+if ${ac_cv_type_uid_t+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sys/types.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "uid_t" >/dev/null 2>&1; then :
+ ac_cv_type_uid_t=yes
+else
+ ac_cv_type_uid_t=no
+fi
+rm -f conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_uid_t" >&5
+$as_echo "$ac_cv_type_uid_t" >&6; }
+if test $ac_cv_type_uid_t = no; then
+
+$as_echo "#define uid_t int" >>confdefs.h
+
+
+$as_echo "#define gid_t int" >>confdefs.h
+
+fi
+
+ac_fn_c_find_intX_t "$LINENO" "16" "ac_cv_c_int16_t"
+case $ac_cv_c_int16_t in #(
+ no|yes) ;; #(
+ *)
+
+cat >>confdefs.h <<_ACEOF
+#define int16_t $ac_cv_c_int16_t
+_ACEOF
+;;
+esac
+
+ac_fn_c_find_intX_t "$LINENO" "32" "ac_cv_c_int32_t"
+case $ac_cv_c_int32_t in #(
+ no|yes) ;; #(
+ *)
+
+cat >>confdefs.h <<_ACEOF
+#define int32_t $ac_cv_c_int32_t
+_ACEOF
+;;
+esac
+
+ac_fn_c_find_intX_t "$LINENO" "64" "ac_cv_c_int64_t"
+case $ac_cv_c_int64_t in #(
+ no|yes) ;; #(
+ *)
+
+cat >>confdefs.h <<_ACEOF
+#define int64_t $ac_cv_c_int64_t
+_ACEOF
+;;
+esac
+
+ac_fn_c_find_intX_t "$LINENO" "8" "ac_cv_c_int8_t"
+case $ac_cv_c_int8_t in #(
+ no|yes) ;; #(
+ *)
+
+cat >>confdefs.h <<_ACEOF
+#define int8_t $ac_cv_c_int8_t
+_ACEOF
+;;
+esac
+
+ac_fn_c_find_uintX_t "$LINENO" "16" "ac_cv_c_uint16_t"
+case $ac_cv_c_uint16_t in #(
+ no|yes) ;; #(
+ *)
+
+
+cat >>confdefs.h <<_ACEOF
+#define uint16_t $ac_cv_c_uint16_t
+_ACEOF
+;;
+ esac
+
+ac_fn_c_find_uintX_t "$LINENO" "32" "ac_cv_c_uint32_t"
+case $ac_cv_c_uint32_t in #(
+ no|yes) ;; #(
+ *)
+
+$as_echo "#define _UINT32_T 1" >>confdefs.h
+
+
+cat >>confdefs.h <<_ACEOF
+#define uint32_t $ac_cv_c_uint32_t
+_ACEOF
+;;
+ esac
+
+ac_fn_c_find_uintX_t "$LINENO" "64" "ac_cv_c_uint64_t"
+case $ac_cv_c_uint64_t in #(
+ no|yes) ;; #(
+ *)
+
+$as_echo "#define _UINT64_T 1" >>confdefs.h
+
+
+cat >>confdefs.h <<_ACEOF
+#define uint64_t $ac_cv_c_uint64_t
+_ACEOF
+;;
+ esac
+
+ac_fn_c_find_uintX_t "$LINENO" "8" "ac_cv_c_uint8_t"
+case $ac_cv_c_uint8_t in #(
+ no|yes) ;; #(
+ *)
+
+$as_echo "#define _UINT8_T 1" >>confdefs.h
+
+
+cat >>confdefs.h <<_ACEOF
+#define uint8_t $ac_cv_c_uint8_t
+_ACEOF
+;;
+ esac
+
+ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default"
+if test "x$ac_cv_type_size_t" = xyes; then :
+
+else
+
+cat >>confdefs.h <<_ACEOF
+#define size_t unsigned int
+_ACEOF
+
+fi
+
+ac_fn_c_check_type "$LINENO" "ssize_t" "ac_cv_type_ssize_t" "$ac_includes_default"
+if test "x$ac_cv_type_ssize_t" = xyes; then :
+
+else
+
+cat >>confdefs.h <<_ACEOF
+#define ssize_t int
+_ACEOF
+
+fi
+
+
+# Checks for libraries.
+SAVE_CPPFLAGS="$CPPFLAGS"
+SAVE_LIBS="$LIBS"
+
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for LIBQB" >&5
+$as_echo_n "checking for LIBQB... " >&6; }
+
+if test -n "$LIBQB_CFLAGS"; then
+ pkg_cv_LIBQB_CFLAGS="$LIBQB_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libqb\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "libqb") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_LIBQB_CFLAGS=`$PKG_CONFIG --cflags "libqb" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+if test -n "$LIBQB_LIBS"; then
+ pkg_cv_LIBQB_LIBS="$LIBQB_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libqb\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "libqb") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_LIBQB_LIBS=`$PKG_CONFIG --libs "libqb" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+
+
+
+if test $pkg_failed = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+ _pkg_short_errors_supported=yes
+else
+ _pkg_short_errors_supported=no
+fi
+ if test $_pkg_short_errors_supported = yes; then
+ LIBQB_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libqb" 2>&1`
+ else
+ LIBQB_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libqb" 2>&1`
+ fi
+ # Put the nasty error message in config.log where it belongs
+ echo "$LIBQB_PKG_ERRORS" >&5
+
+ as_fn_error $? "Package requirements (libqb) were not met:
+
+$LIBQB_PKG_ERRORS
+
+Consider adjusting the PKG_CONFIG_PATH environment variable if you
+installed software in a non-standard prefix.
+
+Alternatively, you may set the environment variables LIBQB_CFLAGS
+and LIBQB_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details." "$LINENO" 5
+elif test $pkg_failed = untried; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it
+is in your PATH or set the PKG_CONFIG environment variable to the full
+path to pkg-config.
+
+Alternatively, you may set the environment variables LIBQB_CFLAGS
+and LIBQB_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details.
+
+To get pkg-config, see <http://pkg-config.freedesktop.org/>.
+See \`config.log' for more details" "$LINENO" 5; }
+else
+ LIBQB_CFLAGS=$pkg_cv_LIBQB_CFLAGS
+ LIBQB_LIBS=$pkg_cv_LIBQB_LIBS
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+fi
+CPPFLAGS="$CPPFLAGS $LIBQB_CFLAGS"
+LIBS="$LIBS $LIBQB_LIBS"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for qb_log_thread_priority_set in -lqb" >&5
+$as_echo_n "checking for qb_log_thread_priority_set in -lqb... " >&6; }
+if ${ac_cv_lib_qb_qb_log_thread_priority_set+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lqb $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char qb_log_thread_priority_set ();
+int
+main ()
+{
+return qb_log_thread_priority_set ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_qb_qb_log_thread_priority_set=yes
+else
+ ac_cv_lib_qb_qb_log_thread_priority_set=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_qb_qb_log_thread_priority_set" >&5
+$as_echo "$ac_cv_lib_qb_qb_log_thread_priority_set" >&6; }
+if test "x$ac_cv_lib_qb_qb_log_thread_priority_set" = xyes; then :
+ \
+ have_qb_log_thread_priority_set="yes"
+else
+ \
+ have_qb_log_thread_priority_set="no"
+fi
+
+if test "x${have_qb_log_thread_priority_set}" = xyes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_QB_LOG_THREAD_PRIORITY_SET 1
+_ACEOF
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for qb_log_file_reopen in -lqb" >&5
+$as_echo_n "checking for qb_log_file_reopen in -lqb... " >&6; }
+if ${ac_cv_lib_qb_qb_log_file_reopen+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lqb $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char qb_log_file_reopen ();
+int
+main ()
+{
+return qb_log_file_reopen ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_qb_qb_log_file_reopen=yes
+else
+ ac_cv_lib_qb_qb_log_file_reopen=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_qb_qb_log_file_reopen" >&5
+$as_echo "$ac_cv_lib_qb_qb_log_file_reopen" >&6; }
+if test "x$ac_cv_lib_qb_qb_log_file_reopen" = xyes; then :
+ \
+ have_qb_log_file_reopen="yes"
+else
+ \
+ have_qb_log_file_reopen="no"
+fi
+
+if test "x${have_qb_log_file_reopen}" = xyes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_QB_LOG_FILE_REOPEN 1
+_ACEOF
+
+fi
+ if test x$have_qb_log_file_reopen = xyes; then
+ HAVE_QB_LOG_FILE_REOPEN_TRUE=
+ HAVE_QB_LOG_FILE_REOPEN_FALSE='#'
+else
+ HAVE_QB_LOG_FILE_REOPEN_TRUE='#'
+ HAVE_QB_LOG_FILE_REOPEN_FALSE=
+fi
+
+
+CPPFLAGS="$SAVE_CPPFLAGS"
+LIBS="$SAVE_LIBS"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_create in -lpthread" >&5
+$as_echo_n "checking for pthread_create in -lpthread... " >&6; }
+if ${ac_cv_lib_pthread_pthread_create+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lpthread $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char pthread_create ();
+int
+main ()
+{
+return pthread_create ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_pthread_pthread_create=yes
+else
+ ac_cv_lib_pthread_pthread_create=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pthread_pthread_create" >&5
+$as_echo "$ac_cv_lib_pthread_pthread_create" >&6; }
+if test "x$ac_cv_lib_pthread_pthread_create" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBPTHREAD 1
+_ACEOF
+
+ LIBS="-lpthread $LIBS"
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for socket in -lsocket" >&5
+$as_echo_n "checking for socket in -lsocket... " >&6; }
+if ${ac_cv_lib_socket_socket+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsocket $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char socket ();
+int
+main ()
+{
+return socket ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_socket_socket=yes
+else
+ ac_cv_lib_socket_socket=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_socket" >&5
+$as_echo "$ac_cv_lib_socket_socket" >&6; }
+if test "x$ac_cv_lib_socket_socket" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBSOCKET 1
+_ACEOF
+
+ LIBS="-lsocket $LIBS"
+
+fi
+
+
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for knet" >&5
+$as_echo_n "checking for knet... " >&6; }
+
+if test -n "$knet_CFLAGS"; then
+ pkg_cv_knet_CFLAGS="$knet_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libknet\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "libknet") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_knet_CFLAGS=`$PKG_CONFIG --cflags "libknet" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+if test -n "$knet_LIBS"; then
+ pkg_cv_knet_LIBS="$knet_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libknet\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "libknet") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_knet_LIBS=`$PKG_CONFIG --libs "libknet" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+
+
+
+if test $pkg_failed = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+ _pkg_short_errors_supported=yes
+else
+ _pkg_short_errors_supported=no
+fi
+ if test $_pkg_short_errors_supported = yes; then
+ knet_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libknet" 2>&1`
+ else
+ knet_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libknet" 2>&1`
+ fi
+ # Put the nasty error message in config.log where it belongs
+ echo "$knet_PKG_ERRORS" >&5
+
+ as_fn_error $? "Package requirements (libknet) were not met:
+
+$knet_PKG_ERRORS
+
+Consider adjusting the PKG_CONFIG_PATH environment variable if you
+installed software in a non-standard prefix.
+
+Alternatively, you may set the environment variables knet_CFLAGS
+and knet_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details." "$LINENO" 5
+elif test $pkg_failed = untried; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it
+is in your PATH or set the PKG_CONFIG environment variable to the full
+path to pkg-config.
+
+Alternatively, you may set the environment variables knet_CFLAGS
+and knet_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details.
+
+To get pkg-config, see <http://pkg-config.freedesktop.org/>.
+See \`config.log' for more details" "$LINENO" 5; }
+else
+ knet_CFLAGS=$pkg_cv_knet_CFLAGS
+ knet_LIBS=$pkg_cv_knet_LIBS
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for t_open in -lnsl" >&5
+$as_echo_n "checking for t_open in -lnsl... " >&6; }
+if ${ac_cv_lib_nsl_t_open+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lnsl $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char t_open ();
+int
+main ()
+{
+return t_open ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_nsl_t_open=yes
+else
+ ac_cv_lib_nsl_t_open=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nsl_t_open" >&5
+$as_echo "$ac_cv_lib_nsl_t_open" >&6; }
+if test "x$ac_cv_lib_nsl_t_open" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBNSL 1
+_ACEOF
+
+ LIBS="-lnsl $LIBS"
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sched_getscheduler in -lrt" >&5
+$as_echo_n "checking for sched_getscheduler in -lrt... " >&6; }
+if ${ac_cv_lib_rt_sched_getscheduler+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lrt $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char sched_getscheduler ();
+int
+main ()
+{
+return sched_getscheduler ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_rt_sched_getscheduler=yes
+else
+ ac_cv_lib_rt_sched_getscheduler=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_rt_sched_getscheduler" >&5
+$as_echo "$ac_cv_lib_rt_sched_getscheduler" >&6; }
+if test "x$ac_cv_lib_rt_sched_getscheduler" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBRT 1
+_ACEOF
+
+ LIBS="-lrt $LIBS"
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for crc32 in -lz" >&5
+$as_echo_n "checking for crc32 in -lz... " >&6; }
+if ${ac_cv_lib_z_crc32+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lz $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char crc32 ();
+int
+main ()
+{
+return crc32 ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_z_crc32=yes
+else
+ ac_cv_lib_z_crc32=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_z_crc32" >&5
+$as_echo "$ac_cv_lib_z_crc32" >&6; }
+if test "x$ac_cv_lib_z_crc32" = xyes; then :
+ if true; then
+ HAVE_CRC32_TRUE=
+ HAVE_CRC32_FALSE='#'
+else
+ HAVE_CRC32_TRUE='#'
+ HAVE_CRC32_FALSE=
+fi
+
+else
+ if false; then
+ HAVE_CRC32_TRUE=
+ HAVE_CRC32_FALSE='#'
+else
+ HAVE_CRC32_TRUE='#'
+ HAVE_CRC32_FALSE=
+fi
+
+fi
+
+
+# this hack is necessary to check for symbols on out of tree builds
+# but it is as horrible as it gets and in theory users should be
+# invoking ./configure with proper LIBRARY_PATH set.
+OLDLIBS="$LIBS"
+LIBS="$knet_LIBS $LIBS"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for knet_handle_enable_access_lists in -lknet" >&5
+$as_echo_n "checking for knet_handle_enable_access_lists in -lknet... " >&6; }
+if ${ac_cv_lib_knet_knet_handle_enable_access_lists+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lknet $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char knet_handle_enable_access_lists ();
+int
+main ()
+{
+return knet_handle_enable_access_lists ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_knet_knet_handle_enable_access_lists=yes
+else
+ ac_cv_lib_knet_knet_handle_enable_access_lists=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_knet_knet_handle_enable_access_lists" >&5
+$as_echo "$ac_cv_lib_knet_knet_handle_enable_access_lists" >&6; }
+if test "x$ac_cv_lib_knet_knet_handle_enable_access_lists" = xyes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_KNET_ACCESS_LIST 1
+_ACEOF
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for knet_handle_crypto_set_config in -lknet" >&5
+$as_echo_n "checking for knet_handle_crypto_set_config in -lknet... " >&6; }
+if ${ac_cv_lib_knet_knet_handle_crypto_set_config+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lknet $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char knet_handle_crypto_set_config ();
+int
+main ()
+{
+return knet_handle_crypto_set_config ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_knet_knet_handle_crypto_set_config=yes
+else
+ ac_cv_lib_knet_knet_handle_crypto_set_config=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_knet_knet_handle_crypto_set_config" >&5
+$as_echo "$ac_cv_lib_knet_knet_handle_crypto_set_config" >&6; }
+if test "x$ac_cv_lib_knet_knet_handle_crypto_set_config" = xyes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_KNET_CRYPTO_RECONF 1
+_ACEOF
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for knet_handle_get_onwire_ver in -lknet" >&5
+$as_echo_n "checking for knet_handle_get_onwire_ver in -lknet... " >&6; }
+if ${ac_cv_lib_knet_knet_handle_get_onwire_ver+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lknet $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char knet_handle_get_onwire_ver ();
+int
+main ()
+{
+return knet_handle_get_onwire_ver ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_knet_knet_handle_get_onwire_ver=yes
+else
+ ac_cv_lib_knet_knet_handle_get_onwire_ver=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_knet_knet_handle_get_onwire_ver" >&5
+$as_echo "$ac_cv_lib_knet_knet_handle_get_onwire_ver" >&6; }
+if test "x$ac_cv_lib_knet_knet_handle_get_onwire_ver" = xyes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_KNET_ONWIRE_VER 1
+_ACEOF
+
+fi
+
+LIBS="$OLDLIBS"
+
+# Checks for library functions.
+# The Ultrix 4.2 mips builtin alloca declared by alloca.h only works
+# for constant arguments. Useless!
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for working alloca.h" >&5
+$as_echo_n "checking for working alloca.h... " >&6; }
+if ${ac_cv_working_alloca_h+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <alloca.h>
+int
+main ()
+{
+char *p = (char *) alloca (2 * sizeof (int));
+ if (p) return 0;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_working_alloca_h=yes
+else
+ ac_cv_working_alloca_h=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_working_alloca_h" >&5
+$as_echo "$ac_cv_working_alloca_h" >&6; }
+if test $ac_cv_working_alloca_h = yes; then
+
+$as_echo "#define HAVE_ALLOCA_H 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for alloca" >&5
+$as_echo_n "checking for alloca... " >&6; }
+if ${ac_cv_func_alloca_works+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#ifdef __GNUC__
+# define alloca __builtin_alloca
+#else
+# ifdef _MSC_VER
+# include <malloc.h>
+# define alloca _alloca
+# else
+# ifdef HAVE_ALLOCA_H
+# include <alloca.h>
+# else
+# ifdef _AIX
+ #pragma alloca
+# else
+# ifndef alloca /* predefined by HP cc +Olibcalls */
+void *alloca (size_t);
+# endif
+# endif
+# endif
+# endif
+#endif
+
+int
+main ()
+{
+char *p = (char *) alloca (1);
+ if (p) return 0;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_func_alloca_works=yes
+else
+ ac_cv_func_alloca_works=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_alloca_works" >&5
+$as_echo "$ac_cv_func_alloca_works" >&6; }
+
+if test $ac_cv_func_alloca_works = yes; then
+
+$as_echo "#define HAVE_ALLOCA 1" >>confdefs.h
+
+else
+ # The SVR3 libPW and SVR4 libucb both contain incompatible functions
+# that cause trouble. Some versions do not even contain alloca or
+# contain a buggy version. If you still want to use their alloca,
+# use ar to extract alloca.o from them instead of compiling alloca.c.
+
+ALLOCA=\${LIBOBJDIR}alloca.$ac_objext
+
+$as_echo "#define C_ALLOCA 1" >>confdefs.h
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether \`alloca.c' needs Cray hooks" >&5
+$as_echo_n "checking whether \`alloca.c' needs Cray hooks... " >&6; }
+if ${ac_cv_os_cray+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#if defined CRAY && ! defined CRAY2
+webecray
+#else
+wenotbecray
+#endif
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "webecray" >/dev/null 2>&1; then :
+ ac_cv_os_cray=yes
+else
+ ac_cv_os_cray=no
+fi
+rm -f conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_os_cray" >&5
+$as_echo "$ac_cv_os_cray" >&6; }
+if test $ac_cv_os_cray = yes; then
+ for ac_func in _getb67 GETB67 getb67; do
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+
+cat >>confdefs.h <<_ACEOF
+#define CRAY_STACKSEG_END $ac_func
+_ACEOF
+
+ break
+fi
+
+ done
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking stack direction for C alloca" >&5
+$as_echo_n "checking stack direction for C alloca... " >&6; }
+if ${ac_cv_c_stack_direction+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "$cross_compiling" = yes; then :
+ ac_cv_c_stack_direction=0
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$ac_includes_default
+int
+find_stack_direction (int *addr, int depth)
+{
+ int dir, dummy = 0;
+ if (! addr)
+ addr = &dummy;
+ *addr = addr < &dummy ? 1 : addr == &dummy ? 0 : -1;
+ dir = depth ? find_stack_direction (addr, depth - 1) : 0;
+ return dir + dummy;
+}
+
+int
+main (int argc, char **argv)
+{
+ return find_stack_direction (0, argc + !argv + 20) < 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+ ac_cv_c_stack_direction=1
+else
+ ac_cv_c_stack_direction=-1
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_stack_direction" >&5
+$as_echo "$ac_cv_c_stack_direction" >&6; }
+cat >>confdefs.h <<_ACEOF
+#define STACK_DIRECTION $ac_cv_c_stack_direction
+_ACEOF
+
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether closedir returns void" >&5
+$as_echo_n "checking whether closedir returns void... " >&6; }
+if ${ac_cv_func_closedir_void+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "$cross_compiling" = yes; then :
+ ac_cv_func_closedir_void=yes
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$ac_includes_default
+#include <$ac_header_dirent>
+#ifndef __cplusplus
+int closedir ();
+#endif
+
+int
+main ()
+{
+return closedir (opendir (".")) != 0;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+ ac_cv_func_closedir_void=no
+else
+ ac_cv_func_closedir_void=yes
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_closedir_void" >&5
+$as_echo "$ac_cv_func_closedir_void" >&6; }
+if test $ac_cv_func_closedir_void = yes; then
+
+$as_echo "#define CLOSEDIR_VOID 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for error_at_line" >&5
+$as_echo_n "checking for error_at_line... " >&6; }
+if ${ac_cv_lib_error_at_line+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <error.h>
+int
+main ()
+{
+error_at_line (0, 0, "", 0, "an error occurred");
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_error_at_line=yes
+else
+ ac_cv_lib_error_at_line=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_error_at_line" >&5
+$as_echo "$ac_cv_lib_error_at_line" >&6; }
+if test $ac_cv_lib_error_at_line = no; then
+ case " $LIBOBJS " in
+ *" error.$ac_objext "* ) ;;
+ *) LIBOBJS="$LIBOBJS error.$ac_objext"
+ ;;
+esac
+
+fi
+
+ac_fn_c_check_type "$LINENO" "pid_t" "ac_cv_type_pid_t" "$ac_includes_default"
+if test "x$ac_cv_type_pid_t" = xyes; then :
+
+else
+
+cat >>confdefs.h <<_ACEOF
+#define pid_t int
+_ACEOF
+
+fi
+
+for ac_header in vfork.h
+do :
+ ac_fn_c_check_header_mongrel "$LINENO" "vfork.h" "ac_cv_header_vfork_h" "$ac_includes_default"
+if test "x$ac_cv_header_vfork_h" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_VFORK_H 1
+_ACEOF
+
+fi
+
+done
+
+for ac_func in fork vfork
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+if test "x$ac_cv_func_fork" = xyes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working fork" >&5
+$as_echo_n "checking for working fork... " >&6; }
+if ${ac_cv_func_fork_works+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "$cross_compiling" = yes; then :
+ ac_cv_func_fork_works=cross
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+
+ /* By Ruediger Kuhlmann. */
+ return fork () < 0;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+ ac_cv_func_fork_works=yes
+else
+ ac_cv_func_fork_works=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_fork_works" >&5
+$as_echo "$ac_cv_func_fork_works" >&6; }
+
+else
+ ac_cv_func_fork_works=$ac_cv_func_fork
+fi
+if test "x$ac_cv_func_fork_works" = xcross; then
+ case $host in
+ *-*-amigaos* | *-*-msdosdjgpp*)
+ # Override, as these systems have only a dummy fork() stub
+ ac_cv_func_fork_works=no
+ ;;
+ *)
+ ac_cv_func_fork_works=yes
+ ;;
+ esac
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: result $ac_cv_func_fork_works guessed because of cross compilation" >&5
+$as_echo "$as_me: WARNING: result $ac_cv_func_fork_works guessed because of cross compilation" >&2;}
+fi
+ac_cv_func_vfork_works=$ac_cv_func_vfork
+if test "x$ac_cv_func_vfork" = xyes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working vfork" >&5
+$as_echo_n "checking for working vfork... " >&6; }
+if ${ac_cv_func_vfork_works+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "$cross_compiling" = yes; then :
+ ac_cv_func_vfork_works=cross
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+/* Thanks to Paul Eggert for this test. */
+$ac_includes_default
+#include <sys/wait.h>
+#ifdef HAVE_VFORK_H
+# include <vfork.h>
+#endif
+/* On some sparc systems, changes by the child to local and incoming
+ argument registers are propagated back to the parent. The compiler
+ is told about this with #include <vfork.h>, but some compilers
+ (e.g. gcc -O) don't grok <vfork.h>. Test for this by using a
+ static variable whose address is put into a register that is
+ clobbered by the vfork. */
+static void
+#ifdef __cplusplus
+sparc_address_test (int arg)
+# else
+sparc_address_test (arg) int arg;
+#endif
+{
+ static pid_t child;
+ if (!child) {
+ child = vfork ();
+ if (child < 0) {
+ perror ("vfork");
+ _exit(2);
+ }
+ if (!child) {
+ arg = getpid();
+ write(-1, "", 0);
+ _exit (arg);
+ }
+ }
+}
+
+int
+main ()
+{
+ pid_t parent = getpid ();
+ pid_t child;
+
+ sparc_address_test (0);
+
+ child = vfork ();
+
+ if (child == 0) {
+ /* Here is another test for sparc vfork register problems. This
+ test uses lots of local variables, at least as many local
+ variables as main has allocated so far including compiler
+ temporaries. 4 locals are enough for gcc 1.40.3 on a Solaris
+ 4.1.3 sparc, but we use 8 to be safe. A buggy compiler should
+ reuse the register of parent for one of the local variables,
+ since it will think that parent can't possibly be used any more
+ in this routine. Assigning to the local variable will thus
+ munge parent in the parent process. */
+ pid_t
+ p = getpid(), p1 = getpid(), p2 = getpid(), p3 = getpid(),
+ p4 = getpid(), p5 = getpid(), p6 = getpid(), p7 = getpid();
+ /* Convince the compiler that p..p7 are live; otherwise, it might
+ use the same hardware register for all 8 local variables. */
+ if (p != p1 || p != p2 || p != p3 || p != p4
+ || p != p5 || p != p6 || p != p7)
+ _exit(1);
+
+ /* On some systems (e.g. IRIX 3.3), vfork doesn't separate parent
+ from child file descriptors. If the child closes a descriptor
+ before it execs or exits, this munges the parent's descriptor
+ as well. Test for this by closing stdout in the child. */
+ _exit(close(fileno(stdout)) != 0);
+ } else {
+ int status;
+ struct stat st;
+
+ while (wait(&status) != child)
+ ;
+ return (
+ /* Was there some problem with vforking? */
+ child < 0
+
+ /* Did the child fail? (This shouldn't happen.) */
+ || status
+
+ /* Did the vfork/compiler bug occur? */
+ || parent != getpid()
+
+ /* Did the file descriptor bug occur? */
+ || fstat(fileno(stdout), &st) != 0
+ );
+ }
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+ ac_cv_func_vfork_works=yes
+else
+ ac_cv_func_vfork_works=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_vfork_works" >&5
+$as_echo "$ac_cv_func_vfork_works" >&6; }
+
+fi;
+if test "x$ac_cv_func_fork_works" = xcross; then
+ ac_cv_func_vfork_works=$ac_cv_func_vfork
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: result $ac_cv_func_vfork_works guessed because of cross compilation" >&5
+$as_echo "$as_me: WARNING: result $ac_cv_func_vfork_works guessed because of cross compilation" >&2;}
+fi
+
+if test "x$ac_cv_func_vfork_works" = xyes; then
+
+$as_echo "#define HAVE_WORKING_VFORK 1" >>confdefs.h
+
+else
+
+$as_echo "#define vfork fork" >>confdefs.h
+
+fi
+if test "x$ac_cv_func_fork_works" = xyes; then
+
+$as_echo "#define HAVE_WORKING_FORK 1" >>confdefs.h
+
+fi
+
+for ac_header in stdlib.h
+do :
+ ac_fn_c_check_header_mongrel "$LINENO" "stdlib.h" "ac_cv_header_stdlib_h" "$ac_includes_default"
+if test "x$ac_cv_header_stdlib_h" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_STDLIB_H 1
+_ACEOF
+
+fi
+
+done
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU libc compatible malloc" >&5
+$as_echo_n "checking for GNU libc compatible malloc... " >&6; }
+if ${ac_cv_func_malloc_0_nonnull+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "$cross_compiling" = yes; then :
+ ac_cv_func_malloc_0_nonnull=no
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#if defined STDC_HEADERS || defined HAVE_STDLIB_H
+# include <stdlib.h>
+#else
+char *malloc ();
+#endif
+
+int
+main ()
+{
+return ! malloc (0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+ ac_cv_func_malloc_0_nonnull=yes
+else
+ ac_cv_func_malloc_0_nonnull=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_malloc_0_nonnull" >&5
+$as_echo "$ac_cv_func_malloc_0_nonnull" >&6; }
+if test $ac_cv_func_malloc_0_nonnull = yes; then :
+
+$as_echo "#define HAVE_MALLOC 1" >>confdefs.h
+
+else
+ $as_echo "#define HAVE_MALLOC 0" >>confdefs.h
+
+ case " $LIBOBJS " in
+ *" malloc.$ac_objext "* ) ;;
+ *) LIBOBJS="$LIBOBJS malloc.$ac_objext"
+ ;;
+esac
+
+
+$as_echo "#define malloc rpl_malloc" >>confdefs.h
+
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for working memcmp" >&5
+$as_echo_n "checking for working memcmp... " >&6; }
+if ${ac_cv_func_memcmp_working+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "$cross_compiling" = yes; then :
+ ac_cv_func_memcmp_working=no
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+
+ /* Some versions of memcmp are not 8-bit clean. */
+ char c0 = '\100', c1 = '\200', c2 = '\201';
+ if (memcmp(&c0, &c2, 1) >= 0 || memcmp(&c1, &c2, 1) >= 0)
+ return 1;
+
+ /* The Next x86 OpenStep bug shows up only when comparing 16 bytes
+ or more and with at least one buffer not starting on a 4-byte boundary.
+ William Lewis provided this test program. */
+ {
+ char foo[21];
+ char bar[21];
+ int i;
+ for (i = 0; i < 4; i++)
+ {
+ char *a = foo + i;
+ char *b = bar + i;
+ strcpy (a, "--------01111111");
+ strcpy (b, "--------10000000");
+ if (memcmp (a, b, 16) >= 0)
+ return 1;
+ }
+ return 0;
+ }
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+ ac_cv_func_memcmp_working=yes
+else
+ ac_cv_func_memcmp_working=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_memcmp_working" >&5
+$as_echo "$ac_cv_func_memcmp_working" >&6; }
+test $ac_cv_func_memcmp_working = no && case " $LIBOBJS " in
+ *" memcmp.$ac_objext "* ) ;;
+ *) LIBOBJS="$LIBOBJS memcmp.$ac_objext"
+ ;;
+esac
+
+
+
+
+
+ for ac_header in $ac_header_list
+do :
+ as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
+"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+
+
+
+
+
+
+for ac_func in getpagesize
+do :
+ ac_fn_c_check_func "$LINENO" "getpagesize" "ac_cv_func_getpagesize"
+if test "x$ac_cv_func_getpagesize" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_GETPAGESIZE 1
+_ACEOF
+
+fi
+done
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for working mmap" >&5
+$as_echo_n "checking for working mmap... " >&6; }
+if ${ac_cv_func_mmap_fixed_mapped+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "$cross_compiling" = yes; then :
+ ac_cv_func_mmap_fixed_mapped=no
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$ac_includes_default
+/* malloc might have been renamed as rpl_malloc. */
+#undef malloc
+
+/* Thanks to Mike Haertel and Jim Avera for this test.
+ Here is a matrix of mmap possibilities:
+ mmap private not fixed
+ mmap private fixed at somewhere currently unmapped
+ mmap private fixed at somewhere already mapped
+ mmap shared not fixed
+ mmap shared fixed at somewhere currently unmapped
+ mmap shared fixed at somewhere already mapped
+ For private mappings, we should verify that changes cannot be read()
+ back from the file, nor mmap's back from the file at a different
+ address. (There have been systems where private was not correctly
+ implemented like the infamous i386 svr4.0, and systems where the
+ VM page cache was not coherent with the file system buffer cache
+ like early versions of FreeBSD and possibly contemporary NetBSD.)
+ For shared mappings, we should conversely verify that changes get
+ propagated back to all the places they're supposed to be.
+
+ Grep wants private fixed already mapped.
+ The main things grep needs to know about mmap are:
+ * does it exist and is it safe to write into the mmap'd area
+ * how to use it (BSD variants) */
+
+#include <fcntl.h>
+#include <sys/mman.h>
+
+#if !defined STDC_HEADERS && !defined HAVE_STDLIB_H
+char *malloc ();
+#endif
+
+/* This mess was copied from the GNU getpagesize.h. */
+#ifndef HAVE_GETPAGESIZE
+# ifdef _SC_PAGESIZE
+# define getpagesize() sysconf(_SC_PAGESIZE)
+# else /* no _SC_PAGESIZE */
+# ifdef HAVE_SYS_PARAM_H
+# include <sys/param.h>
+# ifdef EXEC_PAGESIZE
+# define getpagesize() EXEC_PAGESIZE
+# else /* no EXEC_PAGESIZE */
+# ifdef NBPG
+# define getpagesize() NBPG * CLSIZE
+# ifndef CLSIZE
+# define CLSIZE 1
+# endif /* no CLSIZE */
+# else /* no NBPG */
+# ifdef NBPC
+# define getpagesize() NBPC
+# else /* no NBPC */
+# ifdef PAGESIZE
+# define getpagesize() PAGESIZE
+# endif /* PAGESIZE */
+# endif /* no NBPC */
+# endif /* no NBPG */
+# endif /* no EXEC_PAGESIZE */
+# else /* no HAVE_SYS_PARAM_H */
+# define getpagesize() 8192 /* punt totally */
+# endif /* no HAVE_SYS_PARAM_H */
+# endif /* no _SC_PAGESIZE */
+
+#endif /* no HAVE_GETPAGESIZE */
+
+int
+main ()
+{
+ char *data, *data2, *data3;
+ const char *cdata2;
+ int i, pagesize;
+ int fd, fd2;
+
+ pagesize = getpagesize ();
+
+ /* First, make a file with some known garbage in it. */
+ data = (char *) malloc (pagesize);
+ if (!data)
+ return 1;
+ for (i = 0; i < pagesize; ++i)
+ *(data + i) = rand ();
+ umask (0);
+ fd = creat ("conftest.mmap", 0600);
+ if (fd < 0)
+ return 2;
+ if (write (fd, data, pagesize) != pagesize)
+ return 3;
+ close (fd);
+
+ /* Next, check that the tail of a page is zero-filled. File must have
+ non-zero length, otherwise we risk SIGBUS for entire page. */
+ fd2 = open ("conftest.txt", O_RDWR | O_CREAT | O_TRUNC, 0600);
+ if (fd2 < 0)
+ return 4;
+ cdata2 = "";
+ if (write (fd2, cdata2, 1) != 1)
+ return 5;
+ data2 = (char *) mmap (0, pagesize, PROT_READ | PROT_WRITE, MAP_SHARED, fd2, 0L);
+ if (data2 == MAP_FAILED)
+ return 6;
+ for (i = 0; i < pagesize; ++i)
+ if (*(data2 + i))
+ return 7;
+ close (fd2);
+ if (munmap (data2, pagesize))
+ return 8;
+
+ /* Next, try to mmap the file at a fixed address which already has
+ something else allocated at it. If we can, also make sure that
+ we see the same garbage. */
+ fd = open ("conftest.mmap", O_RDWR);
+ if (fd < 0)
+ return 9;
+ if (data2 != mmap (data2, pagesize, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_FIXED, fd, 0L))
+ return 10;
+ for (i = 0; i < pagesize; ++i)
+ if (*(data + i) != *(data2 + i))
+ return 11;
+
+ /* Finally, make sure that changes to the mapped area do not
+ percolate back to the file as seen by read(). (This is a bug on
+ some variants of i386 svr4.0.) */
+ for (i = 0; i < pagesize; ++i)
+ *(data2 + i) = *(data2 + i) + 1;
+ data3 = (char *) malloc (pagesize);
+ if (!data3)
+ return 12;
+ if (read (fd, data3, pagesize) != pagesize)
+ return 13;
+ for (i = 0; i < pagesize; ++i)
+ if (*(data + i) != *(data3 + i))
+ return 14;
+ close (fd);
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+ ac_cv_func_mmap_fixed_mapped=yes
+else
+ ac_cv_func_mmap_fixed_mapped=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_mmap_fixed_mapped" >&5
+$as_echo "$ac_cv_func_mmap_fixed_mapped" >&6; }
+if test $ac_cv_func_mmap_fixed_mapped = yes; then
+
+$as_echo "#define HAVE_MMAP 1" >>confdefs.h
+
+fi
+rm -f conftest.mmap conftest.txt
+
+for ac_header in stdlib.h
+do :
+ ac_fn_c_check_header_mongrel "$LINENO" "stdlib.h" "ac_cv_header_stdlib_h" "$ac_includes_default"
+if test "x$ac_cv_header_stdlib_h" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_STDLIB_H 1
+_ACEOF
+
+fi
+
+done
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU libc compatible realloc" >&5
+$as_echo_n "checking for GNU libc compatible realloc... " >&6; }
+if ${ac_cv_func_realloc_0_nonnull+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "$cross_compiling" = yes; then :
+ ac_cv_func_realloc_0_nonnull=no
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#if defined STDC_HEADERS || defined HAVE_STDLIB_H
+# include <stdlib.h>
+#else
+char *realloc ();
+#endif
+
+int
+main ()
+{
+return ! realloc (0, 0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+ ac_cv_func_realloc_0_nonnull=yes
+else
+ ac_cv_func_realloc_0_nonnull=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_realloc_0_nonnull" >&5
+$as_echo "$ac_cv_func_realloc_0_nonnull" >&6; }
+if test $ac_cv_func_realloc_0_nonnull = yes; then :
+
+$as_echo "#define HAVE_REALLOC 1" >>confdefs.h
+
+else
+ $as_echo "#define HAVE_REALLOC 0" >>confdefs.h
+
+ case " $LIBOBJS " in
+ *" realloc.$ac_objext "* ) ;;
+ *) LIBOBJS="$LIBOBJS realloc.$ac_objext"
+ ;;
+esac
+
+
+$as_echo "#define realloc rpl_realloc" >>confdefs.h
+
+fi
+
+
+for ac_header in sys/select.h sys/socket.h
+do :
+ as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking types of arguments for select" >&5
+$as_echo_n "checking types of arguments for select... " >&6; }
+if ${ac_cv_func_select_args+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ for ac_arg234 in 'fd_set *' 'int *' 'void *'; do
+ for ac_arg1 in 'int' 'size_t' 'unsigned long int' 'unsigned int'; do
+ for ac_arg5 in 'struct timeval *' 'const struct timeval *'; do
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$ac_includes_default
+#ifdef HAVE_SYS_SELECT_H
+# include <sys/select.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+# include <sys/socket.h>
+#endif
+
+int
+main ()
+{
+extern int select ($ac_arg1,
+ $ac_arg234, $ac_arg234, $ac_arg234,
+ $ac_arg5);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_func_select_args="$ac_arg1,$ac_arg234,$ac_arg5"; break 3
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ done
+ done
+done
+# Provide a safe default value.
+: "${ac_cv_func_select_args=int,int *,struct timeval *}"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_select_args" >&5
+$as_echo "$ac_cv_func_select_args" >&6; }
+ac_save_IFS=$IFS; IFS=','
+set dummy `echo "$ac_cv_func_select_args" | sed 's/\*/\*/g'`
+IFS=$ac_save_IFS
+shift
+
+cat >>confdefs.h <<_ACEOF
+#define SELECT_TYPE_ARG1 $1
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define SELECT_TYPE_ARG234 ($2)
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define SELECT_TYPE_ARG5 ($3)
+_ACEOF
+
+rm -f conftest*
+
+for ac_func in vprintf
+do :
+ ac_fn_c_check_func "$LINENO" "vprintf" "ac_cv_func_vprintf"
+if test "x$ac_cv_func_vprintf" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_VPRINTF 1
+_ACEOF
+
+ac_fn_c_check_func "$LINENO" "_doprnt" "ac_cv_func__doprnt"
+if test "x$ac_cv_func__doprnt" = xyes; then :
+
+$as_echo "#define HAVE_DOPRNT 1" >>confdefs.h
+
+fi
+
+fi
+done
+
+
+
+for ac_func in alarm alphasort atexit bzero dup2 endgrent endpwent fdatasync \
+ fcntl getcwd getpeerucred getpeereid gettimeofday inet_ntoa \
+ memmove memset mkdir scandir select socket strcasecmp strchr \
+ strdup strerror strrchr strspn strstr pthread_setschedparam \
+ sched_get_priority_max sched_setscheduler getifaddrs \
+ clock_gettime ftruncate gethostname localtime_r munmap strtol
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
+ac_config_files="$ac_config_files Makefile exec/Makefile include/Makefile init/Makefile lib/Makefile common_lib/Makefile man/Makefile pkgconfig/Makefile test/Makefile tools/Makefile conf/Makefile vqsim/Makefile Doxyfile conf/logrotate/Makefile bindings/Makefile bindings/rust/Makefile bindings/rust/tests/Makefile bindings/rust/Cargo.toml bindings/rust/tests/Cargo.toml"
+
+
+### Local business
+
+# check for rust tools to build bindings
+if test "x$enable_rust_bindings" = "xyes"; then
+ # Extract the first word of "cargo", so it can be a program name with args.
+set dummy cargo; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_CARGO+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $CARGO in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_CARGO="$CARGO" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_CARGO="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ test -z "$ac_cv_path_CARGO" && ac_cv_path_CARGO="no"
+ ;;
+esac
+fi
+CARGO=$ac_cv_path_CARGO
+if test -n "$CARGO"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CARGO" >&5
+$as_echo "$CARGO" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ if test "x$CARGO" = xno; then
+ as_fn_error $? "\"cargo command not found\"" "$LINENO" 5
+ fi
+
+ # Extract the first word of "rustc", so it can be a program name with args.
+set dummy rustc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_RUSTC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $RUSTC in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_RUSTC="$RUSTC" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_RUSTC="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ test -z "$ac_cv_path_RUSTC" && ac_cv_path_RUSTC="no"
+ ;;
+esac
+fi
+RUSTC=$ac_cv_path_RUSTC
+if test -n "$RUSTC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RUSTC" >&5
+$as_echo "$RUSTC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ if test "x$RUSTC" = xno; then
+ as_fn_error $? "\"rustc command not found\"" "$LINENO" 5
+ fi
+
+ # Extract the first word of "rustdoc", so it can be a program name with args.
+set dummy rustdoc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_RUSTDOC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $RUSTDOC in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_RUSTDOC="$RUSTDOC" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_RUSTDOC="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ test -z "$ac_cv_path_RUSTDOC" && ac_cv_path_RUSTDOC="no"
+ ;;
+esac
+fi
+RUSTDOC=$ac_cv_path_RUSTDOC
+if test -n "$RUSTDOC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RUSTDOC" >&5
+$as_echo "$RUSTDOC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ if test "x$RUSTDOC" = xno; then
+ as_fn_error $? "\"rustdoc command not found\"" "$LINENO" 5
+ fi
+
+ # Extract the first word of "bindgen", so it can be a program name with args.
+set dummy bindgen; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_BINDGEN+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $BINDGEN in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_BINDGEN="$BINDGEN" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_BINDGEN="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ test -z "$ac_cv_path_BINDGEN" && ac_cv_path_BINDGEN="no"
+ ;;
+esac
+fi
+BINDGEN=$ac_cv_path_BINDGEN
+if test -n "$BINDGEN"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $BINDGEN" >&5
+$as_echo "$BINDGEN" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ if test "x$BINDGEN" = xno; then
+ as_fn_error $? "\"bindgen command not found\"" "$LINENO" 5
+ fi
+
+ # Extract the first word of "clippy-driver", so it can be a program name with args.
+set dummy clippy-driver; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_CLIPPY+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $CLIPPY in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_CLIPPY="$CLIPPY" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_CLIPPY="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ test -z "$ac_cv_path_CLIPPY" && ac_cv_path_CLIPPY="no"
+ ;;
+esac
+fi
+CLIPPY=$ac_cv_path_CLIPPY
+if test -n "$CLIPPY"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CLIPPY" >&5
+$as_echo "$CLIPPY" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ if test "x$CLIPPY" = xno; then
+ as_fn_error $? "\"clippy-driver command not found\"" "$LINENO" 5
+ fi
+
+ # Extract the first word of "rustfmt", so it can be a program name with args.
+set dummy rustfmt; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_RUSTFMT+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $RUSTFMT in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_RUSTFMT="$RUSTFMT" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_RUSTFMT="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ test -z "$ac_cv_path_RUSTFMT" && ac_cv_path_RUSTFMT="no"
+ ;;
+esac
+fi
+RUSTFMT=$ac_cv_path_RUSTFMT
+if test -n "$RUSTFMT"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RUSTFMT" >&5
+$as_echo "$RUSTFMT" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ if test "x$RUSTFMT" = xno; then
+ as_fn_error $? "\"rustfmt command not found\"" "$LINENO" 5
+ fi
+fi
+
+
+
+
+
+
+# ===============================================
+# Helpers
+# ===============================================
+
+## check if the compiler supports -Werror -Wunknown-warning-option
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC supports -Wunknown-warning-option -Werror" >&5
+$as_echo_n "checking whether $CC supports -Wunknown-warning-option -Werror... " >&6; }
+BACKUP="$CPPFLAGS"
+CPPFLAGS="$CPPFLAGS -Werror -Wunknown-warning-option"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ unknown_warnings_as_errors='-Wunknown-warning-option -Werror'; { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+ unknown_warnings_as_errors=''; { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+CPPFLAGS="$BACKUP"
+
+## helper for CC stuff
+cc_supports_flag() {
+ BACKUP="$CPPFLAGS"
+ CPPFLAGS="$CPPFLAGS $@ $unknown_warnings_as_errors"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC supports \"$@\"" >&5
+$as_echo_n "checking whether $CC supports \"$@\"... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ RC=0; { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+ RC=1; { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ CPPFLAGS="$BACKUP"
+ return $RC
+}
+
+## local defines
+PACKAGE_FEATURES=""
+
+LINT_FLAGS="-weak -unrecog +posixlib +ignoresigns -fcnuse \
+ -badflag -D__gnuc_va_list=va_list -D__attribute\(x\)="
+
+# default libraries SONAME
+SOMAJOR="5"
+SOMINOR="0"
+SOMICRO="0"
+SONAME="${SOMAJOR}.${SOMINOR}.${SOMICRO}"
+
+# specific libraries SONAME
+CFG_SONAME="7.3.0"
+CPG_SONAME="4.1.0"
+QUORUM_SONAME="5.1.0"
+SAM_SONAME="4.4.0"
+VOTEQUORUM_SONAME="8.0.0"
+CMAP_SONAME="4.1.0"
+
+# local options
+# Check whether --enable-ansi was given.
+if test "${enable_ansi+set}" = set; then :
+ enableval=$enable_ansi; default="no"
+fi
+
+
+# Check whether --enable-fatal-warnings was given.
+if test "${enable_fatal_warnings+set}" = set; then :
+ enableval=$enable_fatal_warnings; default="no"
+fi
+
+
+# Check whether --enable-debug was given.
+if test "${enable_debug+set}" = set; then :
+ enableval=$enable_debug; default="no"
+fi
+
+
+
+# Check whether --with-sanitizers was given.
+if test "${with_sanitizers+set}" = set; then :
+ withval=$with_sanitizers; SANITIZERS="$withval"
+else
+ SANITIZERS=""
+fi
+
+
+# Check whether --enable-secure-build was given.
+if test "${enable_secure_build+set}" = set; then :
+ enableval=$enable_secure_build;
+else
+ enable_secure_build="yes"
+fi
+
+
+# Check whether --enable-user-flags was given.
+if test "${enable_user_flags+set}" = set; then :
+ enableval=$enable_user_flags; default="no"
+fi
+
+
+# Check whether --enable-coverage was given.
+if test "${enable_coverage+set}" = set; then :
+ enableval=$enable_coverage; default="no"
+fi
+
+
+# Check whether --enable-small-memory-footprint was given.
+if test "${enable_small_memory_footprint+set}" = set; then :
+ enableval=$enable_small_memory_footprint; default="no"
+fi
+
+
+# Check whether --enable-dbus was given.
+if test "${enable_dbus+set}" = set; then :
+ enableval=$enable_dbus;
+else
+ enable_dbus="no"
+fi
+
+
+# Check whether --enable-monitoring was given.
+if test "${enable_monitoring+set}" = set; then :
+ enableval=$enable_monitoring;
+else
+ default="no"
+fi
+
+ if test x$enable_monitoring = xyes; then
+ BUILD_MONITORING_TRUE=
+ BUILD_MONITORING_FALSE='#'
+else
+ BUILD_MONITORING_TRUE='#'
+ BUILD_MONITORING_FALSE=
+fi
+
+
+# Check whether --enable-watchdog was given.
+if test "${enable_watchdog+set}" = set; then :
+ enableval=$enable_watchdog;
+else
+ default="no"
+fi
+
+ if test x$enable_watchdog = xyes; then
+ BUILD_WATCHDOG_TRUE=
+ BUILD_WATCHDOG_FALSE='#'
+else
+ BUILD_WATCHDOG_TRUE='#'
+ BUILD_WATCHDOG_FALSE=
+fi
+
+
+# Check whether --enable-augeas was given.
+if test "${enable_augeas+set}" = set; then :
+ enableval=$enable_augeas;
+else
+ enable_augeas="no"
+fi
+
+ if test x$enable_augeas = xyes; then
+ INSTALL_AUGEAS_TRUE=
+ INSTALL_AUGEAS_FALSE='#'
+else
+ INSTALL_AUGEAS_TRUE='#'
+ INSTALL_AUGEAS_FALSE=
+fi
+
+
+# Check whether --enable-systemd was given.
+if test "${enable_systemd+set}" = set; then :
+ enableval=$enable_systemd;
+else
+ enable_systemd="no"
+fi
+
+ if test x$enable_systemd = xyes; then
+ INSTALL_SYSTEMD_TRUE=
+ INSTALL_SYSTEMD_FALSE='#'
+else
+ INSTALL_SYSTEMD_TRUE='#'
+ INSTALL_SYSTEMD_FALSE=
+fi
+
+
+
+# Check whether --with-initconfigdir was given.
+if test "${with_initconfigdir+set}" = set; then :
+ withval=$with_initconfigdir; INITCONFIGDIR="$withval"
+else
+ INITCONFIGDIR='${sysconfdir}/sysconfig'
+fi
+
+
+
+
+# Check whether --with-initddir was given.
+if test "${with_initddir+set}" = set; then :
+ withval=$with_initddir; INITDDIR="$withval"
+else
+ INITDDIR="$sysconfdir/init.d"
+fi
+
+
+
+# Check whether --with-systemddir was given.
+if test "${with_systemddir+set}" = set; then :
+ withval=$with_systemddir; SYSTEMDDIR="$withval"
+else
+ SYSTEMDDIR="$systemddir"
+fi
+
+
+
+# Check whether --with-logdir was given.
+if test "${with_logdir+set}" = set; then :
+ withval=$with_logdir; LOGDIR="$withval"
+else
+ LOGDIR="$localstatedir/log/cluster"
+fi
+
+
+
+# Check whether --with-logrotatedir was given.
+if test "${with_logrotatedir+set}" = set; then :
+ withval=$with_logrotatedir; LOGROTATEDIR="$withval"
+else
+ LOGROTATEDIR="$sysconfdir/logrotate.d"
+fi
+
+
+# Check whether --enable-snmp was given.
+if test "${enable_snmp+set}" = set; then :
+ enableval=$enable_snmp; default="no"
+fi
+
+
+# Check whether --enable-xmlconf was given.
+if test "${enable_xmlconf+set}" = set; then :
+ enableval=$enable_xmlconf;
+else
+ enable_xmlconf="no"
+fi
+
+ if test x$enable_xmlconf = xyes; then
+ INSTALL_XMLCONF_TRUE=
+ INSTALL_XMLCONF_FALSE='#'
+else
+ INSTALL_XMLCONF_TRUE='#'
+ INSTALL_XMLCONF_FALSE=
+fi
+
+
+# Check whether --enable-vqsim was given.
+if test "${enable_vqsim+set}" = set; then :
+ enableval=$enable_vqsim;
+else
+ enable_vqsim="no"
+fi
+
+ if test x$enable_vqsim = xyes; then
+ BUILD_VQSIM_TRUE=
+ BUILD_VQSIM_FALSE='#'
+else
+ BUILD_VQSIM_TRUE='#'
+ BUILD_VQSIM_FALSE=
+fi
+
+
+# Check whether --enable-nozzle was given.
+if test "${enable_nozzle+set}" = set; then :
+ enableval=$enable_nozzle;
+else
+ enable_nozzle="no"
+fi
+
+
+# *FLAGS handling goes here
+
+ENV_CFLAGS="$CFLAGS"
+ENV_CPPFLAGS="$CPPFLAGS"
+ENV_LDFLAGS="$LDFLAGS"
+
+# debug build stuff
+if test "x${enable_debug}" = xyes; then
+
+cat >>confdefs.h <<_ACEOF
+#define DEBUG 1
+_ACEOF
+
+ OPT_CFLAGS="-O0"
+ PACKAGE_FEATURES="$PACKAGE_FEATURES debug"
+ RUST_FLAGS=""
+ RUST_TARGET_DIR="debug"
+else
+ OPT_CFLAGS="-O3"
+ RUST_FLAGS="--release"
+ RUST_TARGET_DIR="release"
+fi
+
+# gdb flags
+if test "x${GCC}" = xyes; then
+ GDB_FLAGS="-ggdb3"
+else
+ GDB_FLAGS="-g"
+fi
+
+# --- ASAN/UBSAN/TSAN (see man gcc) ---
+# when using SANitizers, we need to pass the -fsanitize..
+# to both CFLAGS and LDFLAGS. The CFLAGS/LDFLAGS must be
+# specified as first in the list or there will be runtime
+# issues (for example user has to LD_PRELOAD asan for it to work
+# properly).
+
+if test -n "${SANITIZERS}"; then
+ SANITIZERS=$(echo $SANITIZERS | sed -e 's/,/ /g')
+ for SANITIZER in $SANITIZERS; do
+ case $SANITIZER in
+ asan|ASAN)
+ SANITIZERS_CFLAGS="$SANITIZERS_CFLAGS -fsanitize=address"
+ SANITIZERS_LDFLAGS="$SANITIZERS_LDFLAGS -fsanitize=address -lasan"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lasan" >&5
+$as_echo_n "checking for main in -lasan... " >&6; }
+if ${ac_cv_lib_asan_main+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lasan $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+
+int
+main ()
+{
+return main ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_asan_main=yes
+else
+ ac_cv_lib_asan_main=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_asan_main" >&5
+$as_echo "$ac_cv_lib_asan_main" >&6; }
+if test "x$ac_cv_lib_asan_main" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBASAN 1
+_ACEOF
+
+ LIBS="-lasan $LIBS"
+
+else
+ as_fn_error $? "Unable to find libasan" "$LINENO" 5
+fi
+
+ ;;
+ ubsan|UBSAN)
+ SANITIZERS_CFLAGS="$SANITIZERS_CFLAGS -fsanitize=undefined"
+ SANITIZERS_LDFLAGS="$SANITIZERS_LDFLAGS -fsanitize=undefined -lubsan"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lubsan" >&5
+$as_echo_n "checking for main in -lubsan... " >&6; }
+if ${ac_cv_lib_ubsan_main+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lubsan $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+
+int
+main ()
+{
+return main ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_ubsan_main=yes
+else
+ ac_cv_lib_ubsan_main=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ubsan_main" >&5
+$as_echo "$ac_cv_lib_ubsan_main" >&6; }
+if test "x$ac_cv_lib_ubsan_main" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBUBSAN 1
+_ACEOF
+
+ LIBS="-lubsan $LIBS"
+
+else
+ as_fn_error $? "Unable to find libubsan" "$LINENO" 5
+fi
+
+ ;;
+ tsan|TSAN)
+ SANITIZERS_CFLAGS="$SANITIZERS_CFLAGS -fsanitize=thread"
+ SANITIZERS_LDFLAGS="$SANITIZERS_LDFLAGS -fsanitize=thread -ltsan"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -ltsan" >&5
+$as_echo_n "checking for main in -ltsan... " >&6; }
+if ${ac_cv_lib_tsan_main+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-ltsan $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+
+int
+main ()
+{
+return main ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_tsan_main=yes
+else
+ ac_cv_lib_tsan_main=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_tsan_main" >&5
+$as_echo "$ac_cv_lib_tsan_main" >&6; }
+if test "x$ac_cv_lib_tsan_main" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBTSAN 1
+_ACEOF
+
+ LIBS="-ltsan $LIBS"
+
+else
+ as_fn_error $? "Unable to find libtsan" "$LINENO" 5
+fi
+
+ ;;
+ esac
+ done
+fi
+
+# Look for dbus-1
+if test "x${enable_dbus}" = xyes; then
+
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for DBUS" >&5
+$as_echo_n "checking for DBUS... " >&6; }
+
+if test -n "$DBUS_CFLAGS"; then
+ pkg_cv_DBUS_CFLAGS="$DBUS_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"dbus-1\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "dbus-1") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_DBUS_CFLAGS=`$PKG_CONFIG --cflags "dbus-1" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+if test -n "$DBUS_LIBS"; then
+ pkg_cv_DBUS_LIBS="$DBUS_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"dbus-1\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "dbus-1") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_DBUS_LIBS=`$PKG_CONFIG --libs "dbus-1" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+
+
+
+if test $pkg_failed = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+ _pkg_short_errors_supported=yes
+else
+ _pkg_short_errors_supported=no
+fi
+ if test $_pkg_short_errors_supported = yes; then
+ DBUS_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "dbus-1" 2>&1`
+ else
+ DBUS_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "dbus-1" 2>&1`
+ fi
+ # Put the nasty error message in config.log where it belongs
+ echo "$DBUS_PKG_ERRORS" >&5
+
+ as_fn_error $? "Package requirements (dbus-1) were not met:
+
+$DBUS_PKG_ERRORS
+
+Consider adjusting the PKG_CONFIG_PATH environment variable if you
+installed software in a non-standard prefix.
+
+Alternatively, you may set the environment variables DBUS_CFLAGS
+and DBUS_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details." "$LINENO" 5
+elif test $pkg_failed = untried; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it
+is in your PATH or set the PKG_CONFIG environment variable to the full
+path to pkg-config.
+
+Alternatively, you may set the environment variables DBUS_CFLAGS
+and DBUS_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details.
+
+To get pkg-config, see <http://pkg-config.freedesktop.org/>.
+See \`config.log' for more details" "$LINENO" 5; }
+else
+ DBUS_CFLAGS=$pkg_cv_DBUS_CFLAGS
+ DBUS_LIBS=$pkg_cv_DBUS_LIBS
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DBUS 1
+_ACEOF
+
+ PACKAGE_FEATURES="$PACKAGE_FEATURES dbus"
+ WITH_LIST="$WITH_LIST --with dbus"
+fi
+
+if test "x${enable_monitoring}" = xyes; then
+
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for statgrab" >&5
+$as_echo_n "checking for statgrab... " >&6; }
+
+if test -n "$statgrab_CFLAGS"; then
+ pkg_cv_statgrab_CFLAGS="$statgrab_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libstatgrab\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "libstatgrab") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_statgrab_CFLAGS=`$PKG_CONFIG --cflags "libstatgrab" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+if test -n "$statgrab_LIBS"; then
+ pkg_cv_statgrab_LIBS="$statgrab_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libstatgrab\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "libstatgrab") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_statgrab_LIBS=`$PKG_CONFIG --libs "libstatgrab" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+
+
+
+if test $pkg_failed = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+ _pkg_short_errors_supported=yes
+else
+ _pkg_short_errors_supported=no
+fi
+ if test $_pkg_short_errors_supported = yes; then
+ statgrab_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libstatgrab" 2>&1`
+ else
+ statgrab_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libstatgrab" 2>&1`
+ fi
+ # Put the nasty error message in config.log where it belongs
+ echo "$statgrab_PKG_ERRORS" >&5
+
+ as_fn_error $? "Package requirements (libstatgrab) were not met:
+
+$statgrab_PKG_ERRORS
+
+Consider adjusting the PKG_CONFIG_PATH environment variable if you
+installed software in a non-standard prefix.
+
+Alternatively, you may set the environment variables statgrab_CFLAGS
+and statgrab_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details." "$LINENO" 5
+elif test $pkg_failed = untried; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it
+is in your PATH or set the PKG_CONFIG environment variable to the full
+path to pkg-config.
+
+Alternatively, you may set the environment variables statgrab_CFLAGS
+and statgrab_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details.
+
+To get pkg-config, see <http://pkg-config.freedesktop.org/>.
+See \`config.log' for more details" "$LINENO" 5; }
+else
+ statgrab_CFLAGS=$pkg_cv_statgrab_CFLAGS
+ statgrab_LIBS=$pkg_cv_statgrab_LIBS
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+fi
+
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for statgrabge090" >&5
+$as_echo_n "checking for statgrabge090... " >&6; }
+
+if test -n "$statgrabge090_CFLAGS"; then
+ pkg_cv_statgrabge090_CFLAGS="$statgrabge090_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libstatgrab >= 0.90\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "libstatgrab >= 0.90") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_statgrabge090_CFLAGS=`$PKG_CONFIG --cflags "libstatgrab >= 0.90" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+if test -n "$statgrabge090_LIBS"; then
+ pkg_cv_statgrabge090_LIBS="$statgrabge090_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libstatgrab >= 0.90\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "libstatgrab >= 0.90") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_statgrabge090_LIBS=`$PKG_CONFIG --libs "libstatgrab >= 0.90" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+
+
+
+if test $pkg_failed = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+ _pkg_short_errors_supported=yes
+else
+ _pkg_short_errors_supported=no
+fi
+ if test $_pkg_short_errors_supported = yes; then
+ statgrabge090_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libstatgrab >= 0.90" 2>&1`
+ else
+ statgrabge090_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libstatgrab >= 0.90" 2>&1`
+ fi
+ # Put the nasty error message in config.log where it belongs
+ echo "$statgrabge090_PKG_ERRORS" >&5
+
+ TMP_VARIABLE=1
+elif test $pkg_failed = untried; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ TMP_VARIABLE=1
+else
+ statgrabge090_CFLAGS=$pkg_cv_statgrabge090_CFLAGS
+ statgrabge090_LIBS=$pkg_cv_statgrabge090_LIBS
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBSTATGRAB_GE_090 1
+_ACEOF
+
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_MONITORING 1
+_ACEOF
+
+ PACKAGE_FEATURES="$PACKAGE_FEATURES monitoring"
+ WITH_LIST="$WITH_LIST --with monitoring"
+fi
+
+if test "x${enable_watchdog}" = xyes; then
+ ac_fn_c_check_header_mongrel "$LINENO" "linux/watchdog.h" "ac_cv_header_linux_watchdog_h" "$ac_includes_default"
+if test "x$ac_cv_header_linux_watchdog_h" = xyes; then :
+
+else
+ as_fn_error $? "watchdog requires linux/watchdog.h" "$LINENO" 5
+fi
+
+
+ ac_fn_c_check_header_mongrel "$LINENO" "linux/reboot.h" "ac_cv_header_linux_reboot_h" "$ac_includes_default"
+if test "x$ac_cv_header_linux_reboot_h" = xyes; then :
+
+else
+ as_fn_error $? "watchdog requires linux/reboot.h" "$LINENO" 5
+fi
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_WATCHDOG 1
+_ACEOF
+
+ PACKAGE_FEATURES="$PACKAGE_FEATURES watchdog"
+ WITH_LIST="$WITH_LIST --with watchdog"
+fi
+
+if test "x${enable_augeas}" = xyes; then
+ PACKAGE_FEATURES="$PACKAGE_FEATURES augeas"
+fi
+if test "x${enable_systemd}" = xyes; then
+
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for libsystemd" >&5
+$as_echo_n "checking for libsystemd... " >&6; }
+
+if test -n "$libsystemd_CFLAGS"; then
+ pkg_cv_libsystemd_CFLAGS="$libsystemd_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libsystemd\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "libsystemd") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_libsystemd_CFLAGS=`$PKG_CONFIG --cflags "libsystemd" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+if test -n "$libsystemd_LIBS"; then
+ pkg_cv_libsystemd_LIBS="$libsystemd_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libsystemd\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "libsystemd") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_libsystemd_LIBS=`$PKG_CONFIG --libs "libsystemd" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+
+
+
+if test $pkg_failed = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+ _pkg_short_errors_supported=yes
+else
+ _pkg_short_errors_supported=no
+fi
+ if test $_pkg_short_errors_supported = yes; then
+ libsystemd_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libsystemd" 2>&1`
+ else
+ libsystemd_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libsystemd" 2>&1`
+ fi
+ # Put the nasty error message in config.log where it belongs
+ echo "$libsystemd_PKG_ERRORS" >&5
+
+ as_fn_error $? "Package requirements (libsystemd) were not met:
+
+$libsystemd_PKG_ERRORS
+
+Consider adjusting the PKG_CONFIG_PATH environment variable if you
+installed software in a non-standard prefix.
+
+Alternatively, you may set the environment variables libsystemd_CFLAGS
+and libsystemd_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details." "$LINENO" 5
+elif test $pkg_failed = untried; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it
+is in your PATH or set the PKG_CONFIG environment variable to the full
+path to pkg-config.
+
+Alternatively, you may set the environment variables libsystemd_CFLAGS
+and libsystemd_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details.
+
+To get pkg-config, see <http://pkg-config.freedesktop.org/>.
+See \`config.log' for more details" "$LINENO" 5; }
+else
+ libsystemd_CFLAGS=$pkg_cv_libsystemd_CFLAGS
+ libsystemd_LIBS=$pkg_cv_libsystemd_LIBS
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+fi
+
+$as_echo "#define HAVE_LIBSYSTEMD 1" >>confdefs.h
+
+ PACKAGE_FEATURES="$PACKAGE_FEATURES systemd"
+ WITH_LIST="$WITH_LIST --with systemd"
+fi
+if test "x${enable_xmlconf}" = xyes; then
+ PACKAGE_FEATURES="$PACKAGE_FEATURES xmlconf"
+ WITH_LIST="$WITH_LIST --with xmlconf"
+fi
+if test "x${enable_vqsim}" = xyes; then
+ vqsim_readline=no
+ for ac_header in readline/readline.h readline/history.h
+do :
+ as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: vqsim will lack readline support" >&5
+$as_echo "$as_me: WARNING: vqsim will lack readline support" >&2;}
+fi
+
+done
+
+ PACKAGE_FEATURES="$PACKAGE_FEATURES vqsim"
+ WITH_LIST="$WITH_LIST --with vqsim"
+fi
+ if test "x${ac_cv_header_readline_readline_h}" = xyes; then
+ VQSIM_READLINE_TRUE=
+ VQSIM_READLINE_FALSE='#'
+else
+ VQSIM_READLINE_TRUE='#'
+ VQSIM_READLINE_FALSE=
+fi
+
+
+# Look for nozzle
+if test "x${enable_nozzle}" = xyes; then
+
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for nozzle" >&5
+$as_echo_n "checking for nozzle... " >&6; }
+
+if test -n "$nozzle_CFLAGS"; then
+ pkg_cv_nozzle_CFLAGS="$nozzle_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libnozzle\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "libnozzle") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_nozzle_CFLAGS=`$PKG_CONFIG --cflags "libnozzle" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+if test -n "$nozzle_LIBS"; then
+ pkg_cv_nozzle_LIBS="$nozzle_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libnozzle\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "libnozzle") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_nozzle_LIBS=`$PKG_CONFIG --libs "libnozzle" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+
+
+
+if test $pkg_failed = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+ _pkg_short_errors_supported=yes
+else
+ _pkg_short_errors_supported=no
+fi
+ if test $_pkg_short_errors_supported = yes; then
+ nozzle_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libnozzle" 2>&1`
+ else
+ nozzle_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libnozzle" 2>&1`
+ fi
+ # Put the nasty error message in config.log where it belongs
+ echo "$nozzle_PKG_ERRORS" >&5
+
+ as_fn_error $? "Package requirements (libnozzle) were not met:
+
+$nozzle_PKG_ERRORS
+
+Consider adjusting the PKG_CONFIG_PATH environment variable if you
+installed software in a non-standard prefix.
+
+Alternatively, you may set the environment variables nozzle_CFLAGS
+and nozzle_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details." "$LINENO" 5
+elif test $pkg_failed = untried; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it
+is in your PATH or set the PKG_CONFIG environment variable to the full
+path to pkg-config.
+
+Alternatively, you may set the environment variables nozzle_CFLAGS
+and nozzle_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details.
+
+To get pkg-config, see <http://pkg-config.freedesktop.org/>.
+See \`config.log' for more details" "$LINENO" 5; }
+else
+ nozzle_CFLAGS=$pkg_cv_nozzle_CFLAGS
+ nozzle_LIBS=$pkg_cv_nozzle_LIBS
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBNOZZLE 1
+_ACEOF
+
+ PACKAGE_FEATURES="$PACKAGE_FEATURES nozzle"
+ WITH_LIST="$WITH_LIST --with nozzle"
+fi
+
+do_snmp=0
+if test "x${enable_snmp}" = xyes; then
+ for ac_prog in net-snmp-config
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_SNMPCONFIG+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $SNMPCONFIG in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_SNMPCONFIG="$SNMPCONFIG" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_SNMPCONFIG="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+fi
+SNMPCONFIG=$ac_cv_path_SNMPCONFIG
+if test -n "$SNMPCONFIG"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $SNMPCONFIG" >&5
+$as_echo "$SNMPCONFIG" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$SNMPCONFIG" && break
+done
+
+
+ if test "x${SNMPCONFIG}" != "x"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for snmp includes" >&5
+$as_echo_n "checking for snmp includes... " >&6; }
+ SNMP_PREFIX=`$SNMPCONFIG --prefix`
+ SNMP_INCLUDES="-I$SNMP_PREFIX/include"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $SNMP_INCLUDES" >&5
+$as_echo "$SNMP_INCLUDES" >&6; }
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for snmp libraries" >&5
+$as_echo_n "checking for snmp libraries... " >&6; }
+ SNMP_LIBS=`$SNMPCONFIG --libs`
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $SNMP_LIBS" >&5
+$as_echo "$SNMP_LIBS" >&6; }
+
+
+ saveCFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS $SNMP_INCLUDES"
+ for ac_header in net-snmp/net-snmp-config.h
+do :
+ ac_fn_c_check_header_mongrel "$LINENO" "net-snmp/net-snmp-config.h" "ac_cv_header_net_snmp_net_snmp_config_h" "$ac_includes_default"
+if test "x$ac_cv_header_net_snmp_net_snmp_config_h" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_NET_SNMP_NET_SNMP_CONFIG_H 1
+_ACEOF
+
+fi
+
+done
+
+ CFLAGS="$saveCFLAGS"
+
+ if test "x${ac_cv_header_net_snmp_net_snmp_config_h}" != "xyes"; then
+ as_fn_error $? "Unable to use net-snmp/net-snmp-config.h" "$LINENO" 5
+ fi
+
+ savedLibs=$LIBS
+ LIBS="$LIBS $SNMP_LIBS"
+ for ac_func in netsnmp_transport_open_client
+do :
+ ac_fn_c_check_func "$LINENO" "netsnmp_transport_open_client" "ac_cv_func_netsnmp_transport_open_client"
+if test "x$ac_cv_func_netsnmp_transport_open_client" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_NETSNMP_TRANSPORT_OPEN_CLIENT 1
+_ACEOF
+
+fi
+done
+
+ if test $ac_cv_func_netsnmp_transport_open_client != yes; then
+ for ac_func in netsnmp_tdomain_transport
+do :
+ ac_fn_c_check_func "$LINENO" "netsnmp_tdomain_transport" "ac_cv_func_netsnmp_tdomain_transport"
+if test "x$ac_cv_func_netsnmp_tdomain_transport" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_NETSNMP_TDOMAIN_TRANSPORT 1
+_ACEOF
+
+fi
+done
+
+ if test $ac_cv_func_netsnmp_tdomain_transport != yes; then
+ as_fn_error $? "No usable SNMP client transport implementation found" "$LINENO" 5
+ fi
+ else
+
+cat >>confdefs.h <<_ACEOF
+#define NETSNMPV54 $NETSNMP_NEW_SUPPORT
+_ACEOF
+
+ fi
+ LIBS=$savedLibs
+
+ do_snmp=1
+ PACKAGE_FEATURES="$PACKAGE_FEATURES snmp"
+ WITH_LIST="$WITH_LIST --with snmp"
+
+cat >>confdefs.h <<_ACEOF
+#define ENABLE_SNMP $do_snmp
+_ACEOF
+
+ else
+ as_fn_error $? "You need the net_snmp development package to continue." "$LINENO" 5
+ fi
+fi
+ if test "${do_snmp}" = "1"; then
+ BUILD_SNMP_TRUE=
+ BUILD_SNMP_FALSE='#'
+else
+ BUILD_SNMP_TRUE='#'
+ BUILD_SNMP_FALSE=
+fi
+
+
+# extra warnings
+EXTRA_WARNINGS=""
+
+WARNLIST="
+ all
+ shadow
+ missing-prototypes
+ missing-declarations
+ strict-prototypes
+ pointer-arith
+ write-strings
+ cast-align
+ bad-function-cast
+ missing-format-attribute
+ format=2
+ format-security
+ format-nonliteral
+ no-long-long
+ unsigned-char
+ no-strict-aliasing
+ "
+
+for j in $WARNLIST; do
+ if cc_supports_flag -W$j; then
+ EXTRA_WARNINGS="$EXTRA_WARNINGS -W$j";
+ fi
+done
+
+if test "x${enable_coverage}" = xyes && \
+ cc_supports_flag -ftest-coverage && \
+ cc_supports_flag -fprofile-arcs ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Enabling Coverage (enable -O0 by default)" >&5
+$as_echo "$as_me: Enabling Coverage (enable -O0 by default)" >&6;}
+ OPT_CFLAGS="-O0"
+ COVERAGE_CFLAGS="-ftest-coverage -fprofile-arcs"
+ COVERAGE_LDFLAGS="-ftest-coverage -fprofile-arcs"
+ PACKAGE_FEATURES="$PACKAGE_FEATURES coverage"
+else
+ COVERAGE_CFLAGS=""
+ COVERAGE_LDFLAGS=""
+fi
+
+if test "x${enable_small_memory_footprint}" = xyes ; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_SMALL_MEMORY_FOOTPRINT 1
+_ACEOF
+
+ PACKAGE_FEATURES="$PACKAGE_FEATURES small-memory-footprint"
+fi
+
+if test "x${enable_ansi}" = xyes && \
+ cc_supports_flag -std=iso9899:199409 ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Enabling ANSI Compatibility" >&5
+$as_echo "$as_me: Enabling ANSI Compatibility" >&6;}
+ ANSI_CPPFLAGS="-ansi -DANSI_ONLY"
+ PACKAGE_FEATURES="$PACKAGE_FEATURES ansi"
+else
+ ANSI_CPPFLAGS=""
+fi
+
+if test "x${enable_fatal_warnings}" = xyes && \
+ cc_supports_flag -Werror ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Enabling Fatal Warnings (-Werror)" >&5
+$as_echo "$as_me: Enabling Fatal Warnings (-Werror)" >&6;}
+ WERROR_CFLAGS="-Werror"
+ PACKAGE_FEATURES="$PACKAGE_FEATURES fatal-warnings"
+else
+ WERROR_CFLAGS=""
+fi
+
+# don't add addtional cflags
+if test "x${enable_user_flags}" = xyes; then
+ OPT_CFLAGS=""
+ GDB_FLAGS=""
+ EXTRA_WARNINGS=""
+fi
+
+if test "x${enable_secure_build}" = xyes; then
+ # stolen from apache configure snippet
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts PIE flags" >&5
+$as_echo_n "checking whether $CC accepts PIE flags... " >&6; }
+if ${ap_cv_cc_pie+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+ save_CFLAGS=$CFLAGS
+ save_LDFLAGS=$LDFLAGS
+ CFLAGS="$CFLAGS -fPIE"
+ LDFLAGS="$LDFLAGS -pie"
+ if test "$cross_compiling" = yes; then :
+ ap_cv_cc_pie=yes
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+static int foo[30000]; int main () { return 0; }
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+ ap_cv_cc_pie=yes
+else
+ ap_cv_cc_pie=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+ CFLAGS=$save_CFLAGS
+ LDFLAGS=$save_LDFLAGS
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ap_cv_cc_pie" >&5
+$as_echo "$ap_cv_cc_pie" >&6; }
+ if test "$ap_cv_cc_pie" = "yes"; then
+ SEC_FLAGS="$SEC_FLAGS -fPIE"
+ SEC_LDFLAGS="$SEC_LDFLAGS -pie"
+ PACKAGE_FEATURES="$PACKAGE_FEATURES pie"
+ fi
+
+ # similar to above
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts RELRO flags" >&5
+$as_echo_n "checking whether $CC accepts RELRO flags... " >&6; }
+if ${ap_cv_cc_relro+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+ save_LDFLAGS=$LDFLAGS
+ LDFLAGS="$LDFLAGS -Wl,-z,relro"
+ if test "$cross_compiling" = yes; then :
+ ap_cv_cc_relro=yes
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+static int foo[30000]; int main () { return 0; }
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+ ap_cv_cc_relro=yes
+else
+ ap_cv_cc_relro=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+ LDFLAGS=$save_LDFLAGS
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ap_cv_cc_relro" >&5
+$as_echo "$ap_cv_cc_relro" >&6; }
+ if test "$ap_cv_cc_relro" = "yes"; then
+ SEC_LDFLAGS="$SEC_LDFLAGS -Wl,-z,relro"
+ PACKAGE_FEATURES="$PACKAGE_FEATURES relro"
+ fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts BINDNOW flags" >&5
+$as_echo_n "checking whether $CC accepts BINDNOW flags... " >&6; }
+if ${ap_cv_cc_bindnow+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+ save_LDFLAGS=$LDFLAGS
+ LDFLAGS="$LDFLAGS -Wl,-z,now"
+ if test "$cross_compiling" = yes; then :
+ ap_cv_cc_bindnow=yes
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+static int foo[30000]; int main () { return 0; }
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+ ap_cv_cc_bindnow=yes
+else
+ ap_cv_cc_bindnow=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+ LDFLAGS=$save_LDFLAGS
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ap_cv_cc_bindnow" >&5
+$as_echo "$ap_cv_cc_bindnow" >&6; }
+ if test "$ap_cv_cc_bindnow" = "yes"; then
+ SEC_LDFLAGS="$SEC_LDFLAGS -Wl,-z,now"
+ PACKAGE_FEATURES="$PACKAGE_FEATURES bindnow"
+ fi
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts \"--as-needed\"" >&5
+$as_echo_n "checking whether $CC accepts \"--as-needed\"... " >&6; }
+if ${ap_cv_cc_as_needed+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+ save_LDFLAGS=$LDFLAGS
+ LDFLAGS="$LDFLAGS -Wl,--as-needed"
+ if test "$cross_compiling" = yes; then :
+ ap_cv_cc_as_needed=yes
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+static int foo[30000]; int main () { return 0; }
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+ ap_cv_cc_as_needed=yes
+else
+ ap_cv_cc_as_needed=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+ LDFLAGS=$save_LDFLAGS
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ap_cv_cc_as_needed" >&5
+$as_echo "$ap_cv_cc_as_needed" >&6; }
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts \"--version-script\"" >&5
+$as_echo_n "checking whether $CC accepts \"--version-script\"... " >&6; }
+if ${ap_cv_cc_version_script+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+ save_LDFLAGS=$LDFLAGS
+ LDFLAGS="$LDFLAGS -Wl,--version-script=conftest.versions"
+ echo "CONFTEST { };" >conftest.versions
+ if test "$cross_compiling" = yes; then :
+ ap_cv_cc_version_script=yes
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+static int foo[30000]; int main () { return 0; }
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+ ap_cv_cc_version_script=yes
+else
+ ap_cv_cc_version_script=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+ rm -f conftest.versions
+ LDFLAGS=$save_LDFLAGS
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ap_cv_cc_version_script" >&5
+$as_echo "$ap_cv_cc_version_script" >&6; }
+if test "$ap_cv_cc_version_script" = "yes"; then
+ VERSCRIPT_LDFLAGS="-Wl,--version-script=\$(srcdir)/lib\$(call get_libname,\$<).versions"
+
+else
+ VERSCRIPT_LDFLAGS=""
+
+fi
+
+# define global include dirs
+INCLUDE_DIRS="$INCLUDE_DIRS -I\$(top_builddir)/include -I\$(top_srcdir)/include"
+INCLUDE_DIRS="$INCLUDE_DIRS -I\$(top_builddir)/include/corosync -I\$(top_srcdir)/include/corosync"
+
+# final build of *FLAGS
+CFLAGS="$SANITIZERS_CFLAGS $ENV_CFLAGS $lt_prog_compiler_pic $SEC_FLAGS $OPT_CFLAGS $GDB_FLAGS \
+ $COVERAGE_CFLAGS $EXTRA_WARNINGS \
+ $WERROR_CFLAGS $LIBQB_CFLAGS \
+ $SNMP_INCLUDES"
+CPPFLAGS="$ENV_CPPFLAGS $ANSI_CPPFLAGS $INCLUDE_DIRS"
+LDFLAGS="$SANITIZERS_LDFLAGS $ENV_LDFLAGS $lt_prog_compiler_pic $SEC_LDFLAGS $COVERAGE_LDFLAGS"
+
+if test "$ap_cv_cc_as_needed" = "yes"; then
+ LDFLAGS="$LDFLAGS -Wl,--as-needed"
+fi
+
+# substitute what we need:
+
+
+
+
+
+
+
+
+
+
+
+
+
+ if test "${do_snmp}" = "1"; then
+ INSTALL_MIB_TRUE=
+ INSTALL_MIB_FALSE='#'
+else
+ INSTALL_MIB_TRUE='#'
+ INSTALL_MIB_FALSE=
+fi
+
+ if test "${enable_dbus}" = "yes"; then
+ INSTALL_DBUSCONF_TRUE=
+ INSTALL_DBUSCONF_FALSE='#'
+else
+ INSTALL_DBUSCONF_TRUE='#'
+ INSTALL_DBUSCONF_FALSE=
+fi
+
+ if test -n "${AUGTOOL}"; then
+ AUGTOOL_TRUE=
+ AUGTOOL_FALSE='#'
+else
+ AUGTOOL_TRUE='#'
+ AUGTOOL_FALSE=
+fi
+
+
+ if test -n "${GROFF}"; then
+ BUILD_HTML_DOCS_TRUE=
+ BUILD_HTML_DOCS_FALSE='#'
+else
+ BUILD_HTML_DOCS_TRUE='#'
+ BUILD_HTML_DOCS_FALSE=
+fi
+
+
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define LOCALSTATEDIR "$(eval echo ${localstatedir})"
+_ACEOF
+
+
+COROSYSCONFDIR=${sysconfdir}/corosync
+
+
+cat >>confdefs.h <<_ACEOF
+#define COROSYSCONFDIR "$(eval echo ${COROSYSCONFDIR})"
+_ACEOF
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_FEATURES "${PACKAGE_FEATURES}"
+_ACEOF
+
+
+cat >confcache <<\_ACEOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs, see configure's option --config-cache.
+# It is not useful on other systems. If it contains results you don't
+# want to keep, you may remove or edit it.
+#
+# config.status only pays attention to the cache file if you give it
+# the --recheck option to rerun configure.
+#
+# `ac_cv_env_foo' variables (set or unset) will be overridden when
+# loading this file, other *unset* `ac_cv_foo' will be assigned the
+# following values.
+
+_ACEOF
+
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, we kill variables containing newlines.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(
+ for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do
+ eval ac_val=\$$ac_var
+ case $ac_val in #(
+ *${as_nl}*)
+ case $ac_var in #(
+ *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+ esac
+ case $ac_var in #(
+ _ | IFS | as_nl) ;; #(
+ BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+ *) { eval $ac_var=; unset $ac_var;} ;;
+ esac ;;
+ esac
+ done
+
+ (set) 2>&1 |
+ case $as_nl`(ac_space=' '; set) 2>&1` in #(
+ *${as_nl}ac_space=\ *)
+ # `set' does not quote correctly, so add quotes: double-quote
+ # substitution turns \\\\ into \\, and sed turns \\ into \.
+ sed -n \
+ "s/'/'\\\\''/g;
+ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+ ;; #(
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+ ;;
+ esac |
+ sort
+) |
+ sed '
+ /^ac_cv_env_/b end
+ t clear
+ :clear
+ s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+ t end
+ s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+ :end' >>confcache
+if diff "$cache_file" confcache >/dev/null 2>&1; then :; else
+ if test -w "$cache_file"; then
+ if test "x$cache_file" != "x/dev/null"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5
+$as_echo "$as_me: updating cache $cache_file" >&6;}
+ if test ! -f "$cache_file" || test -h "$cache_file"; then
+ cat confcache >"$cache_file"
+ else
+ case $cache_file in #(
+ */* | ?:*)
+ mv -f confcache "$cache_file"$$ &&
+ mv -f "$cache_file"$$ "$cache_file" ;; #(
+ *)
+ mv -f confcache "$cache_file" ;;
+ esac
+ fi
+ fi
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5
+$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;}
+ fi
+fi
+rm -f confcache
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+DEFS=-DHAVE_CONFIG_H
+
+ac_libobjs=
+ac_ltlibobjs=
+U=
+for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
+ # 1. Remove the extension, and $U if already installed.
+ ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'
+ ac_i=`$as_echo "$ac_i" | sed "$ac_script"`
+ # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR
+ # will be set to the directory where LIBOBJS objects are built.
+ as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext"
+ as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo'
+done
+LIBOBJS=$ac_libobjs
+
+LTLIBOBJS=$ac_ltlibobjs
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5
+$as_echo_n "checking that generated files are newer than configure... " >&6; }
+ if test -n "$am_sleep_pid"; then
+ # Hide warnings about reused PIDs.
+ wait $am_sleep_pid 2>/dev/null
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5
+$as_echo "done" >&6; }
+if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then
+ as_fn_error $? "conditional \"AMDEP\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then
+ as_fn_error $? "conditional \"am__fastdepCC\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+ if test -n "$EXEEXT"; then
+ am__EXEEXT_TRUE=
+ am__EXEEXT_FALSE='#'
+else
+ am__EXEEXT_TRUE='#'
+ am__EXEEXT_FALSE=
+fi
+
+if test -z "${BUILD_RUST_BINDINGS_TRUE}" && test -z "${BUILD_RUST_BINDINGS_FALSE}"; then
+ as_fn_error $? "conditional \"BUILD_RUST_BINDINGS\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${HAVE_QB_LOG_FILE_REOPEN_TRUE}" && test -z "${HAVE_QB_LOG_FILE_REOPEN_FALSE}"; then
+ as_fn_error $? "conditional \"HAVE_QB_LOG_FILE_REOPEN\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${HAVE_CRC32_TRUE}" && test -z "${HAVE_CRC32_FALSE}"; then
+ as_fn_error $? "conditional \"HAVE_CRC32\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${HAVE_CRC32_TRUE}" && test -z "${HAVE_CRC32_FALSE}"; then
+ as_fn_error $? "conditional \"HAVE_CRC32\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${BUILD_MONITORING_TRUE}" && test -z "${BUILD_MONITORING_FALSE}"; then
+ as_fn_error $? "conditional \"BUILD_MONITORING\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${BUILD_WATCHDOG_TRUE}" && test -z "${BUILD_WATCHDOG_FALSE}"; then
+ as_fn_error $? "conditional \"BUILD_WATCHDOG\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${INSTALL_AUGEAS_TRUE}" && test -z "${INSTALL_AUGEAS_FALSE}"; then
+ as_fn_error $? "conditional \"INSTALL_AUGEAS\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${INSTALL_SYSTEMD_TRUE}" && test -z "${INSTALL_SYSTEMD_FALSE}"; then
+ as_fn_error $? "conditional \"INSTALL_SYSTEMD\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${INSTALL_XMLCONF_TRUE}" && test -z "${INSTALL_XMLCONF_FALSE}"; then
+ as_fn_error $? "conditional \"INSTALL_XMLCONF\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${BUILD_VQSIM_TRUE}" && test -z "${BUILD_VQSIM_FALSE}"; then
+ as_fn_error $? "conditional \"BUILD_VQSIM\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${VQSIM_READLINE_TRUE}" && test -z "${VQSIM_READLINE_FALSE}"; then
+ as_fn_error $? "conditional \"VQSIM_READLINE\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${BUILD_SNMP_TRUE}" && test -z "${BUILD_SNMP_FALSE}"; then
+ as_fn_error $? "conditional \"BUILD_SNMP\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${INSTALL_MIB_TRUE}" && test -z "${INSTALL_MIB_FALSE}"; then
+ as_fn_error $? "conditional \"INSTALL_MIB\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${INSTALL_DBUSCONF_TRUE}" && test -z "${INSTALL_DBUSCONF_FALSE}"; then
+ as_fn_error $? "conditional \"INSTALL_DBUSCONF\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${AUGTOOL_TRUE}" && test -z "${AUGTOOL_FALSE}"; then
+ as_fn_error $? "conditional \"AUGTOOL\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${BUILD_HTML_DOCS_TRUE}" && test -z "${BUILD_HTML_DOCS_FALSE}"; then
+ as_fn_error $? "conditional \"BUILD_HTML_DOCS\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+
+: "${CONFIG_STATUS=./config.status}"
+ac_write_fail=0
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files $CONFIG_STATUS"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5
+$as_echo "$as_me: creating $CONFIG_STATUS" >&6;}
+as_write_fail=0
+cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate the current configuration.
+# Compiler output produced by configure, useful for debugging
+# configure, is in config.log if it exists.
+
+debug=false
+ac_cs_recheck=false
+ac_cs_silent=false
+
+SHELL=\${CONFIG_SHELL-$SHELL}
+export SHELL
+_ASEOF
+cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in #(
+ *posix*) :
+ set -o posix ;; #(
+ *) :
+ ;;
+esac
+fi
+
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='print -r --'
+ as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='printf %s\n'
+ as_echo_n='printf %s'
+else
+ if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+ as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+ as_echo_n='/usr/ucb/echo -n'
+ else
+ as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+ as_echo_n_body='eval
+ arg=$1;
+ case $arg in #(
+ *"$as_nl"*)
+ expr "X$arg" : "X\\(.*\\)$as_nl";
+ arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+ esac;
+ expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+ '
+ export as_echo_n_body
+ as_echo_n='sh -c $as_echo_n_body as_echo'
+ fi
+ export as_echo_body
+ as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ PATH_SEPARATOR=:
+ (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+ (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+ PATH_SEPARATOR=';'
+ }
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order. Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" "" $as_nl"
+
+# Find who we are. Look in the path if we contain no directory separator.
+as_myself=
+case $0 in #((
+ *[\\/]* ) as_myself=$0 ;;
+ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+ as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+ $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+ exit 1
+fi
+
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there. '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+
+# as_fn_error STATUS ERROR [LINENO LOG_FD]
+# ----------------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with STATUS, using 1 if that was 0.
+as_fn_error ()
+{
+ as_status=$1; test $as_status -eq 0 && as_status=1
+ if test "$4"; then
+ as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+ fi
+ $as_echo "$as_me: error: $2" >&2
+ as_fn_exit $as_status
+} # as_fn_error
+
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+ return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+ set +e
+ as_fn_set_status $1
+ exit $1
+} # as_fn_exit
+
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+ { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+ eval 'as_fn_append ()
+ {
+ eval $1+=\$2
+ }'
+else
+ as_fn_append ()
+ {
+ eval $1=\$$1\$2
+ }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+ eval 'as_fn_arith ()
+ {
+ as_val=$(( $* ))
+ }'
+else
+ as_fn_arith ()
+ {
+ as_val=`expr "$@" || test $? -eq 1`
+ }
+fi # as_fn_arith
+
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+ test "X`expr 00001 : '.*\(...\)'`" = X001; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+ as_basename=basename
+else
+ as_basename=false
+fi
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+ as_dirname=dirname
+else
+ as_dirname=false
+fi
+
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in #(((((
+-n*)
+ case `echo 'xy\c'` in
+ *c*) ECHO_T=' ';; # ECHO_T is single tab character.
+ xy) ECHO_C='\c';;
+ *) echo `echo ksh88 bug on AIX 6.1` > /dev/null
+ ECHO_T=' ';;
+ esac;;
+*)
+ ECHO_N='-n';;
+esac
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+ rm -f conf$$.dir/conf$$.file
+else
+ rm -f conf$$.dir
+ mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+ if ln -s conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s='ln -s'
+ # ... but there are two gotchas:
+ # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+ # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+ # In both cases, we have to default to `cp -pR'.
+ ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+ as_ln_s='cp -pR'
+ elif ln conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s=ln
+ else
+ as_ln_s='cp -pR'
+ fi
+else
+ as_ln_s='cp -pR'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+ case $as_dir in #(
+ -*) as_dir=./$as_dir;;
+ esac
+ test -d "$as_dir" || eval $as_mkdir_p || {
+ as_dirs=
+ while :; do
+ case $as_dir in #(
+ *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+ *) as_qdir=$as_dir;;
+ esac
+ as_dirs="'$as_qdir' $as_dirs"
+ as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ test -d "$as_dir" && break
+ done
+ test -z "$as_dirs" || eval "mkdir $as_dirs"
+ } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
+
+
+} # as_fn_mkdir_p
+if mkdir -p . 2>/dev/null; then
+ as_mkdir_p='mkdir -p "$as_dir"'
+else
+ test -d ./-p && rmdir ./-p
+ as_mkdir_p=false
+fi
+
+
+# as_fn_executable_p FILE
+# -----------------------
+# Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+ test -f "$1" && test -x "$1"
+} # as_fn_executable_p
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+exec 6>&1
+## ----------------------------------- ##
+## Main body of $CONFIG_STATUS script. ##
+## ----------------------------------- ##
+_ASEOF
+test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# Save the log message, to keep $0 and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling.
+ac_log="
+This file was extended by corosync $as_me 3.1.8, which was
+generated by GNU Autoconf 2.69. Invocation command line was
+
+ CONFIG_FILES = $CONFIG_FILES
+ CONFIG_HEADERS = $CONFIG_HEADERS
+ CONFIG_LINKS = $CONFIG_LINKS
+ CONFIG_COMMANDS = $CONFIG_COMMANDS
+ $ $0 $@
+
+on `(hostname || uname -n) 2>/dev/null | sed 1q`
+"
+
+_ACEOF
+
+case $ac_config_files in *"
+"*) set x $ac_config_files; shift; ac_config_files=$*;;
+esac
+
+case $ac_config_headers in *"
+"*) set x $ac_config_headers; shift; ac_config_headers=$*;;
+esac
+
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+# Files that config.status was made for.
+config_files="$ac_config_files"
+config_headers="$ac_config_headers"
+config_commands="$ac_config_commands"
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+ac_cs_usage="\
+\`$as_me' instantiates files and other configuration actions
+from templates according to the current configuration. Unless the files
+and actions are specified as TAGs, all are instantiated by default.
+
+Usage: $0 [OPTION]... [TAG]...
+
+ -h, --help print this help, then exit
+ -V, --version print version number and configuration settings, then exit
+ --config print configuration, then exit
+ -q, --quiet, --silent
+ do not print progress messages
+ -d, --debug don't remove temporary files
+ --recheck update $as_me by reconfiguring in the same conditions
+ --file=FILE[:TEMPLATE]
+ instantiate the configuration file FILE
+ --header=FILE[:TEMPLATE]
+ instantiate the configuration header FILE
+
+Configuration files:
+$config_files
+
+Configuration headers:
+$config_headers
+
+Configuration commands:
+$config_commands
+
+Report bugs to <users@clusterlabs.org>."
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
+ac_cs_version="\\
+corosync config.status 3.1.8
+configured by $0, generated by GNU Autoconf 2.69,
+ with options \\"\$ac_cs_config\\"
+
+Copyright (C) 2012 Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+
+ac_pwd='$ac_pwd'
+srcdir='$srcdir'
+INSTALL='$INSTALL'
+MKDIR_P='$MKDIR_P'
+AWK='$AWK'
+test -n "\$AWK" || AWK=awk
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# The default lists apply if the user does not specify any file.
+ac_need_defaults=:
+while test $# != 0
+do
+ case $1 in
+ --*=?*)
+ ac_option=`expr "X$1" : 'X\([^=]*\)='`
+ ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'`
+ ac_shift=:
+ ;;
+ --*=)
+ ac_option=`expr "X$1" : 'X\([^=]*\)='`
+ ac_optarg=
+ ac_shift=:
+ ;;
+ *)
+ ac_option=$1
+ ac_optarg=$2
+ ac_shift=shift
+ ;;
+ esac
+
+ case $ac_option in
+ # Handling of the options.
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ ac_cs_recheck=: ;;
+ --version | --versio | --versi | --vers | --ver | --ve | --v | -V )
+ $as_echo "$ac_cs_version"; exit ;;
+ --config | --confi | --conf | --con | --co | --c )
+ $as_echo "$ac_cs_config"; exit ;;
+ --debug | --debu | --deb | --de | --d | -d )
+ debug=: ;;
+ --file | --fil | --fi | --f )
+ $ac_shift
+ case $ac_optarg in
+ *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ '') as_fn_error $? "missing file argument" ;;
+ esac
+ as_fn_append CONFIG_FILES " '$ac_optarg'"
+ ac_need_defaults=false;;
+ --header | --heade | --head | --hea )
+ $ac_shift
+ case $ac_optarg in
+ *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ esac
+ as_fn_append CONFIG_HEADERS " '$ac_optarg'"
+ ac_need_defaults=false;;
+ --he | --h)
+ # Conflict between --help and --header
+ as_fn_error $? "ambiguous option: \`$1'
+Try \`$0 --help' for more information.";;
+ --help | --hel | -h )
+ $as_echo "$ac_cs_usage"; exit ;;
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil | --si | --s)
+ ac_cs_silent=: ;;
+
+ # This is an error.
+ -*) as_fn_error $? "unrecognized option: \`$1'
+Try \`$0 --help' for more information." ;;
+
+ *) as_fn_append ac_config_targets " $1"
+ ac_need_defaults=false ;;
+
+ esac
+ shift
+done
+
+ac_configure_extra_args=
+
+if $ac_cs_silent; then
+ exec 6>/dev/null
+ ac_configure_extra_args="$ac_configure_extra_args --silent"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+if \$ac_cs_recheck; then
+ set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+ shift
+ \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6
+ CONFIG_SHELL='$SHELL'
+ export CONFIG_SHELL
+ exec "\$@"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+exec 5>>config.log
+{
+ echo
+ sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+ $as_echo "$ac_log"
+} >&5
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+#
+# INIT-COMMANDS
+#
+AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"
+
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+sed_quote_subst='$sed_quote_subst'
+double_quote_subst='$double_quote_subst'
+delay_variable_subst='$delay_variable_subst'
+macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`'
+macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`'
+enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`'
+enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`'
+pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`'
+enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`'
+SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`'
+ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`'
+PATH_SEPARATOR='`$ECHO "$PATH_SEPARATOR" | $SED "$delay_single_quote_subst"`'
+host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`'
+host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`'
+host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`'
+build_alias='`$ECHO "$build_alias" | $SED "$delay_single_quote_subst"`'
+build='`$ECHO "$build" | $SED "$delay_single_quote_subst"`'
+build_os='`$ECHO "$build_os" | $SED "$delay_single_quote_subst"`'
+SED='`$ECHO "$SED" | $SED "$delay_single_quote_subst"`'
+Xsed='`$ECHO "$Xsed" | $SED "$delay_single_quote_subst"`'
+GREP='`$ECHO "$GREP" | $SED "$delay_single_quote_subst"`'
+EGREP='`$ECHO "$EGREP" | $SED "$delay_single_quote_subst"`'
+FGREP='`$ECHO "$FGREP" | $SED "$delay_single_quote_subst"`'
+LD='`$ECHO "$LD" | $SED "$delay_single_quote_subst"`'
+NM='`$ECHO "$NM" | $SED "$delay_single_quote_subst"`'
+LN_S='`$ECHO "$LN_S" | $SED "$delay_single_quote_subst"`'
+max_cmd_len='`$ECHO "$max_cmd_len" | $SED "$delay_single_quote_subst"`'
+ac_objext='`$ECHO "$ac_objext" | $SED "$delay_single_quote_subst"`'
+exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`'
+lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`'
+lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`'
+lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`'
+lt_cv_to_host_file_cmd='`$ECHO "$lt_cv_to_host_file_cmd" | $SED "$delay_single_quote_subst"`'
+lt_cv_to_tool_file_cmd='`$ECHO "$lt_cv_to_tool_file_cmd" | $SED "$delay_single_quote_subst"`'
+reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`'
+reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`'
+OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`'
+deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`'
+file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`'
+file_magic_glob='`$ECHO "$file_magic_glob" | $SED "$delay_single_quote_subst"`'
+want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`'
+DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`'
+sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`'
+AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`'
+AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`'
+archiver_list_spec='`$ECHO "$archiver_list_spec" | $SED "$delay_single_quote_subst"`'
+STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`'
+RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`'
+old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`'
+old_postuninstall_cmds='`$ECHO "$old_postuninstall_cmds" | $SED "$delay_single_quote_subst"`'
+old_archive_cmds='`$ECHO "$old_archive_cmds" | $SED "$delay_single_quote_subst"`'
+lock_old_archive_extraction='`$ECHO "$lock_old_archive_extraction" | $SED "$delay_single_quote_subst"`'
+CC='`$ECHO "$CC" | $SED "$delay_single_quote_subst"`'
+CFLAGS='`$ECHO "$CFLAGS" | $SED "$delay_single_quote_subst"`'
+compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`'
+GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`'
+nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`'
+lt_sysroot='`$ECHO "$lt_sysroot" | $SED "$delay_single_quote_subst"`'
+objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`'
+MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`'
+lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`'
+need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`'
+MANIFEST_TOOL='`$ECHO "$MANIFEST_TOOL" | $SED "$delay_single_quote_subst"`'
+DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`'
+NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`'
+LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`'
+OTOOL='`$ECHO "$OTOOL" | $SED "$delay_single_quote_subst"`'
+OTOOL64='`$ECHO "$OTOOL64" | $SED "$delay_single_quote_subst"`'
+libext='`$ECHO "$libext" | $SED "$delay_single_quote_subst"`'
+shrext_cmds='`$ECHO "$shrext_cmds" | $SED "$delay_single_quote_subst"`'
+extract_expsyms_cmds='`$ECHO "$extract_expsyms_cmds" | $SED "$delay_single_quote_subst"`'
+archive_cmds_need_lc='`$ECHO "$archive_cmds_need_lc" | $SED "$delay_single_quote_subst"`'
+enable_shared_with_static_runtimes='`$ECHO "$enable_shared_with_static_runtimes" | $SED "$delay_single_quote_subst"`'
+export_dynamic_flag_spec='`$ECHO "$export_dynamic_flag_spec" | $SED "$delay_single_quote_subst"`'
+whole_archive_flag_spec='`$ECHO "$whole_archive_flag_spec" | $SED "$delay_single_quote_subst"`'
+compiler_needs_object='`$ECHO "$compiler_needs_object" | $SED "$delay_single_quote_subst"`'
+old_archive_from_new_cmds='`$ECHO "$old_archive_from_new_cmds" | $SED "$delay_single_quote_subst"`'
+old_archive_from_expsyms_cmds='`$ECHO "$old_archive_from_expsyms_cmds" | $SED "$delay_single_quote_subst"`'
+archive_cmds='`$ECHO "$archive_cmds" | $SED "$delay_single_quote_subst"`'
+archive_expsym_cmds='`$ECHO "$archive_expsym_cmds" | $SED "$delay_single_quote_subst"`'
+module_cmds='`$ECHO "$module_cmds" | $SED "$delay_single_quote_subst"`'
+module_expsym_cmds='`$ECHO "$module_expsym_cmds" | $SED "$delay_single_quote_subst"`'
+with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`'
+allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`'
+no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`'
+hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`'
+hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`'
+hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`'
+hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`'
+hardcode_minus_L='`$ECHO "$hardcode_minus_L" | $SED "$delay_single_quote_subst"`'
+hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_quote_subst"`'
+hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`'
+inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`'
+link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`'
+always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`'
+export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`'
+exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`'
+include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`'
+prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`'
+postlink_cmds='`$ECHO "$postlink_cmds" | $SED "$delay_single_quote_subst"`'
+file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`'
+variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`'
+need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`'
+need_version='`$ECHO "$need_version" | $SED "$delay_single_quote_subst"`'
+version_type='`$ECHO "$version_type" | $SED "$delay_single_quote_subst"`'
+runpath_var='`$ECHO "$runpath_var" | $SED "$delay_single_quote_subst"`'
+shlibpath_var='`$ECHO "$shlibpath_var" | $SED "$delay_single_quote_subst"`'
+shlibpath_overrides_runpath='`$ECHO "$shlibpath_overrides_runpath" | $SED "$delay_single_quote_subst"`'
+libname_spec='`$ECHO "$libname_spec" | $SED "$delay_single_quote_subst"`'
+library_names_spec='`$ECHO "$library_names_spec" | $SED "$delay_single_quote_subst"`'
+soname_spec='`$ECHO "$soname_spec" | $SED "$delay_single_quote_subst"`'
+install_override_mode='`$ECHO "$install_override_mode" | $SED "$delay_single_quote_subst"`'
+postinstall_cmds='`$ECHO "$postinstall_cmds" | $SED "$delay_single_quote_subst"`'
+postuninstall_cmds='`$ECHO "$postuninstall_cmds" | $SED "$delay_single_quote_subst"`'
+finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`'
+finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`'
+hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`'
+sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`'
+sys_lib_dlsearch_path_spec='`$ECHO "$sys_lib_dlsearch_path_spec" | $SED "$delay_single_quote_subst"`'
+hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`'
+enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`'
+enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`'
+enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`'
+old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`'
+striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`'
+
+LTCC='$LTCC'
+LTCFLAGS='$LTCFLAGS'
+compiler='$compiler_DEFAULT'
+
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
+{
+ eval 'cat <<_LTECHO_EOF
+\$1
+_LTECHO_EOF'
+}
+
+# Quote evaled strings.
+for var in SHELL \
+ECHO \
+PATH_SEPARATOR \
+SED \
+GREP \
+EGREP \
+FGREP \
+LD \
+NM \
+LN_S \
+lt_SP2NL \
+lt_NL2SP \
+reload_flag \
+OBJDUMP \
+deplibs_check_method \
+file_magic_cmd \
+file_magic_glob \
+want_nocaseglob \
+DLLTOOL \
+sharedlib_from_linklib_cmd \
+AR \
+AR_FLAGS \
+archiver_list_spec \
+STRIP \
+RANLIB \
+CC \
+CFLAGS \
+compiler \
+lt_cv_sys_global_symbol_pipe \
+lt_cv_sys_global_symbol_to_cdecl \
+lt_cv_sys_global_symbol_to_c_name_address \
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \
+nm_file_list_spec \
+lt_prog_compiler_no_builtin_flag \
+lt_prog_compiler_pic \
+lt_prog_compiler_wl \
+lt_prog_compiler_static \
+lt_cv_prog_compiler_c_o \
+need_locks \
+MANIFEST_TOOL \
+DSYMUTIL \
+NMEDIT \
+LIPO \
+OTOOL \
+OTOOL64 \
+shrext_cmds \
+export_dynamic_flag_spec \
+whole_archive_flag_spec \
+compiler_needs_object \
+with_gnu_ld \
+allow_undefined_flag \
+no_undefined_flag \
+hardcode_libdir_flag_spec \
+hardcode_libdir_separator \
+exclude_expsyms \
+include_expsyms \
+file_list_spec \
+variables_saved_for_relink \
+libname_spec \
+library_names_spec \
+soname_spec \
+install_override_mode \
+finish_eval \
+old_striplib \
+striplib; do
+ case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
+ *[\\\\\\\`\\"\\\$]*)
+ eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\""
+ ;;
+ *)
+ eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+ ;;
+ esac
+done
+
+# Double-quote double-evaled strings.
+for var in reload_cmds \
+old_postinstall_cmds \
+old_postuninstall_cmds \
+old_archive_cmds \
+extract_expsyms_cmds \
+old_archive_from_new_cmds \
+old_archive_from_expsyms_cmds \
+archive_cmds \
+archive_expsym_cmds \
+module_cmds \
+module_expsym_cmds \
+export_symbols_cmds \
+prelink_cmds \
+postlink_cmds \
+postinstall_cmds \
+postuninstall_cmds \
+finish_cmds \
+sys_lib_search_path_spec \
+sys_lib_dlsearch_path_spec; do
+ case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
+ *[\\\\\\\`\\"\\\$]*)
+ eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\""
+ ;;
+ *)
+ eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+ ;;
+ esac
+done
+
+ac_aux_dir='$ac_aux_dir'
+xsi_shell='$xsi_shell'
+lt_shell_append='$lt_shell_append'
+
+# See if we are running on zsh, and set the options which allow our
+# commands through without removal of \ escapes INIT.
+if test -n "\${ZSH_VERSION+set}" ; then
+ setopt NO_GLOB_SUBST
+fi
+
+
+ PACKAGE='$PACKAGE'
+ VERSION='$VERSION'
+ TIMESTAMP='$TIMESTAMP'
+ RM='$RM'
+ ofile='$ofile'
+
+
+
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+
+# Handling of arguments.
+for ac_config_target in $ac_config_targets
+do
+ case $ac_config_target in
+ "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;;
+ "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;;
+ "include/corosync/config.h") CONFIG_HEADERS="$CONFIG_HEADERS include/corosync/config.h" ;;
+ "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
+ "exec/Makefile") CONFIG_FILES="$CONFIG_FILES exec/Makefile" ;;
+ "include/Makefile") CONFIG_FILES="$CONFIG_FILES include/Makefile" ;;
+ "init/Makefile") CONFIG_FILES="$CONFIG_FILES init/Makefile" ;;
+ "lib/Makefile") CONFIG_FILES="$CONFIG_FILES lib/Makefile" ;;
+ "common_lib/Makefile") CONFIG_FILES="$CONFIG_FILES common_lib/Makefile" ;;
+ "man/Makefile") CONFIG_FILES="$CONFIG_FILES man/Makefile" ;;
+ "pkgconfig/Makefile") CONFIG_FILES="$CONFIG_FILES pkgconfig/Makefile" ;;
+ "test/Makefile") CONFIG_FILES="$CONFIG_FILES test/Makefile" ;;
+ "tools/Makefile") CONFIG_FILES="$CONFIG_FILES tools/Makefile" ;;
+ "conf/Makefile") CONFIG_FILES="$CONFIG_FILES conf/Makefile" ;;
+ "vqsim/Makefile") CONFIG_FILES="$CONFIG_FILES vqsim/Makefile" ;;
+ "Doxyfile") CONFIG_FILES="$CONFIG_FILES Doxyfile" ;;
+ "conf/logrotate/Makefile") CONFIG_FILES="$CONFIG_FILES conf/logrotate/Makefile" ;;
+ "bindings/Makefile") CONFIG_FILES="$CONFIG_FILES bindings/Makefile" ;;
+ "bindings/rust/Makefile") CONFIG_FILES="$CONFIG_FILES bindings/rust/Makefile" ;;
+ "bindings/rust/tests/Makefile") CONFIG_FILES="$CONFIG_FILES bindings/rust/tests/Makefile" ;;
+ "bindings/rust/Cargo.toml") CONFIG_FILES="$CONFIG_FILES bindings/rust/Cargo.toml" ;;
+ "bindings/rust/tests/Cargo.toml") CONFIG_FILES="$CONFIG_FILES bindings/rust/tests/Cargo.toml" ;;
+
+ *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
+ esac
+done
+
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used. Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+ test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
+ test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers
+ test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands
+fi
+
+# Have a temporary directory for convenience. Make it in the build tree
+# simply because there is no reason against having it here, and in addition,
+# creating and moving files from /tmp can sometimes cause problems.
+# Hook for its removal unless debugging.
+# Note that there is a small window in which the directory will not be cleaned:
+# after its creation but before its name has been assigned to `$tmp'.
+$debug ||
+{
+ tmp= ac_tmp=
+ trap 'exit_status=$?
+ : "${ac_tmp:=$tmp}"
+ { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status
+' 0
+ trap 'as_fn_exit 1' 1 2 13 15
+}
+# Create a (secure) tmp directory for tmp files.
+
+{
+ tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&
+ test -d "$tmp"
+} ||
+{
+ tmp=./conf$$-$RANDOM
+ (umask 077 && mkdir "$tmp")
+} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5
+ac_tmp=$tmp
+
+# Set up the scripts for CONFIG_FILES section.
+# No need to generate them if there are no CONFIG_FILES.
+# This happens for instance with `./config.status config.h'.
+if test -n "$CONFIG_FILES"; then
+
+
+ac_cr=`echo X | tr X '\015'`
+# On cygwin, bash can eat \r inside `` if the user requested igncr.
+# But we know of no other shell where ac_cr would be empty at this
+# point, so we can use a bashism as a fallback.
+if test "x$ac_cr" = x; then
+ eval ac_cr=\$\'\\r\'
+fi
+ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null`
+if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then
+ ac_cs_awk_cr='\\r'
+else
+ ac_cs_awk_cr=$ac_cr
+fi
+
+echo 'BEGIN {' >"$ac_tmp/subs1.awk" &&
+_ACEOF
+
+
+{
+ echo "cat >conf$$subs.awk <<_ACEOF" &&
+ echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' &&
+ echo "_ACEOF"
+} >conf$$subs.sh ||
+ as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'`
+ac_delim='%!_!# '
+for ac_last_try in false false false false false :; do
+ . ./conf$$subs.sh ||
+ as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+
+ ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X`
+ if test $ac_delim_n = $ac_delim_num; then
+ break
+ elif $ac_last_try; then
+ as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+ else
+ ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+ fi
+done
+rm -f conf$$subs.sh
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK &&
+_ACEOF
+sed -n '
+h
+s/^/S["/; s/!.*/"]=/
+p
+g
+s/^[^!]*!//
+:repl
+t repl
+s/'"$ac_delim"'$//
+t delim
+:nl
+h
+s/\(.\{148\}\)..*/\1/
+t more1
+s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/
+p
+n
+b repl
+:more1
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t nl
+:delim
+h
+s/\(.\{148\}\)..*/\1/
+t more2
+s/["\\]/\\&/g; s/^/"/; s/$/"/
+p
+b
+:more2
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t delim
+' <conf$$subs.awk | sed '
+/^[^""]/{
+ N
+ s/\n//
+}
+' >>$CONFIG_STATUS || ac_write_fail=1
+rm -f conf$$subs.awk
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+_ACAWK
+cat >>"\$ac_tmp/subs1.awk" <<_ACAWK &&
+ for (key in S) S_is_set[key] = 1
+ FS = ""
+
+}
+{
+ line = $ 0
+ nfields = split(line, field, "@")
+ substed = 0
+ len = length(field[1])
+ for (i = 2; i < nfields; i++) {
+ key = field[i]
+ keylen = length(key)
+ if (S_is_set[key]) {
+ value = S[key]
+ line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3)
+ len += length(value) + length(field[++i])
+ substed = 1
+ } else
+ len += 1 + keylen
+ }
+
+ print line
+}
+
+_ACAWK
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then
+ sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g"
+else
+ cat
+fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \
+ || as_fn_error $? "could not setup config files machinery" "$LINENO" 5
+_ACEOF
+
+# VPATH may cause trouble with some makes, so we remove sole $(srcdir),
+# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and
+# trailing colons and then remove the whole line if VPATH becomes empty
+# (actually we leave an empty line to preserve line numbers).
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{
+h
+s///
+s/^/:/
+s/[ ]*$/:/
+s/:\$(srcdir):/:/g
+s/:\${srcdir}:/:/g
+s/:@srcdir@:/:/g
+s/^:*//
+s/:*$//
+x
+s/\(=[ ]*\).*/\1/
+G
+s/\n//
+s/^[^=]*=[ ]*$//
+}'
+fi
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+fi # test -n "$CONFIG_FILES"
+
+# Set up the scripts for CONFIG_HEADERS section.
+# No need to generate them if there are no CONFIG_HEADERS.
+# This happens for instance with `./config.status Makefile'.
+if test -n "$CONFIG_HEADERS"; then
+cat >"$ac_tmp/defines.awk" <<\_ACAWK ||
+BEGIN {
+_ACEOF
+
+# Transform confdefs.h into an awk script `defines.awk', embedded as
+# here-document in config.status, that substitutes the proper values into
+# config.h.in to produce config.h.
+
+# Create a delimiter string that does not exist in confdefs.h, to ease
+# handling of long lines.
+ac_delim='%!_!# '
+for ac_last_try in false false :; do
+ ac_tt=`sed -n "/$ac_delim/p" confdefs.h`
+ if test -z "$ac_tt"; then
+ break
+ elif $ac_last_try; then
+ as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5
+ else
+ ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+ fi
+done
+
+# For the awk script, D is an array of macro values keyed by name,
+# likewise P contains macro parameters if any. Preserve backslash
+# newline sequences.
+
+ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]*
+sed -n '
+s/.\{148\}/&'"$ac_delim"'/g
+t rset
+:rset
+s/^[ ]*#[ ]*define[ ][ ]*/ /
+t def
+d
+:def
+s/\\$//
+t bsnl
+s/["\\]/\\&/g
+s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\
+D["\1"]=" \3"/p
+s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p
+d
+:bsnl
+s/["\\]/\\&/g
+s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\
+D["\1"]=" \3\\\\\\n"\\/p
+t cont
+s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p
+t cont
+d
+:cont
+n
+s/.\{148\}/&'"$ac_delim"'/g
+t clear
+:clear
+s/\\$//
+t bsnlc
+s/["\\]/\\&/g; s/^/"/; s/$/"/p
+d
+:bsnlc
+s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p
+b cont
+' <confdefs.h | sed '
+s/'"$ac_delim"'/"\\\
+"/g' >>$CONFIG_STATUS || ac_write_fail=1
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ for (key in D) D_is_set[key] = 1
+ FS = ""
+}
+/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ {
+ line = \$ 0
+ split(line, arg, " ")
+ if (arg[1] == "#") {
+ defundef = arg[2]
+ mac1 = arg[3]
+ } else {
+ defundef = substr(arg[1], 2)
+ mac1 = arg[2]
+ }
+ split(mac1, mac2, "(") #)
+ macro = mac2[1]
+ prefix = substr(line, 1, index(line, defundef) - 1)
+ if (D_is_set[macro]) {
+ # Preserve the white space surrounding the "#".
+ print prefix "define", macro P[macro] D[macro]
+ next
+ } else {
+ # Replace #undef with comments. This is necessary, for example,
+ # in the case of _POSIX_SOURCE, which is predefined and required
+ # on some systems where configure will not decide to define it.
+ if (defundef == "undef") {
+ print "/*", prefix defundef, macro, "*/"
+ next
+ }
+ }
+}
+{ print }
+_ACAWK
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+ as_fn_error $? "could not setup config headers machinery" "$LINENO" 5
+fi # test -n "$CONFIG_HEADERS"
+
+
+eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS"
+shift
+for ac_tag
+do
+ case $ac_tag in
+ :[FHLC]) ac_mode=$ac_tag; continue;;
+ esac
+ case $ac_mode$ac_tag in
+ :[FHL]*:*);;
+ :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;;
+ :[FH]-) ac_tag=-:-;;
+ :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
+ esac
+ ac_save_IFS=$IFS
+ IFS=:
+ set x $ac_tag
+ IFS=$ac_save_IFS
+ shift
+ ac_file=$1
+ shift
+
+ case $ac_mode in
+ :L) ac_source=$1;;
+ :[FH])
+ ac_file_inputs=
+ for ac_f
+ do
+ case $ac_f in
+ -) ac_f="$ac_tmp/stdin";;
+ *) # Look for the file first in the build tree, then in the source tree
+ # (if the path is not absolute). The absolute path cannot be DOS-style,
+ # because $ac_f cannot contain `:'.
+ test -f "$ac_f" ||
+ case $ac_f in
+ [\\/$]*) false;;
+ *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
+ esac ||
+ as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;;
+ esac
+ case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
+ as_fn_append ac_file_inputs " '$ac_f'"
+ done
+
+ # Let's still pretend it is `configure' which instantiates (i.e., don't
+ # use $as_me), people would be surprised to read:
+ # /* config.h. Generated by config.status. */
+ configure_input='Generated from '`
+ $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g'
+ `' by configure.'
+ if test x"$ac_file" != x-; then
+ configure_input="$ac_file. $configure_input"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5
+$as_echo "$as_me: creating $ac_file" >&6;}
+ fi
+ # Neutralize special characters interpreted by sed in replacement strings.
+ case $configure_input in #(
+ *\&* | *\|* | *\\* )
+ ac_sed_conf_input=`$as_echo "$configure_input" |
+ sed 's/[\\\\&|]/\\\\&/g'`;; #(
+ *) ac_sed_conf_input=$configure_input;;
+ esac
+
+ case $ac_tag in
+ *:-:* | *:-) cat >"$ac_tmp/stdin" \
+ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;;
+ esac
+ ;;
+ esac
+
+ ac_dir=`$as_dirname -- "$ac_file" ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$ac_file" : 'X\(//\)[^/]' \| \
+ X"$ac_file" : 'X\(//\)$' \| \
+ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$ac_file" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ as_dir="$ac_dir"; as_fn_mkdir_p
+ ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+ ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+ # A ".." for each directory in $ac_dir_suffix.
+ ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+ case $ac_top_builddir_sub in
+ "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+ *) ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+ esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+ .) # We are building in place.
+ ac_srcdir=.
+ ac_top_srcdir=$ac_top_builddir_sub
+ ac_abs_top_srcdir=$ac_pwd ;;
+ [\\/]* | ?:[\\/]* ) # Absolute name.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir
+ ac_abs_top_srcdir=$srcdir ;;
+ *) # Relative name.
+ ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_build_prefix$srcdir
+ ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+
+ case $ac_mode in
+ :F)
+ #
+ # CONFIG_FILE
+ #
+
+ case $INSTALL in
+ [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;;
+ *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;;
+ esac
+ ac_MKDIR_P=$MKDIR_P
+ case $MKDIR_P in
+ [\\/$]* | ?:[\\/]* ) ;;
+ */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;;
+ esac
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# If the template does not know about datarootdir, expand it.
+# FIXME: This hack should be removed a few years after 2.60.
+ac_datarootdir_hack=; ac_datarootdir_seen=
+ac_sed_dataroot='
+/datarootdir/ {
+ p
+ q
+}
+/@datadir@/p
+/@docdir@/p
+/@infodir@/p
+/@localedir@/p
+/@mandir@/p'
+case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in
+*datarootdir*) ac_datarootdir_seen=yes;;
+*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5
+$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ ac_datarootdir_hack='
+ s&@datadir@&$datadir&g
+ s&@docdir@&$docdir&g
+ s&@infodir@&$infodir&g
+ s&@localedir@&$localedir&g
+ s&@mandir@&$mandir&g
+ s&\\\${datarootdir}&$datarootdir&g' ;;
+esac
+_ACEOF
+
+# Neutralize VPATH when `$srcdir' = `.'.
+# Shell code in configure.ac might set extrasub.
+# FIXME: do we really want to maintain this feature?
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_sed_extra="$ac_vpsub
+$extrasub
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s|@configure_input@|$ac_sed_conf_input|;t t
+s&@top_builddir@&$ac_top_builddir_sub&;t t
+s&@top_build_prefix@&$ac_top_build_prefix&;t t
+s&@srcdir@&$ac_srcdir&;t t
+s&@abs_srcdir@&$ac_abs_srcdir&;t t
+s&@top_srcdir@&$ac_top_srcdir&;t t
+s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t
+s&@builddir@&$ac_builddir&;t t
+s&@abs_builddir@&$ac_abs_builddir&;t t
+s&@abs_top_builddir@&$ac_abs_top_builddir&;t t
+s&@INSTALL@&$ac_INSTALL&;t t
+s&@MKDIR_P@&$ac_MKDIR_P&;t t
+$ac_datarootdir_hack
+"
+eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \
+ >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+
+test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
+ { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } &&
+ { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \
+ "$ac_tmp/out"`; test -z "$ac_out"; } &&
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined. Please make sure it is defined" >&5
+$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined. Please make sure it is defined" >&2;}
+
+ rm -f "$ac_tmp/stdin"
+ case $ac_file in
+ -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";;
+ *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";;
+ esac \
+ || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+ ;;
+ :H)
+ #
+ # CONFIG_HEADER
+ #
+ if test x"$ac_file" != x-; then
+ {
+ $as_echo "/* $configure_input */" \
+ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs"
+ } >"$ac_tmp/config.h" \
+ || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+ if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5
+$as_echo "$as_me: $ac_file is unchanged" >&6;}
+ else
+ rm -f "$ac_file"
+ mv "$ac_tmp/config.h" "$ac_file" \
+ || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+ fi
+ else
+ $as_echo "/* $configure_input */" \
+ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \
+ || as_fn_error $? "could not create -" "$LINENO" 5
+ fi
+# Compute "$ac_file"'s index in $config_headers.
+_am_arg="$ac_file"
+_am_stamp_count=1
+for _am_header in $config_headers :; do
+ case $_am_header in
+ $_am_arg | $_am_arg:* )
+ break ;;
+ * )
+ _am_stamp_count=`expr $_am_stamp_count + 1` ;;
+ esac
+done
+echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" ||
+$as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$_am_arg" : 'X\(//\)[^/]' \| \
+ X"$_am_arg" : 'X\(//\)$' \| \
+ X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$_am_arg" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`/stamp-h$_am_stamp_count
+ ;;
+
+ :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5
+$as_echo "$as_me: executing $ac_file commands" >&6;}
+ ;;
+ esac
+
+
+ case $ac_file$ac_mode in
+ "depfiles":C) test x"$AMDEP_TRUE" != x"" || {
+ # Older Autoconf quotes --file arguments for eval, but not when files
+ # are listed without --file. Let's play safe and only enable the eval
+ # if we detect the quoting.
+ case $CONFIG_FILES in
+ *\'*) eval set x "$CONFIG_FILES" ;;
+ *) set x $CONFIG_FILES ;;
+ esac
+ shift
+ for mf
+ do
+ # Strip MF so we end up with the name of the file.
+ mf=`echo "$mf" | sed -e 's/:.*$//'`
+ # Check whether this is an Automake generated Makefile or not.
+ # We used to match only the files named 'Makefile.in', but
+ # some people rename them; so instead we look at the file content.
+ # Grep'ing the first line is not enough: some people post-process
+ # each Makefile.in and add a new line on top of each file to say so.
+ # Grep'ing the whole file is not good either: AIX grep has a line
+ # limit of 2048, but all sed's we know have understand at least 4000.
+ if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then
+ dirpart=`$as_dirname -- "$mf" ||
+$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$mf" : 'X\(//\)[^/]' \| \
+ X"$mf" : 'X\(//\)$' \| \
+ X"$mf" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$mf" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ else
+ continue
+ fi
+ # Extract the definition of DEPDIR, am__include, and am__quote
+ # from the Makefile without running 'make'.
+ DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
+ test -z "$DEPDIR" && continue
+ am__include=`sed -n 's/^am__include = //p' < "$mf"`
+ test -z "$am__include" && continue
+ am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
+ # Find all dependency output files, they are included files with
+ # $(DEPDIR) in their names. We invoke sed twice because it is the
+ # simplest approach to changing $(DEPDIR) to its actual value in the
+ # expansion.
+ for file in `sed -n "
+ s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
+ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do
+ # Make sure the directory exists.
+ test -f "$dirpart/$file" && continue
+ fdir=`$as_dirname -- "$file" ||
+$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$file" : 'X\(//\)[^/]' \| \
+ X"$file" : 'X\(//\)$' \| \
+ X"$file" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$file" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ as_dir=$dirpart/$fdir; as_fn_mkdir_p
+ # echo "creating $dirpart/$file"
+ echo '# dummy' > "$dirpart/$file"
+ done
+ done
+}
+ ;;
+ "libtool":C)
+
+ # See if we are running on zsh, and set the options which allow our
+ # commands through without removal of \ escapes.
+ if test -n "${ZSH_VERSION+set}" ; then
+ setopt NO_GLOB_SUBST
+ fi
+
+ cfgfile="${ofile}T"
+ trap "$RM \"$cfgfile\"; exit 1" 1 2 15
+ $RM "$cfgfile"
+
+ cat <<_LT_EOF >> "$cfgfile"
+#! $SHELL
+
+# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services.
+# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION
+# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+# NOTE: Changes made to this file will be lost: look at ltmain.sh.
+#
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005,
+# 2006, 2007, 2008, 2009, 2010, 2011 Free Software
+# Foundation, Inc.
+# Written by Gordon Matzigkeit, 1996
+#
+# This file is part of GNU Libtool.
+#
+# GNU Libtool 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.
+#
+# As a special exception to the GNU General Public License,
+# if you distribute this file as part of a program or library that
+# is built using GNU Libtool, you may include this file under the
+# same distribution terms that you use for the rest of that program.
+#
+# GNU Libtool 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 GNU Libtool; see the file COPYING. If not, a copy
+# can be downloaded from http://www.gnu.org/licenses/gpl.html, or
+# obtained by writing to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+
+# The names of the tagged configurations supported by this script.
+available_tags=""
+
+# ### BEGIN LIBTOOL CONFIG
+
+# Which release of libtool.m4 was used?
+macro_version=$macro_version
+macro_revision=$macro_revision
+
+# Whether or not to build shared libraries.
+build_libtool_libs=$enable_shared
+
+# Whether or not to build static libraries.
+build_old_libs=$enable_static
+
+# What type of objects to build.
+pic_mode=$pic_mode
+
+# Whether or not to optimize for fast installation.
+fast_install=$enable_fast_install
+
+# Shell to use when invoking shell scripts.
+SHELL=$lt_SHELL
+
+# An echo program that protects backslashes.
+ECHO=$lt_ECHO
+
+# The PATH separator for the build system.
+PATH_SEPARATOR=$lt_PATH_SEPARATOR
+
+# The host system.
+host_alias=$host_alias
+host=$host
+host_os=$host_os
+
+# The build system.
+build_alias=$build_alias
+build=$build
+build_os=$build_os
+
+# A sed program that does not truncate output.
+SED=$lt_SED
+
+# Sed that helps us avoid accidentally triggering echo(1) options like -n.
+Xsed="\$SED -e 1s/^X//"
+
+# A grep program that handles long lines.
+GREP=$lt_GREP
+
+# An ERE matcher.
+EGREP=$lt_EGREP
+
+# A literal string matcher.
+FGREP=$lt_FGREP
+
+# A BSD- or MS-compatible name lister.
+NM=$lt_NM
+
+# Whether we need soft or hard links.
+LN_S=$lt_LN_S
+
+# What is the maximum length of a command?
+max_cmd_len=$max_cmd_len
+
+# Object file suffix (normally "o").
+objext=$ac_objext
+
+# Executable file suffix (normally "").
+exeext=$exeext
+
+# whether the shell understands "unset".
+lt_unset=$lt_unset
+
+# turn spaces into newlines.
+SP2NL=$lt_lt_SP2NL
+
+# turn newlines into spaces.
+NL2SP=$lt_lt_NL2SP
+
+# convert \$build file names to \$host format.
+to_host_file_cmd=$lt_cv_to_host_file_cmd
+
+# convert \$build files to toolchain format.
+to_tool_file_cmd=$lt_cv_to_tool_file_cmd
+
+# An object symbol dumper.
+OBJDUMP=$lt_OBJDUMP
+
+# Method to check whether dependent libraries are shared objects.
+deplibs_check_method=$lt_deplibs_check_method
+
+# Command to use when deplibs_check_method = "file_magic".
+file_magic_cmd=$lt_file_magic_cmd
+
+# How to find potential files when deplibs_check_method = "file_magic".
+file_magic_glob=$lt_file_magic_glob
+
+# Find potential files using nocaseglob when deplibs_check_method = "file_magic".
+want_nocaseglob=$lt_want_nocaseglob
+
+# DLL creation program.
+DLLTOOL=$lt_DLLTOOL
+
+# Command to associate shared and link libraries.
+sharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd
+
+# The archiver.
+AR=$lt_AR
+
+# Flags to create an archive.
+AR_FLAGS=$lt_AR_FLAGS
+
+# How to feed a file listing to the archiver.
+archiver_list_spec=$lt_archiver_list_spec
+
+# A symbol stripping program.
+STRIP=$lt_STRIP
+
+# Commands used to install an old-style archive.
+RANLIB=$lt_RANLIB
+old_postinstall_cmds=$lt_old_postinstall_cmds
+old_postuninstall_cmds=$lt_old_postuninstall_cmds
+
+# Whether to use a lock for old archive extraction.
+lock_old_archive_extraction=$lock_old_archive_extraction
+
+# A C compiler.
+LTCC=$lt_CC
+
+# LTCC compiler flags.
+LTCFLAGS=$lt_CFLAGS
+
+# Take the output of nm and produce a listing of raw symbols and C names.
+global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe
+
+# Transform the output of nm in a proper C declaration.
+global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl
+
+# Transform the output of nm in a C name address pair.
+global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address
+
+# Transform the output of nm in a C name address pair when lib prefix is needed.
+global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix
+
+# Specify filename containing input files for \$NM.
+nm_file_list_spec=$lt_nm_file_list_spec
+
+# The root where to search for dependent libraries,and in which our libraries should be installed.
+lt_sysroot=$lt_sysroot
+
+# The name of the directory that contains temporary libtool files.
+objdir=$objdir
+
+# Used to examine libraries when file_magic_cmd begins with "file".
+MAGIC_CMD=$MAGIC_CMD
+
+# Must we lock files when doing compilation?
+need_locks=$lt_need_locks
+
+# Manifest tool.
+MANIFEST_TOOL=$lt_MANIFEST_TOOL
+
+# Tool to manipulate archived DWARF debug symbol files on Mac OS X.
+DSYMUTIL=$lt_DSYMUTIL
+
+# Tool to change global to local symbols on Mac OS X.
+NMEDIT=$lt_NMEDIT
+
+# Tool to manipulate fat objects and archives on Mac OS X.
+LIPO=$lt_LIPO
+
+# ldd/readelf like tool for Mach-O binaries on Mac OS X.
+OTOOL=$lt_OTOOL
+
+# ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4.
+OTOOL64=$lt_OTOOL64
+
+# Old archive suffix (normally "a").
+libext=$libext
+
+# Shared library suffix (normally ".so").
+shrext_cmds=$lt_shrext_cmds
+
+# The commands to extract the exported symbol list from a shared archive.
+extract_expsyms_cmds=$lt_extract_expsyms_cmds
+
+# Variables whose values should be saved in libtool wrapper scripts and
+# restored at link time.
+variables_saved_for_relink=$lt_variables_saved_for_relink
+
+# Do we need the "lib" prefix for modules?
+need_lib_prefix=$need_lib_prefix
+
+# Do we need a version for libraries?
+need_version=$need_version
+
+# Library versioning type.
+version_type=$version_type
+
+# Shared library runtime path variable.
+runpath_var=$runpath_var
+
+# Shared library path variable.
+shlibpath_var=$shlibpath_var
+
+# Is shlibpath searched before the hard-coded library search path?
+shlibpath_overrides_runpath=$shlibpath_overrides_runpath
+
+# Format of library name prefix.
+libname_spec=$lt_libname_spec
+
+# List of archive names. First name is the real one, the rest are links.
+# The last name is the one that the linker finds with -lNAME
+library_names_spec=$lt_library_names_spec
+
+# The coded name of the library, if different from the real name.
+soname_spec=$lt_soname_spec
+
+# Permission mode override for installation of shared libraries.
+install_override_mode=$lt_install_override_mode
+
+# Command to use after installation of a shared archive.
+postinstall_cmds=$lt_postinstall_cmds
+
+# Command to use after uninstallation of a shared archive.
+postuninstall_cmds=$lt_postuninstall_cmds
+
+# Commands used to finish a libtool library installation in a directory.
+finish_cmds=$lt_finish_cmds
+
+# As "finish_cmds", except a single script fragment to be evaled but
+# not shown.
+finish_eval=$lt_finish_eval
+
+# Whether we should hardcode library paths into libraries.
+hardcode_into_libs=$hardcode_into_libs
+
+# Compile-time system search path for libraries.
+sys_lib_search_path_spec=$lt_sys_lib_search_path_spec
+
+# Run-time system search path for libraries.
+sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec
+
+# Whether dlopen is supported.
+dlopen_support=$enable_dlopen
+
+# Whether dlopen of programs is supported.
+dlopen_self=$enable_dlopen_self
+
+# Whether dlopen of statically linked programs is supported.
+dlopen_self_static=$enable_dlopen_self_static
+
+# Commands to strip libraries.
+old_striplib=$lt_old_striplib
+striplib=$lt_striplib
+
+
+# The linker used to build libraries.
+LD=$lt_LD
+
+# How to create reloadable object files.
+reload_flag=$lt_reload_flag
+reload_cmds=$lt_reload_cmds
+
+# Commands used to build an old-style archive.
+old_archive_cmds=$lt_old_archive_cmds
+
+# A language specific compiler.
+CC=$lt_compiler
+
+# Is the compiler the GNU compiler?
+with_gcc=$GCC
+
+# Compiler flag to turn off builtin functions.
+no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag
+
+# Additional compiler flags for building library objects.
+pic_flag=$lt_lt_prog_compiler_pic
+
+# How to pass a linker flag through the compiler.
+wl=$lt_lt_prog_compiler_wl
+
+# Compiler flag to prevent dynamic linking.
+link_static_flag=$lt_lt_prog_compiler_static
+
+# Does compiler simultaneously support -c and -o options?
+compiler_c_o=$lt_lt_cv_prog_compiler_c_o
+
+# Whether or not to add -lc for building shared libraries.
+build_libtool_need_lc=$archive_cmds_need_lc
+
+# Whether or not to disallow shared libs when runtime libs are static.
+allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes
+
+# Compiler flag to allow reflexive dlopens.
+export_dynamic_flag_spec=$lt_export_dynamic_flag_spec
+
+# Compiler flag to generate shared objects directly from archives.
+whole_archive_flag_spec=$lt_whole_archive_flag_spec
+
+# Whether the compiler copes with passing no objects directly.
+compiler_needs_object=$lt_compiler_needs_object
+
+# Create an old-style archive from a shared archive.
+old_archive_from_new_cmds=$lt_old_archive_from_new_cmds
+
+# Create a temporary old-style archive to link instead of a shared archive.
+old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds
+
+# Commands used to build a shared archive.
+archive_cmds=$lt_archive_cmds
+archive_expsym_cmds=$lt_archive_expsym_cmds
+
+# Commands used to build a loadable module if different from building
+# a shared archive.
+module_cmds=$lt_module_cmds
+module_expsym_cmds=$lt_module_expsym_cmds
+
+# Whether we are building with GNU ld or not.
+with_gnu_ld=$lt_with_gnu_ld
+
+# Flag that allows shared libraries with undefined symbols to be built.
+allow_undefined_flag=$lt_allow_undefined_flag
+
+# Flag that enforces no undefined symbols.
+no_undefined_flag=$lt_no_undefined_flag
+
+# Flag to hardcode \$libdir into a binary during linking.
+# This must work even if \$libdir does not exist
+hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec
+
+# Whether we need a single "-rpath" flag with a separated argument.
+hardcode_libdir_separator=$lt_hardcode_libdir_separator
+
+# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes
+# DIR into the resulting binary.
+hardcode_direct=$hardcode_direct
+
+# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes
+# DIR into the resulting binary and the resulting library dependency is
+# "absolute",i.e impossible to change by setting \${shlibpath_var} if the
+# library is relocated.
+hardcode_direct_absolute=$hardcode_direct_absolute
+
+# Set to "yes" if using the -LDIR flag during linking hardcodes DIR
+# into the resulting binary.
+hardcode_minus_L=$hardcode_minus_L
+
+# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR
+# into the resulting binary.
+hardcode_shlibpath_var=$hardcode_shlibpath_var
+
+# Set to "yes" if building a shared library automatically hardcodes DIR
+# into the library and all subsequent libraries and executables linked
+# against it.
+hardcode_automatic=$hardcode_automatic
+
+# Set to yes if linker adds runtime paths of dependent libraries
+# to runtime path list.
+inherit_rpath=$inherit_rpath
+
+# Whether libtool must link a program against all its dependency libraries.
+link_all_deplibs=$link_all_deplibs
+
+# Set to "yes" if exported symbols are required.
+always_export_symbols=$always_export_symbols
+
+# The commands to list exported symbols.
+export_symbols_cmds=$lt_export_symbols_cmds
+
+# Symbols that should not be listed in the preloaded symbols.
+exclude_expsyms=$lt_exclude_expsyms
+
+# Symbols that must always be exported.
+include_expsyms=$lt_include_expsyms
+
+# Commands necessary for linking programs (against libraries) with templates.
+prelink_cmds=$lt_prelink_cmds
+
+# Commands necessary for finishing linking programs.
+postlink_cmds=$lt_postlink_cmds
+
+# Specify filename containing input files.
+file_list_spec=$lt_file_list_spec
+
+# How to hardcode a shared library path into an executable.
+hardcode_action=$hardcode_action
+
+# ### END LIBTOOL CONFIG
+
+_LT_EOF
+
+ case $host_os in
+ aix3*)
+ cat <<\_LT_EOF >> "$cfgfile"
+# AIX sometimes has problems with the GCC collect2 program. For some
+# reason, if we set the COLLECT_NAMES environment variable, the problems
+# vanish in a puff of smoke.
+if test "X${COLLECT_NAMES+set}" != Xset; then
+ COLLECT_NAMES=
+ export COLLECT_NAMES
+fi
+_LT_EOF
+ ;;
+ esac
+
+
+ltmain="$ac_aux_dir/ltmain.sh"
+
+
+ # We use sed instead of cat because bash on DJGPP gets confused if
+ # if finds mixed CR/LF and LF-only lines. Since sed operates in
+ # text mode, it properly converts lines to CR/LF. This bash problem
+ # is reportedly fixed, but why not run on old versions too?
+ sed '$q' "$ltmain" >> "$cfgfile" \
+ || (rm -f "$cfgfile"; exit 1)
+
+ if test x"$xsi_shell" = xyes; then
+ sed -e '/^func_dirname ()$/,/^} # func_dirname /c\
+func_dirname ()\
+{\
+\ case ${1} in\
+\ */*) func_dirname_result="${1%/*}${2}" ;;\
+\ * ) func_dirname_result="${3}" ;;\
+\ esac\
+} # Extended-shell func_dirname implementation' "$cfgfile" > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+ sed -e '/^func_basename ()$/,/^} # func_basename /c\
+func_basename ()\
+{\
+\ func_basename_result="${1##*/}"\
+} # Extended-shell func_basename implementation' "$cfgfile" > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+ sed -e '/^func_dirname_and_basename ()$/,/^} # func_dirname_and_basename /c\
+func_dirname_and_basename ()\
+{\
+\ case ${1} in\
+\ */*) func_dirname_result="${1%/*}${2}" ;;\
+\ * ) func_dirname_result="${3}" ;;\
+\ esac\
+\ func_basename_result="${1##*/}"\
+} # Extended-shell func_dirname_and_basename implementation' "$cfgfile" > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+ sed -e '/^func_stripname ()$/,/^} # func_stripname /c\
+func_stripname ()\
+{\
+\ # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are\
+\ # positional parameters, so assign one to ordinary parameter first.\
+\ func_stripname_result=${3}\
+\ func_stripname_result=${func_stripname_result#"${1}"}\
+\ func_stripname_result=${func_stripname_result%"${2}"}\
+} # Extended-shell func_stripname implementation' "$cfgfile" > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+ sed -e '/^func_split_long_opt ()$/,/^} # func_split_long_opt /c\
+func_split_long_opt ()\
+{\
+\ func_split_long_opt_name=${1%%=*}\
+\ func_split_long_opt_arg=${1#*=}\
+} # Extended-shell func_split_long_opt implementation' "$cfgfile" > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+ sed -e '/^func_split_short_opt ()$/,/^} # func_split_short_opt /c\
+func_split_short_opt ()\
+{\
+\ func_split_short_opt_arg=${1#??}\
+\ func_split_short_opt_name=${1%"$func_split_short_opt_arg"}\
+} # Extended-shell func_split_short_opt implementation' "$cfgfile" > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+ sed -e '/^func_lo2o ()$/,/^} # func_lo2o /c\
+func_lo2o ()\
+{\
+\ case ${1} in\
+\ *.lo) func_lo2o_result=${1%.lo}.${objext} ;;\
+\ *) func_lo2o_result=${1} ;;\
+\ esac\
+} # Extended-shell func_lo2o implementation' "$cfgfile" > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+ sed -e '/^func_xform ()$/,/^} # func_xform /c\
+func_xform ()\
+{\
+ func_xform_result=${1%.*}.lo\
+} # Extended-shell func_xform implementation' "$cfgfile" > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+ sed -e '/^func_arith ()$/,/^} # func_arith /c\
+func_arith ()\
+{\
+ func_arith_result=$(( $* ))\
+} # Extended-shell func_arith implementation' "$cfgfile" > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+ sed -e '/^func_len ()$/,/^} # func_len /c\
+func_len ()\
+{\
+ func_len_result=${#1}\
+} # Extended-shell func_len implementation' "$cfgfile" > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+fi
+
+if test x"$lt_shell_append" = xyes; then
+ sed -e '/^func_append ()$/,/^} # func_append /c\
+func_append ()\
+{\
+ eval "${1}+=\\${2}"\
+} # Extended-shell func_append implementation' "$cfgfile" > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+ sed -e '/^func_append_quoted ()$/,/^} # func_append_quoted /c\
+func_append_quoted ()\
+{\
+\ func_quote_for_eval "${2}"\
+\ eval "${1}+=\\\\ \\$func_quote_for_eval_result"\
+} # Extended-shell func_append_quoted implementation' "$cfgfile" > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+ # Save a `func_append' function call where possible by direct use of '+='
+ sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+ test 0 -eq $? || _lt_function_replace_fail=:
+else
+ # Save a `func_append' function call even when '+=' is not available
+ sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+ test 0 -eq $? || _lt_function_replace_fail=:
+fi
+
+if test x"$_lt_function_replace_fail" = x":"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Unable to substitute extended shell functions in $ofile" >&5
+$as_echo "$as_me: WARNING: Unable to substitute extended shell functions in $ofile" >&2;}
+fi
+
+
+ mv -f "$cfgfile" "$ofile" ||
+ (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile")
+ chmod +x "$ofile"
+
+ ;;
+
+ esac
+done # for ac_tag
+
+
+as_fn_exit 0
+_ACEOF
+ac_clean_files=$ac_clean_files_save
+
+test $ac_write_fail = 0 ||
+ as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5
+
+
+# configure is writing to config.log, and then calls config.status.
+# config.status does its own redirection, appending to config.log.
+# Unfortunately, on DOS this fails, as config.log is still kept open
+# by configure, so config.status won't be able to write to it; its
+# output is simply discarded. So we exec the FD to /dev/null,
+# effectively closing config.log, so it can be properly (re)opened and
+# appended to by config.status. When coming back to configure, we
+# need to make the FD available again.
+if test "$no_create" != yes; then
+ ac_cs_success=:
+ ac_config_status_args=
+ test "$silent" = yes &&
+ ac_config_status_args="$ac_config_status_args --quiet"
+ exec 5>/dev/null
+ $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
+ exec 5>>config.log
+ # Use ||, not &&, to avoid exiting from the if with $? = 1, which
+ # would make configure fail if this is the last instruction.
+ $ac_cs_success || as_fn_exit 1
+fi
+if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5
+$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: " >&5
+$as_echo "" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $PACKAGE configuration:" >&5
+$as_echo "$PACKAGE configuration:" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: Version = ${VERSION}" >&5
+$as_echo " Version = ${VERSION}" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: Prefix = ${prefix}" >&5
+$as_echo " Prefix = ${prefix}" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: Executables = ${sbindir}" >&5
+$as_echo " Executables = ${sbindir}" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: Man pages = ${mandir}" >&5
+$as_echo " Man pages = ${mandir}" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: Doc dir = ${docdir}" >&5
+$as_echo " Doc dir = ${docdir}" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: Libraries = ${libdir}" >&5
+$as_echo " Libraries = ${libdir}" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: Header files = ${includedir}" >&5
+$as_echo " Header files = ${includedir}" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: Arch-independent files = ${datadir}" >&5
+$as_echo " Arch-independent files = ${datadir}" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: State information = ${localstatedir}" >&5
+$as_echo " State information = ${localstatedir}" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: System configuration = ${sysconfdir}" >&5
+$as_echo " System configuration = ${sysconfdir}" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: System init.d directory = ${INITDDIR}" >&5
+$as_echo " System init.d directory = ${INITDDIR}" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: System systemd directory = ${SYSTEMDDIR}" >&5
+$as_echo " System systemd directory = ${SYSTEMDDIR}" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: Log directory = ${LOGDIR}" >&5
+$as_echo " Log directory = ${LOGDIR}" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: Log rotate directory = ${LOGROTATEDIR}" >&5
+$as_echo " Log rotate directory = ${LOGROTATEDIR}" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: corosync config dir = ${COROSYSCONFDIR}" >&5
+$as_echo " corosync config dir = ${COROSYSCONFDIR}" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: init config directory = ${INITCONFIGDIR}" >&5
+$as_echo " init config directory = ${INITCONFIGDIR}" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: Features =${PACKAGE_FEATURES}" >&5
+$as_echo " Features =${PACKAGE_FEATURES}" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: Rust bindings = ${enable_rust_bindings}" >&5
+$as_echo " Rust bindings = ${enable_rust_bindings}" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: " >&5
+$as_echo "" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $PACKAGE build info:" >&5
+$as_echo "$PACKAGE build info:" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: Library SONAME = ${SONAME}" >&5
+$as_echo " Library SONAME = ${SONAME}" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: CFG Library SONAME = ${CFG_SONAME}" >&5
+$as_echo " CFG Library SONAME = ${CFG_SONAME}" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: CPG Library SONAME = ${CPG_SONAME}" >&5
+$as_echo " CPG Library SONAME = ${CPG_SONAME}" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: QUORUM Library SONAME = ${QUORUM_SONAME}" >&5
+$as_echo " QUORUM Library SONAME = ${QUORUM_SONAME}" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: SAM Library SONAME = ${SAM_SONAME}" >&5
+$as_echo " SAM Library SONAME = ${SAM_SONAME}" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: VOTEQUORUM Library SONAME = ${VOTEQUORUM_SONAME}" >&5
+$as_echo " VOTEQUORUM Library SONAME = ${VOTEQUORUM_SONAME}" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: CMAP Library SONAME = ${CMAP_SONAME}" >&5
+$as_echo " CMAP Library SONAME = ${CMAP_SONAME}" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: Default optimization = ${OPT_CFLAGS}" >&5
+$as_echo " Default optimization = ${OPT_CFLAGS}" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: Default debug options = ${GDB_FLAGS}" >&5
+$as_echo " Default debug options = ${GDB_FLAGS}" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: Extra compiler warnings = ${EXTRA_WARNING}" >&5
+$as_echo " Extra compiler warnings = ${EXTRA_WARNING}" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: Env. defined CFLAG = ${ENV_CFLAGS}" >&5
+$as_echo " Env. defined CFLAG = ${ENV_CFLAGS}" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: Env. defined CPPFLAGS = ${ENV_CPPFLAGS}" >&5
+$as_echo " Env. defined CPPFLAGS = ${ENV_CPPFLAGS}" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: Env. defined LDFLAGS = ${ENV_LDFLAGS}" >&5
+$as_echo " Env. defined LDFLAGS = ${ENV_LDFLAGS}" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: ANSI defined CPPFLAGS = ${ANSI_CPPFLAGS}" >&5
+$as_echo " ANSI defined CPPFLAGS = ${ANSI_CPPFLAGS}" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: Coverage CFLAGS = ${COVERAGE_CFLAGS}" >&5
+$as_echo " Coverage CFLAGS = ${COVERAGE_CFLAGS}" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: Coverage LDFLAGS = ${COVERAGE_LDFLAGS}" >&5
+$as_echo " Coverage LDFLAGS = ${COVERAGE_LDFLAGS}" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: Fatal War. CFLAGS = ${WERROR_CFLAGS}" >&5
+$as_echo " Fatal War. CFLAGS = ${WERROR_CFLAGS}" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: Final CFLAGS = ${CFLAGS}" >&5
+$as_echo " Final CFLAGS = ${CFLAGS}" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: Final CPPFLAGS = ${CPPFLAGS}" >&5
+$as_echo " Final CPPFLAGS = ${CPPFLAGS}" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: Final LDFLAGS = ${LDFLAGS}" >&5
+$as_echo " Final LDFLAGS = ${LDFLAGS}" >&6; }
diff --git a/configure.ac b/configure.ac
new file mode 100644
index 0000000..7a9e420
--- /dev/null
+++ b/configure.ac
@@ -0,0 +1,842 @@
+# -*- Autoconf -*-
+# Process this file with autoconf to produce a configure script.
+
+# bootstrap / init
+AC_PREREQ([2.69])
+
+AC_INIT([corosync],
+ [m4_esyscmd([build-aux/git-version-gen .tarball-version .gitarchivever])],
+ [users@clusterlabs.org])
+
+AC_USE_SYSTEM_EXTENSIONS
+
+AM_INIT_AUTOMAKE([foreign 1.11])
+
+LT_PREREQ([2.2.6])
+LT_INIT
+
+AM_SILENT_RULES([yes])
+
+AC_CONFIG_SRCDIR([lib/cpg.c])
+AC_CONFIG_HEADERS([include/corosync/config.h])
+AC_CONFIG_MACRO_DIR([m4])
+
+AC_CANONICAL_HOST
+
+AC_LANG([C])
+
+AC_SUBST(WITH_LIST, [""])
+
+#Enable inter-library dependencies
+AC_ARG_ENABLE(interlib-deps,
+ [AS_HELP_STRING([--disable-interlib-deps ],[disable inter-library dependencies (might break builds)])],
+ [enable_interlib_deps="$enableval"],
+ [enable_interlib_deps="yes"])
+
+AC_MSG_NOTICE([enable inter-library dependencies: $enable_interlib_deps])
+if test "x${enable_interlib_deps}" = "xyes"; then
+ link_all_deplibs=yes
+ link_all_deplibs_CXX=yes
+else
+ link_all_deplibs=no
+ link_all_deplibs_CXX=no
+fi
+
+AC_ARG_ENABLE([rust-bindings],
+ [AS_HELP_STRING([--enable-rust-bindings],[rust bindings support])],,
+ [ enable_rust_bindings="no" ])
+AM_CONDITIONAL([BUILD_RUST_BINDINGS], [test x$enable_rust_bindings = xyes])
+corosyncrustver="`echo ${VERSION} | sed 's/\(.*\)\./\1-/'`"
+AC_SUBST([corosyncrustver])
+
+dnl Fix default variables - "prefix" variable if not specified
+systemddir=${prefix}/lib/systemd/system
+
+if test "$prefix" = "NONE"; then
+ prefix="/usr"
+
+ dnl Fix "localstatedir" variable if not specified
+ if test "$localstatedir" = "\${prefix}/var"; then
+ localstatedir="/var"
+ fi
+ dnl Fix "sysconfdir" variable if not specified
+ if test "$sysconfdir" = "\${prefix}/etc"; then
+ sysconfdir="/etc"
+ fi
+ if test "$systemddir" = "NONE/lib/systemd/system"; then
+ systemddir=/lib/systemd/system
+ fi
+ dnl Fix "libdir" variable if not specified
+ if test "$libdir" = "\${exec_prefix}/lib"; then
+ if test -e /usr/lib64; then
+ libdir="/usr/lib64"
+ else
+ libdir="/usr/lib"
+ fi
+ fi
+fi
+
+AC_MSG_NOTICE(Sanitizing exec_prefix: ${exec_prefix})
+case $exec_prefix in
+ dnl For consistency with Corosync, map NONE->$prefix
+ 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
+
+sinclude(corosync-default.m4)
+
+AC_PROG_CC
+m4_version_prereq([2.70], [:], [AC_PROG_CC_C99])
+if test "x$ac_cv_prog_cc_c99" = "xno"; then
+ AC_MSG_ERROR(["C99 support is required"])
+fi
+AC_PROG_INSTALL
+AC_PROG_LN_S
+AC_PROG_MAKE_SET
+AC_PROG_SED
+PKG_PROG_PKG_CONFIG
+
+AC_CHECK_PROGS([GROFF], [groff])
+AC_CHECK_PROGS([AUGTOOL], [augtool])
+AC_CHECK_PROGS([DOT], [dot])
+AC_CHECK_PROGS([DOXYGEN], [doxygen])
+AC_CHECK_PROGS([AWK], [awk])
+AC_PATH_PROG([BASHPATH], [bash])
+
+# Checks for compiler characteristics.
+AC_PROG_GCC_TRADITIONAL
+AC_C_CONST
+AC_C_INLINE
+AC_C_VOLATILE
+
+# Checks for header files.
+AC_HEADER_DIRENT
+AC_HEADER_SYS_WAIT
+AC_CHECK_HEADERS([arpa/inet.h fcntl.h limits.h netdb.h netinet/in.h stdint.h \
+ stdlib.h string.h sys/ioctl.h sys/param.h sys/socket.h \
+ sys/time.h syslog.h unistd.h sys/types.h getopt.h malloc.h \
+ utmpx.h ifaddrs.h stddef.h sys/file.h sys/uio.h])
+
+# Check entries in specific structs
+AC_CHECK_MEMBER([struct sockaddr_in.sin_len],
+ [AC_DEFINE_UNQUOTED([HAVE_SOCK_SIN_LEN], [1], [sockaddr_in needs sin_len])],
+ [], [[#include <netinet/in.h>]])
+AC_CHECK_MEMBER([struct sockaddr_in6.sin6_len],
+ [AC_DEFINE_UNQUOTED([HAVE_SOCK_SIN6_LEN], [1], [sockaddr_in6 needs sin6_len])],
+ [], [[#include <netinet/in.h>]])
+AC_CHECK_MEMBER([struct msghdr.msg_control],
+ [AC_DEFINE_UNQUOTED([HAVE_MSGHDR_CONTROL], [1], [msghdr has msg_control])],
+ [], [[#include <sys/socket.h>]])
+AC_CHECK_MEMBER([struct msghdr.msg_controllen],
+ [AC_DEFINE_UNQUOTED([HAVE_MSGHDR_CONTROLLEN], [1], [msghdr has msg_controllen])],
+ [], [[#include <sys/socket.h>]])
+AC_CHECK_MEMBER([struct msghdr.msg_flags],
+ [AC_DEFINE_UNQUOTED([HAVE_MSGHDR_FLAGS], [1], [msghdr has msg_flags])],
+ [], [[#include <sys/socket.h>]])
+AC_CHECK_MEMBER([struct msghdr.msg_accrights],
+ [AC_DEFINE_UNQUOTED([HAVE_MSGHDR_ACCRIGHTS], [1], [msghdr has msg_accrights])],
+ [], [[#include <sys/socket.h>]])
+AC_CHECK_MEMBER([struct msghdr.msg_accrightslen],
+ [AC_DEFINE_UNQUOTED([HAVE_MSGHDR_ACCRIGHTSLEN], [1], [msghdr has msg_accrightslen])],
+ [], [[#include <sys/socket.h>]])
+
+# Checks for typedefs.
+AC_TYPE_UID_T
+AC_TYPE_INT16_T
+AC_TYPE_INT32_T
+AC_TYPE_INT64_T
+AC_TYPE_INT8_T
+AC_TYPE_UINT16_T
+AC_TYPE_UINT32_T
+AC_TYPE_UINT64_T
+AC_TYPE_UINT8_T
+AC_TYPE_SIZE_T
+AC_TYPE_SSIZE_T
+
+# Checks for libraries.
+SAVE_CPPFLAGS="$CPPFLAGS"
+SAVE_LIBS="$LIBS"
+PKG_CHECK_MODULES([LIBQB], [libqb])
+CPPFLAGS="$CPPFLAGS $LIBQB_CFLAGS"
+LIBS="$LIBS $LIBQB_LIBS"
+AC_CHECK_LIB([qb], [qb_log_thread_priority_set], \
+ have_qb_log_thread_priority_set="yes", \
+ have_qb_log_thread_priority_set="no")
+if test "x${have_qb_log_thread_priority_set}" = xyes; then
+ AC_DEFINE_UNQUOTED([HAVE_QB_LOG_THREAD_PRIORITY_SET], 1, [have qb_log_thread_priority_set])
+fi
+AC_CHECK_LIB([qb], [qb_log_file_reopen], \
+ have_qb_log_file_reopen="yes", \
+ have_qb_log_file_reopen="no")
+if test "x${have_qb_log_file_reopen}" = xyes; then
+ AC_DEFINE_UNQUOTED([HAVE_QB_LOG_FILE_REOPEN], 1, [have qb_log_file_reopen])
+fi
+AM_CONDITIONAL(HAVE_QB_LOG_FILE_REOPEN, test x$have_qb_log_file_reopen = xyes)
+
+CPPFLAGS="$SAVE_CPPFLAGS"
+LIBS="$SAVE_LIBS"
+AC_CHECK_LIB([pthread], [pthread_create])
+AC_CHECK_LIB([socket], [socket])
+PKG_CHECK_MODULES([knet],[libknet])
+AC_CHECK_LIB([nsl], [t_open])
+AC_CHECK_LIB([rt], [sched_getscheduler])
+AC_CHECK_LIB([z], [crc32],
+ AM_CONDITIONAL([HAVE_CRC32], true),
+ AM_CONDITIONAL([HAVE_CRC32], false))
+
+# this hack is necessary to check for symbols on out of tree builds
+# but it is as horrible as it gets and in theory users should be
+# invoking ./configure with proper LIBRARY_PATH set.
+OLDLIBS="$LIBS"
+LIBS="$knet_LIBS $LIBS"
+AC_CHECK_LIB([knet],[knet_handle_enable_access_lists],
+ [AC_DEFINE_UNQUOTED([HAVE_KNET_ACCESS_LIST], 1, [have knet access list])])
+AC_CHECK_LIB([knet],[knet_handle_crypto_set_config],
+ [AC_DEFINE_UNQUOTED([HAVE_KNET_CRYPTO_RECONF], 1, [have knet crypto reconfig support])])
+AC_CHECK_LIB([knet],[knet_handle_get_onwire_ver],
+ [AC_DEFINE_UNQUOTED([HAVE_KNET_ONWIRE_VER], 1, [have knet onwire versioning])])
+LIBS="$OLDLIBS"
+
+# Checks for library functions.
+AC_FUNC_ALLOCA
+AC_FUNC_CLOSEDIR_VOID
+AC_FUNC_ERROR_AT_LINE
+AC_FUNC_FORK
+AC_FUNC_MALLOC
+AC_FUNC_MEMCMP
+AC_FUNC_MMAP
+AC_FUNC_REALLOC
+AC_FUNC_SELECT_ARGTYPES
+AC_FUNC_VPRINTF
+
+AC_CHECK_FUNCS([alarm alphasort atexit bzero dup2 endgrent endpwent fdatasync \
+ fcntl getcwd getpeerucred getpeereid gettimeofday inet_ntoa \
+ memmove memset mkdir scandir select socket strcasecmp strchr \
+ strdup strerror strrchr strspn strstr pthread_setschedparam \
+ sched_get_priority_max sched_setscheduler getifaddrs \
+ clock_gettime ftruncate gethostname localtime_r munmap strtol])
+
+AC_CONFIG_FILES([Makefile
+ exec/Makefile
+ include/Makefile
+ init/Makefile
+ lib/Makefile
+ common_lib/Makefile
+ man/Makefile
+ pkgconfig/Makefile
+ test/Makefile
+ tools/Makefile
+ conf/Makefile
+ vqsim/Makefile
+ Doxyfile
+ conf/logrotate/Makefile
+ bindings/Makefile
+ bindings/rust/Makefile
+ bindings/rust/tests/Makefile
+ bindings/rust/Cargo.toml
+ bindings/rust/tests/Cargo.toml])
+
+### Local business
+
+# check for rust tools to build bindings
+if test "x$enable_rust_bindings" = "xyes"; then
+ AC_PATH_PROG([CARGO], [cargo], [no])
+ if test "x$CARGO" = xno; then
+ AC_MSG_ERROR(["cargo command not found"])
+ fi
+
+ AC_PATH_PROG([RUSTC], [rustc], [no])
+ if test "x$RUSTC" = xno; then
+ AC_MSG_ERROR(["rustc command not found"])
+ fi
+
+ AC_PATH_PROG([RUSTDOC], [rustdoc], [no])
+ if test "x$RUSTDOC" = xno; then
+ AC_MSG_ERROR(["rustdoc command not found"])
+ fi
+
+ AC_PATH_PROG([BINDGEN], [bindgen], [no])
+ if test "x$BINDGEN" = xno; then
+ AC_MSG_ERROR(["bindgen command not found"])
+ fi
+
+ AC_PATH_PROG([CLIPPY], [clippy-driver], [no])
+ if test "x$CLIPPY" = xno; then
+ AC_MSG_ERROR(["clippy-driver command not found"])
+ fi
+
+ AC_PATH_PROG([RUSTFMT], [rustfmt], [no])
+ if test "x$RUSTFMT" = xno; then
+ AC_MSG_ERROR(["rustfmt command not found"])
+ fi
+fi
+
+dnl ===============================================
+dnl Functions / global M4 variables
+dnl ===============================================
+dnl Global list of LIB names
+m4_define([local_soname_list], [])dnl
+
+dnl Upcase parameter
+m4_define([local_upcase], [translit([$*], [a-z], [A-Z])])dnl
+
+dnl M4 macro for include lib/lib$1.soname and subst that
+m4_define([LIB_SONAME_IMPORT],[dnl
+m4_define([local_libname], local_upcase($1)[_SONAME])dnl
+m4_define([local_soname], translit(m4_sinclude(lib/lib$1.verso), [
+], []))dnl
+local_libname="local_soname"dnl
+m4_define([local_soname_list], m4_defn([local_soname_list])[,]local_libname[,]local_upcase($1))dnl
+AC_SUBST(local_libname)dnl
+])dnl
+
+dnl M4 macro for print padspaces (used in LIB_MSG_RESULT). It takes 2 arguments, length of string to pad and desired
+dnl (padded) length
+m4_define([m4_printpadspace],[ifelse(m4_eval([$2 - $1 < 1]),[1],,[ ][m4_printpadspace([$1],m4_eval([$2 - 1]))])])dnl
+
+dnl Show AC_MSG_RESULT for specific libraries
+m4_define([LIB_MSG_RESULT], [ifelse([$#], [1], ,[dnl
+AC_MSG_RESULT([ $2 Library SONAME m4_printpadspace(len($2),8) = ${$1}])
+LIB_MSG_RESULT(m4_shift(m4_shift($@)))dnl
+])])dnl
+
+# ===============================================
+# Helpers
+# ===============================================
+
+## check if the compiler supports -Werror -Wunknown-warning-option
+AC_MSG_CHECKING([whether $CC supports -Wunknown-warning-option -Werror])
+BACKUP="$CPPFLAGS"
+CPPFLAGS="$CPPFLAGS -Werror -Wunknown-warning-option"
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([])],
+ [unknown_warnings_as_errors='-Wunknown-warning-option -Werror'; AC_MSG_RESULT([yes])],
+ [unknown_warnings_as_errors=''; AC_MSG_RESULT([no])])
+CPPFLAGS="$BACKUP"
+
+## helper for CC stuff
+cc_supports_flag() {
+ BACKUP="$CPPFLAGS"
+ CPPFLAGS="$CPPFLAGS $@ $unknown_warnings_as_errors"
+ AC_MSG_CHECKING([whether $CC supports "$@"])
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([])],
+ [RC=0; AC_MSG_RESULT([yes])],
+ [RC=1; AC_MSG_RESULT([no])])
+ CPPFLAGS="$BACKUP"
+ return $RC
+}
+
+## local defines
+PACKAGE_FEATURES=""
+
+LINT_FLAGS="-weak -unrecog +posixlib +ignoresigns -fcnuse \
+ -badflag -D__gnuc_va_list=va_list -D__attribute\(x\)="
+
+# default libraries SONAME
+SOMAJOR="5"
+SOMINOR="0"
+SOMICRO="0"
+SONAME="${SOMAJOR}.${SOMINOR}.${SOMICRO}"
+
+# specific libraries SONAME
+LIB_SONAME_IMPORT([cfg])
+LIB_SONAME_IMPORT([cpg])
+LIB_SONAME_IMPORT([quorum])
+LIB_SONAME_IMPORT([sam])
+LIB_SONAME_IMPORT([votequorum])
+LIB_SONAME_IMPORT([cmap])
+
+# local options
+AC_ARG_ENABLE([ansi],
+ [ --enable-ansi : force to build with ANSI standards. ],
+ [ default="no" ])
+
+AC_ARG_ENABLE([fatal-warnings],
+ [ --enable-fatal-warnings : enable fatal warnings. ],
+ [ default="no" ])
+
+AC_ARG_ENABLE([debug],
+ [ --enable-debug : enable debug build. ],
+ [ default="no" ])
+
+AC_ARG_WITH([sanitizers],
+ [AS_HELP_STRING([--with-sanitizers=...,...],
+ [enable SANitizer build, do *NOT* use for production. Only ASAN/UBSAN/TSAN are currently supported])],
+ [ SANITIZERS="$withval" ],
+ [ SANITIZERS="" ])
+
+AC_ARG_ENABLE([secure-build],
+ [ --enable-secure-build : enable PIE/RELRO build. ],
+ [],
+ [enable_secure_build="yes"])
+
+AC_ARG_ENABLE([user-flags],
+ [ --enable-user-flags : rely on user environment. ],
+ [ default="no" ])
+
+AC_ARG_ENABLE([coverage],
+ [ --enable-coverage : coverage analysis of the codebase. ],
+ [ default="no" ])
+
+AC_ARG_ENABLE([small-memory-footprint],
+ [ --enable-small-memory-footprint : Use small message queues and small messages sizes. ],
+ [ default="no" ])
+
+AC_ARG_ENABLE([dbus],
+ [ --enable-dbus : dbus events. ],,
+ [ enable_dbus="no" ])
+
+AC_ARG_ENABLE([monitoring],
+ [ --enable-monitoring : resource monitoring ],,
+ [ default="no" ])
+AM_CONDITIONAL(BUILD_MONITORING, test x$enable_monitoring = xyes)
+
+AC_ARG_ENABLE([watchdog],
+ [ --enable-watchdog : Watchdog support ],,
+ [ default="no" ])
+AM_CONDITIONAL(BUILD_WATCHDOG, test x$enable_watchdog = xyes)
+
+AC_ARG_ENABLE([augeas],
+ [ --enable-augeas : Install the augeas lens for corosync.conf ],,
+ [ enable_augeas="no" ])
+AM_CONDITIONAL(INSTALL_AUGEAS, test x$enable_augeas = xyes)
+
+AC_ARG_ENABLE([systemd],
+ [ --enable-systemd : Install systemd service files],,
+ [ enable_systemd="no" ])
+AM_CONDITIONAL(INSTALL_SYSTEMD, test x$enable_systemd = xyes)
+
+AC_ARG_WITH([initconfigdir],
+ [AS_HELP_STRING([--with-initconfigdir=DIR],
+ [configuration directory @<:@SYSCONFDIR/sysconfig@:>@])],
+ [INITCONFIGDIR="$withval"],
+ [INITCONFIGDIR='${sysconfdir}/sysconfig'])
+AC_SUBST([INITCONFIGDIR])
+
+AC_ARG_WITH([initddir],
+ [ --with-initddir=DIR : path to init script directory. ],
+ [ INITDDIR="$withval" ],
+ [ INITDDIR="$sysconfdir/init.d" ])
+
+AC_ARG_WITH([systemddir],
+ [ --with-systemddir=DIR : path to systemd unit files directory. ],
+ [ SYSTEMDDIR="$withval" ],
+ [ SYSTEMDDIR="$systemddir" ])
+
+AC_ARG_WITH([logdir],
+ [ --with-logdir=DIR : the base directory for corosync logging files. ],
+ [ LOGDIR="$withval" ],
+ [ LOGDIR="$localstatedir/log/cluster" ])
+
+AC_ARG_WITH([logrotatedir],
+ [ --with-logrotatedir=DIR : the base directory for logrorate.d files. ],
+ [ LOGROTATEDIR="$withval" ],
+ [ LOGROTATEDIR="$sysconfdir/logrotate.d" ])
+
+AC_ARG_ENABLE([snmp],
+ [ --enable-snmp : SNMP protocol support ],
+ [ default="no" ])
+
+AC_ARG_ENABLE([xmlconf],
+ [ --enable-xmlconf : XML configuration support ],,
+ [ enable_xmlconf="no" ])
+AM_CONDITIONAL(INSTALL_XMLCONF, test x$enable_xmlconf = xyes)
+
+AC_ARG_ENABLE([vqsim],
+ [ --enable-vqsim : Quorum simulator support ],,
+ [ enable_vqsim="no" ])
+AM_CONDITIONAL(BUILD_VQSIM, test x$enable_vqsim = xyes)
+
+AC_ARG_ENABLE([nozzle],
+ [ --enable-nozzle : Support for nozzle ],,
+ [ enable_nozzle="no" ])
+
+# *FLAGS handling goes here
+
+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"
+ PACKAGE_FEATURES="$PACKAGE_FEATURES debug"
+ RUST_FLAGS=""
+ RUST_TARGET_DIR="debug"
+else
+ OPT_CFLAGS="-O3"
+ RUST_FLAGS="--release"
+ RUST_TARGET_DIR="release"
+fi
+
+# gdb flags
+if test "x${GCC}" = xyes; then
+ GDB_FLAGS="-ggdb3"
+else
+ GDB_FLAGS="-g"
+fi
+
+# --- ASAN/UBSAN/TSAN (see man gcc) ---
+# when using SANitizers, we need to pass the -fsanitize..
+# to both CFLAGS and LDFLAGS. The CFLAGS/LDFLAGS must be
+# specified as first in the list or there will be runtime
+# issues (for example user has to LD_PRELOAD asan for it to work
+# properly).
+
+if test -n "${SANITIZERS}"; then
+ SANITIZERS=$(echo $SANITIZERS | sed -e 's/,/ /g')
+ for SANITIZER in $SANITIZERS; do
+ case $SANITIZER in
+ asan|ASAN)
+ SANITIZERS_CFLAGS="$SANITIZERS_CFLAGS -fsanitize=address"
+ SANITIZERS_LDFLAGS="$SANITIZERS_LDFLAGS -fsanitize=address -lasan"
+ AC_CHECK_LIB([asan],[main],,AC_MSG_ERROR([Unable to find libasan]))
+ ;;
+ ubsan|UBSAN)
+ SANITIZERS_CFLAGS="$SANITIZERS_CFLAGS -fsanitize=undefined"
+ SANITIZERS_LDFLAGS="$SANITIZERS_LDFLAGS -fsanitize=undefined -lubsan"
+ AC_CHECK_LIB([ubsan],[main],,AC_MSG_ERROR([Unable to find libubsan]))
+ ;;
+ tsan|TSAN)
+ SANITIZERS_CFLAGS="$SANITIZERS_CFLAGS -fsanitize=thread"
+ SANITIZERS_LDFLAGS="$SANITIZERS_LDFLAGS -fsanitize=thread -ltsan"
+ AC_CHECK_LIB([tsan],[main],,AC_MSG_ERROR([Unable to find libtsan]))
+ ;;
+ esac
+ done
+fi
+
+# Look for dbus-1
+if test "x${enable_dbus}" = xyes; then
+ PKG_CHECK_MODULES([DBUS],[dbus-1])
+ AC_DEFINE_UNQUOTED([HAVE_DBUS], 1, [have dbus])
+ PACKAGE_FEATURES="$PACKAGE_FEATURES dbus"
+ WITH_LIST="$WITH_LIST --with dbus"
+fi
+
+if test "x${enable_monitoring}" = xyes; then
+ PKG_CHECK_MODULES([statgrab], [libstatgrab])
+ PKG_CHECK_MODULES([statgrabge090], [libstatgrab >= 0.90],
+ AC_DEFINE_UNQUOTED([HAVE_LIBSTATGRAB_GE_090], 1, [have libstatgrab >= 0.90]),
+ TMP_VARIABLE=1)
+ AC_DEFINE_UNQUOTED([HAVE_MONITORING], 1, [have resource monitoring])
+ PACKAGE_FEATURES="$PACKAGE_FEATURES monitoring"
+ WITH_LIST="$WITH_LIST --with monitoring"
+fi
+
+if test "x${enable_watchdog}" = xyes; then
+ AC_CHECK_HEADER([linux/watchdog.h], [], [AC_MSG_ERROR([watchdog requires linux/watchdog.h])])
+ AC_CHECK_HEADER([linux/reboot.h], [], [AC_MSG_ERROR([watchdog requires linux/reboot.h])])
+ AC_DEFINE_UNQUOTED([HAVE_WATCHDOG], 1, [have watchdog])
+ PACKAGE_FEATURES="$PACKAGE_FEATURES watchdog"
+ WITH_LIST="$WITH_LIST --with watchdog"
+fi
+
+if test "x${enable_augeas}" = xyes; then
+ PACKAGE_FEATURES="$PACKAGE_FEATURES augeas"
+fi
+if test "x${enable_systemd}" = xyes; then
+ PKG_CHECK_MODULES([libsystemd], [libsystemd])
+ AC_DEFINE([HAVE_LIBSYSTEMD], [1], [have systemd interface library])
+ PACKAGE_FEATURES="$PACKAGE_FEATURES systemd"
+ WITH_LIST="$WITH_LIST --with systemd"
+fi
+if test "x${enable_xmlconf}" = xyes; then
+ PACKAGE_FEATURES="$PACKAGE_FEATURES xmlconf"
+ WITH_LIST="$WITH_LIST --with xmlconf"
+fi
+if test "x${enable_vqsim}" = xyes; then
+ vqsim_readline=no
+ AC_CHECK_HEADERS([readline/readline.h readline/history.h],
+ [],
+ AC_MSG_WARN([vqsim will lack readline support]))
+ PACKAGE_FEATURES="$PACKAGE_FEATURES vqsim"
+ WITH_LIST="$WITH_LIST --with vqsim"
+fi
+AM_CONDITIONAL(VQSIM_READLINE, [test "x${ac_cv_header_readline_readline_h}" = xyes])
+
+# Look for nozzle
+if test "x${enable_nozzle}" = xyes; then
+ PKG_CHECK_MODULES([nozzle],[libnozzle])
+ AC_DEFINE_UNQUOTED([HAVE_LIBNOZZLE], 1, [have nozzle])
+ PACKAGE_FEATURES="$PACKAGE_FEATURES nozzle"
+ WITH_LIST="$WITH_LIST --with nozzle"
+fi
+
+do_snmp=0
+if test "x${enable_snmp}" = xyes; then
+ AC_PATH_PROGS([SNMPCONFIG], [net-snmp-config])
+
+ if test "x${SNMPCONFIG}" != "x"; then
+ AC_MSG_CHECKING([for snmp includes])
+ SNMP_PREFIX=`$SNMPCONFIG --prefix`
+ SNMP_INCLUDES="-I$SNMP_PREFIX/include"
+ AC_MSG_RESULT([$SNMP_INCLUDES])
+
+ AC_MSG_CHECKING([for snmp libraries])
+ SNMP_LIBS=`$SNMPCONFIG --libs`
+ AC_MSG_RESULT([$SNMP_LIBS])
+ AC_SUBST([SNMP_LIBS])
+
+ saveCFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS $SNMP_INCLUDES"
+ AC_CHECK_HEADERS([net-snmp/net-snmp-config.h])
+ CFLAGS="$saveCFLAGS"
+
+ if test "x${ac_cv_header_net_snmp_net_snmp_config_h}" != "xyes"; then
+ AC_MSG_ERROR([Unable to use net-snmp/net-snmp-config.h])
+ fi
+
+ savedLibs=$LIBS
+ LIBS="$LIBS $SNMP_LIBS"
+ AC_CHECK_FUNCS([netsnmp_transport_open_client])
+ if test $ac_cv_func_netsnmp_transport_open_client != yes; then
+ AC_CHECK_FUNCS([netsnmp_tdomain_transport])
+ if test $ac_cv_func_netsnmp_tdomain_transport != yes; then
+ AC_MSG_ERROR([No usable SNMP client transport implementation found])
+ fi
+ else
+ AC_DEFINE_UNQUOTED([NETSNMPV54], $NETSNMP_NEW_SUPPORT, [have net-snmp5.4 over])
+ fi
+ LIBS=$savedLibs
+
+ do_snmp=1
+ PACKAGE_FEATURES="$PACKAGE_FEATURES snmp"
+ WITH_LIST="$WITH_LIST --with snmp"
+ AC_DEFINE_UNQUOTED([ENABLE_SNMP], $do_snmp, [Build in support for sending SNMP traps])
+ else
+ AC_MSG_ERROR([You need the net_snmp development package to continue.])
+ fi
+fi
+AM_CONDITIONAL(BUILD_SNMP, test "${do_snmp}" = "1")
+
+# extra warnings
+EXTRA_WARNINGS=""
+
+WARNLIST="
+ all
+ shadow
+ missing-prototypes
+ missing-declarations
+ strict-prototypes
+ pointer-arith
+ write-strings
+ cast-align
+ bad-function-cast
+ missing-format-attribute
+ format=2
+ format-security
+ format-nonliteral
+ no-long-long
+ unsigned-char
+ no-strict-aliasing
+ "
+
+for j in $WARNLIST; do
+ if cc_supports_flag -W$j; then
+ EXTRA_WARNINGS="$EXTRA_WARNINGS -W$j";
+ fi
+done
+
+if test "x${enable_coverage}" = xyes && \
+ cc_supports_flag -ftest-coverage && \
+ cc_supports_flag -fprofile-arcs ; then
+ AC_MSG_NOTICE([Enabling Coverage (enable -O0 by default)])
+ OPT_CFLAGS="-O0"
+ COVERAGE_CFLAGS="-ftest-coverage -fprofile-arcs"
+ COVERAGE_LDFLAGS="-ftest-coverage -fprofile-arcs"
+ PACKAGE_FEATURES="$PACKAGE_FEATURES coverage"
+else
+ COVERAGE_CFLAGS=""
+ COVERAGE_LDFLAGS=""
+fi
+
+if test "x${enable_small_memory_footprint}" = xyes ; then
+ AC_DEFINE_UNQUOTED([HAVE_SMALL_MEMORY_FOOTPRINT], 1, [have small_memory_footprint])
+ PACKAGE_FEATURES="$PACKAGE_FEATURES small-memory-footprint"
+fi
+
+if test "x${enable_ansi}" = xyes && \
+ cc_supports_flag -std=iso9899:199409 ; then
+ AC_MSG_NOTICE([Enabling ANSI Compatibility])
+ ANSI_CPPFLAGS="-ansi -DANSI_ONLY"
+ PACKAGE_FEATURES="$PACKAGE_FEATURES ansi"
+else
+ ANSI_CPPFLAGS=""
+fi
+
+if test "x${enable_fatal_warnings}" = xyes && \
+ cc_supports_flag -Werror ; then
+ AC_MSG_NOTICE([Enabling Fatal Warnings (-Werror)])
+ WERROR_CFLAGS="-Werror"
+ PACKAGE_FEATURES="$PACKAGE_FEATURES fatal-warnings"
+else
+ WERROR_CFLAGS=""
+fi
+
+# don't add addtional cflags
+if test "x${enable_user_flags}" = xyes; then
+ OPT_CFLAGS=""
+ GDB_FLAGS=""
+ EXTRA_WARNINGS=""
+fi
+
+if test "x${enable_secure_build}" = xyes; then
+ # stolen from apache configure snippet
+ AC_CACHE_CHECK([whether $CC accepts PIE flags], [ap_cv_cc_pie], [
+ save_CFLAGS=$CFLAGS
+ save_LDFLAGS=$LDFLAGS
+ CFLAGS="$CFLAGS -fPIE"
+ LDFLAGS="$LDFLAGS -pie"
+ AC_RUN_IFELSE([AC_LANG_SOURCE([[static int foo[30000]; int main () { return 0; }]])],
+ [ap_cv_cc_pie=yes], [ap_cv_cc_pie=no], [ap_cv_cc_pie=yes])
+ CFLAGS=$save_CFLAGS
+ LDFLAGS=$save_LDFLAGS
+ ])
+ if test "$ap_cv_cc_pie" = "yes"; then
+ SEC_FLAGS="$SEC_FLAGS -fPIE"
+ SEC_LDFLAGS="$SEC_LDFLAGS -pie"
+ PACKAGE_FEATURES="$PACKAGE_FEATURES pie"
+ fi
+
+ # similar to above
+ AC_CACHE_CHECK([whether $CC accepts RELRO flags], [ap_cv_cc_relro], [
+ save_LDFLAGS=$LDFLAGS
+ LDFLAGS="$LDFLAGS -Wl,-z,relro"
+ AC_RUN_IFELSE([AC_LANG_SOURCE([[static int foo[30000]; int main () { return 0; }]])],
+ [ap_cv_cc_relro=yes], [ap_cv_cc_relro=no], [ap_cv_cc_relro=yes])
+ LDFLAGS=$save_LDFLAGS
+ ])
+ if test "$ap_cv_cc_relro" = "yes"; then
+ SEC_LDFLAGS="$SEC_LDFLAGS -Wl,-z,relro"
+ PACKAGE_FEATURES="$PACKAGE_FEATURES relro"
+ fi
+
+ AC_CACHE_CHECK([whether $CC accepts BINDNOW flags], [ap_cv_cc_bindnow], [
+ save_LDFLAGS=$LDFLAGS
+ LDFLAGS="$LDFLAGS -Wl,-z,now"
+ AC_RUN_IFELSE([AC_LANG_SOURCE([[static int foo[30000]; int main () { return 0; }]])],
+ [ap_cv_cc_bindnow=yes], [ap_cv_cc_bindnow=no], [ap_cv_cc_bindnow=yes])
+ LDFLAGS=$save_LDFLAGS
+ ])
+ if test "$ap_cv_cc_bindnow" = "yes"; then
+ SEC_LDFLAGS="$SEC_LDFLAGS -Wl,-z,now"
+ PACKAGE_FEATURES="$PACKAGE_FEATURES bindnow"
+ fi
+fi
+
+AC_CACHE_CHECK([whether $CC accepts "--as-needed"], [ap_cv_cc_as_needed], [
+ save_LDFLAGS=$LDFLAGS
+ LDFLAGS="$LDFLAGS -Wl,--as-needed"
+ AC_RUN_IFELSE([AC_LANG_SOURCE([[static int foo[30000]; int main () { return 0; }]])],
+ [ap_cv_cc_as_needed=yes], [ap_cv_cc_as_needed=no], [ap_cv_cc_as_needed=yes])
+ LDFLAGS=$save_LDFLAGS
+])
+
+AC_CACHE_CHECK([whether $CC accepts "--version-script"], [ap_cv_cc_version_script], [
+ save_LDFLAGS=$LDFLAGS
+ LDFLAGS="$LDFLAGS -Wl,--version-script=conftest.versions"
+ echo "CONFTEST { };" >conftest.versions
+ AC_RUN_IFELSE([AC_LANG_SOURCE([[static int foo[30000]; int main () { return 0; }]])],
+ [ap_cv_cc_version_script=yes], [ap_cv_cc_version_script=no], [ap_cv_cc_version_script=yes])
+ rm -f conftest.versions
+ LDFLAGS=$save_LDFLAGS
+])
+if test "$ap_cv_cc_version_script" = "yes"; then
+ AC_SUBST(VERSCRIPT_LDFLAGS, ["-Wl,--version-script=\$(srcdir)/lib\$(call get_libname,\$<).versions"])
+else
+ AC_SUBST(VERSCRIPT_LDFLAGS, [""])
+fi
+
+# define global include dirs
+INCLUDE_DIRS="$INCLUDE_DIRS -I\$(top_builddir)/include -I\$(top_srcdir)/include"
+INCLUDE_DIRS="$INCLUDE_DIRS -I\$(top_builddir)/include/corosync -I\$(top_srcdir)/include/corosync"
+
+# final build of *FLAGS
+CFLAGS="$SANITIZERS_CFLAGS $ENV_CFLAGS $lt_prog_compiler_pic $SEC_FLAGS $OPT_CFLAGS $GDB_FLAGS \
+ $COVERAGE_CFLAGS $EXTRA_WARNINGS \
+ $WERROR_CFLAGS $LIBQB_CFLAGS \
+ $SNMP_INCLUDES"
+CPPFLAGS="$ENV_CPPFLAGS $ANSI_CPPFLAGS $INCLUDE_DIRS"
+LDFLAGS="$SANITIZERS_LDFLAGS $ENV_LDFLAGS $lt_prog_compiler_pic $SEC_LDFLAGS $COVERAGE_LDFLAGS"
+
+if test "$ap_cv_cc_as_needed" = "yes"; then
+ LDFLAGS="$LDFLAGS -Wl,--as-needed"
+fi
+
+# substitute what we need:
+AC_SUBST([BASHPATH])
+AC_SUBST([INITDDIR])
+AC_SUBST([SYSTEMDDIR])
+AC_SUBST([LOGDIR])
+AC_SUBST([LOGROTATEDIR])
+
+AC_SUBST([SOMAJOR])
+AC_SUBST([SOMINOR])
+AC_SUBST([SOMICRO])
+AC_SUBST([SONAME])
+AC_SUBST([RUST_FLAGS])
+AC_SUBST([RUST_TARGET_DIR])
+
+AM_CONDITIONAL(INSTALL_MIB, test "${do_snmp}" = "1")
+AM_CONDITIONAL(INSTALL_DBUSCONF, test "${enable_dbus}" = "yes")
+AM_CONDITIONAL(AUGTOOL, test -n "${AUGTOOL}")
+
+AM_CONDITIONAL(BUILD_HTML_DOCS, test -n "${GROFF}")
+
+AC_SUBST([LINT_FLAGS])
+
+AC_DEFINE_UNQUOTED([LOCALSTATEDIR], "$(eval echo ${localstatedir})", [localstate directory])
+
+COROSYSCONFDIR=${sysconfdir}/corosync
+AC_SUBST([COROSYSCONFDIR])
+AC_DEFINE_UNQUOTED([COROSYSCONFDIR], "$(eval echo ${COROSYSCONFDIR})", [corosync config directory])
+
+AC_DEFINE_UNQUOTED([PACKAGE_FEATURES], "${PACKAGE_FEATURES}", [corosync built-in features])
+
+AC_OUTPUT
+
+AC_MSG_RESULT([])
+AC_MSG_RESULT([$PACKAGE configuration:])
+AC_MSG_RESULT([ Version = ${VERSION}])
+AC_MSG_RESULT([ Prefix = ${prefix}])
+AC_MSG_RESULT([ Executables = ${sbindir}])
+AC_MSG_RESULT([ Man pages = ${mandir}])
+AC_MSG_RESULT([ Doc dir = ${docdir}])
+AC_MSG_RESULT([ Libraries = ${libdir}])
+AC_MSG_RESULT([ Header files = ${includedir}])
+AC_MSG_RESULT([ Arch-independent files = ${datadir}])
+AC_MSG_RESULT([ State information = ${localstatedir}])
+AC_MSG_RESULT([ System configuration = ${sysconfdir}])
+AC_MSG_RESULT([ System init.d directory = ${INITDDIR}])
+AC_MSG_RESULT([ System systemd directory = ${SYSTEMDDIR}])
+AC_MSG_RESULT([ Log directory = ${LOGDIR}])
+AC_MSG_RESULT([ Log rotate directory = ${LOGROTATEDIR}])
+AC_MSG_RESULT([ corosync config dir = ${COROSYSCONFDIR}])
+AC_MSG_RESULT([ init config directory = ${INITCONFIGDIR}])
+AC_MSG_RESULT([ Features =${PACKAGE_FEATURES}])
+AC_MSG_RESULT([ Rust bindings = ${enable_rust_bindings}])
+AC_MSG_RESULT([])
+AC_MSG_RESULT([$PACKAGE build info:])
+AC_MSG_RESULT([ Library SONAME = ${SONAME}])
+LIB_MSG_RESULT(m4_shift(local_soname_list))dnl
+AC_MSG_RESULT([ Default optimization = ${OPT_CFLAGS}])
+AC_MSG_RESULT([ Default debug options = ${GDB_FLAGS}])
+AC_MSG_RESULT([ Extra compiler warnings = ${EXTRA_WARNING}])
+AC_MSG_RESULT([ Env. defined CFLAG = ${ENV_CFLAGS}])
+AC_MSG_RESULT([ Env. defined CPPFLAGS = ${ENV_CPPFLAGS}])
+AC_MSG_RESULT([ Env. defined LDFLAGS = ${ENV_LDFLAGS}])
+AC_MSG_RESULT([ ANSI defined CPPFLAGS = ${ANSI_CPPFLAGS}])
+AC_MSG_RESULT([ Coverage CFLAGS = ${COVERAGE_CFLAGS}])
+AC_MSG_RESULT([ Coverage LDFLAGS = ${COVERAGE_LDFLAGS}])
+AC_MSG_RESULT([ Fatal War. CFLAGS = ${WERROR_CFLAGS}])
+AC_MSG_RESULT([ Final CFLAGS = ${CFLAGS}])
+AC_MSG_RESULT([ Final CPPFLAGS = ${CPPFLAGS}])
+AC_MSG_RESULT([ Final LDFLAGS = ${LDFLAGS}])
diff --git a/corosync.spec.in b/corosync.spec.in
new file mode 100644
index 0000000..256442b
--- /dev/null
+++ b/corosync.spec.in
@@ -0,0 +1,305 @@
+@ALPHATAG@
+@NUMCOMM@
+@DIRTY@
+
+# Conditionals
+# Invoke "rpmbuild --without <feature>" or "rpmbuild --with <feature>"
+# to disable or enable specific features
+%bcond_with watchdog
+%bcond_with monitoring
+%bcond_with snmp
+%bcond_with dbus
+%bcond_with systemd
+%bcond_with xmlconf
+%bcond_with nozzle
+%bcond_with vqsim
+%bcond_with runautogen
+%bcond_with userflags
+
+%global gitver %{?numcomm:.%{numcomm}}%{?alphatag:.%{alphatag}}%{?dirty:.%{dirty}}
+%global gittarver %{?numcomm:.%{numcomm}}%{?alphatag:-%{alphatag}}%{?dirty:-%{dirty}}
+
+Name: corosync
+Summary: The Corosync Cluster Engine and Application Programming Interfaces
+Version: @version@
+Release: 1%{?gitver}%{?dist}
+License: BSD-3-Clause
+URL: http://corosync.github.io/corosync/
+Source0: http://build.clusterlabs.org/corosync/releases/%{name}-%{version}%{?gittarver}.tar.gz
+
+# Runtime bits
+# The automatic dependency overridden in favor of explicit version lock
+Requires: corosynclib%{?_isa} = %{version}-%{release}
+
+# Support crypto reload
+Requires: libknet1 >= 1.18
+
+# Build bits
+BuildRequires: gcc
+
+%if 0%{?suse_version}
+BuildRequires: groff-full
+%else
+BuildRequires: groff
+%endif
+BuildRequires: libqb-devel
+BuildRequires: libknet1-devel >= 1.18
+BuildRequires: zlib-devel
+%if %{with runautogen}
+BuildRequires: autoconf automake libtool
+%endif
+%if %{with monitoring}
+BuildRequires: libstatgrab-devel
+%endif
+%if %{with snmp}
+BuildRequires: net-snmp-devel
+%endif
+%if %{with dbus}
+%if 0%{?suse_version}
+BuildRequires: dbus-1-devel
+%else
+BuildRequires: dbus-devel
+%endif
+%endif
+%if %{with nozzle}
+BuildRequires: libnozzle1-devel
+%endif
+%if %{with systemd}
+%{?systemd_requires}
+BuildRequires: systemd
+BuildRequires: systemd-devel
+%else
+Requires(post): /sbin/chkconfig
+Requires(preun): /sbin/chkconfig
+%endif
+%if %{with xmlconf}
+Requires: libxslt
+%endif
+%if %{with vqsim}
+BuildRequires: readline-devel
+%endif
+
+%prep
+%setup -q -n %{name}-%{version}%{?gittarver}
+
+%build
+%if %{with runautogen}
+./autogen.sh
+%endif
+
+%{configure} \
+%if %{with watchdog}
+ --enable-watchdog \
+%endif
+%if %{with monitoring}
+ --enable-monitoring \
+%endif
+%if %{with snmp}
+ --enable-snmp \
+%endif
+%if %{with dbus}
+ --enable-dbus \
+%endif
+%if %{with systemd}
+ --enable-systemd \
+%endif
+%if %{with xmlconf}
+ --enable-xmlconf \
+%endif
+%if %{with nozzle}
+ --enable-nozzle \
+%endif
+%if %{with vqsim}
+ --enable-vqsim \
+%endif
+%if %{with userflags}
+ --enable-user-flags \
+%endif
+ --with-initddir=%{_initrddir} \
+ --with-systemddir=%{_unitdir} \
+ --docdir=%{_docdir}
+
+make %{_smp_mflags}
+
+%install
+make install DESTDIR=%{buildroot}
+
+%if %{with dbus}
+mkdir -p -m 0700 %{buildroot}/%{_sysconfdir}/dbus-1/system.d
+install -m 644 %{_builddir}/%{name}-%{version}%{?gittarver}/conf/corosync-signals.conf %{buildroot}/%{_sysconfdir}/dbus-1/system.d/corosync-signals.conf
+%endif
+
+## tree fixup
+# drop static libs
+rm -f %{buildroot}%{_libdir}/*.a
+rm -f %{buildroot}%{_libdir}/*.la
+# drop docs and html docs for now
+rm -rf %{buildroot}%{_docdir}/*
+# /etc/sysconfig/corosync-notifyd
+mkdir -p %{buildroot}%{_sysconfdir}/sysconfig
+install -m 644 tools/corosync-notifyd.sysconfig.example \
+ %{buildroot}%{_sysconfdir}/sysconfig/corosync-notifyd
+# /etc/sysconfig/corosync
+install -m 644 init/corosync.sysconfig.example \
+ %{buildroot}%{_sysconfdir}/sysconfig/corosync
+
+%description
+This package contains the Corosync Cluster Engine Executive, several default
+APIs and libraries, default configuration files, and an init script.
+
+%post
+%if %{with systemd} && 0%{?systemd_post:1}
+%systemd_post corosync.service
+%else
+if [ $1 -eq 1 ]; then
+ /sbin/chkconfig --add corosync || :
+fi
+%endif
+
+%preun
+%if %{with systemd} && 0%{?systemd_preun:1}
+%systemd_preun corosync.service
+%else
+if [ $1 -eq 0 ]; then
+ /sbin/service corosync stop &>/dev/null || :
+ /sbin/chkconfig --del corosync || :
+fi
+%endif
+
+%postun
+%if %{with systemd} && 0%{?systemd_postun:1}
+%systemd_postun corosync.service
+%endif
+
+%files
+%doc LICENSE
+%{_sbindir}/corosync
+%{_sbindir}/corosync-keygen
+%{_sbindir}/corosync-cmapctl
+%{_sbindir}/corosync-cfgtool
+%{_sbindir}/corosync-cpgtool
+%{_sbindir}/corosync-quorumtool
+%{_sbindir}/corosync-notifyd
+%{_bindir}/corosync-blackbox
+%if %{with xmlconf}
+%{_bindir}/corosync-xmlproc
+%dir %{_datadir}/corosync
+%{_datadir}/corosync/xml2conf.xsl
+%{_mandir}/man8/corosync-xmlproc.8*
+%{_mandir}/man5/corosync.xml.5*
+%endif
+%dir %{_sysconfdir}/corosync
+%dir %{_sysconfdir}/corosync/uidgid.d
+%config(noreplace) %{_sysconfdir}/corosync/corosync.conf.example
+%config(noreplace) %{_sysconfdir}/sysconfig/corosync-notifyd
+%config(noreplace) %{_sysconfdir}/sysconfig/corosync
+%config(noreplace) %{_sysconfdir}/logrotate.d/corosync
+%if %{with dbus}
+%{_sysconfdir}/dbus-1/system.d/corosync-signals.conf
+%endif
+%if %{with snmp}
+%{_datadir}/snmp/mibs/COROSYNC-MIB.txt
+%endif
+%if %{with systemd}
+%{_unitdir}/corosync.service
+%{_unitdir}/corosync-notifyd.service
+%else
+%{_initrddir}/corosync
+%{_initrddir}/corosync-notifyd
+%endif
+%dir %{_localstatedir}/lib/corosync
+%dir %{_localstatedir}/log/cluster
+%{_mandir}/man7/corosync_overview.7*
+%{_mandir}/man8/corosync.8*
+%{_mandir}/man8/corosync-blackbox.8*
+%{_mandir}/man8/corosync-cmapctl.8*
+%{_mandir}/man8/corosync-keygen.8*
+%{_mandir}/man8/corosync-cfgtool.8*
+%{_mandir}/man8/corosync-cpgtool.8*
+%{_mandir}/man8/corosync-notifyd.8*
+%{_mandir}/man8/corosync-quorumtool.8*
+%{_mandir}/man5/corosync.conf.5*
+%{_mandir}/man5/votequorum.5*
+%{_mandir}/man7/cmap_keys.7*
+
+# library
+#
+%package -n corosynclib
+Summary: The Corosync Cluster Engine Libraries
+
+%description -n corosynclib
+This package contains corosync libraries.
+
+%files -n corosynclib
+%doc LICENSE
+%{_libdir}/libcfg.so.*
+%{_libdir}/libcpg.so.*
+%{_libdir}/libcmap.so.*
+%{_libdir}/libquorum.so.*
+%{_libdir}/libvotequorum.so.*
+%{_libdir}/libsam.so.*
+%{_libdir}/libcorosync_common.so.*
+
+%post -n corosynclib -p /sbin/ldconfig
+
+%postun -n corosynclib -p /sbin/ldconfig
+
+%package -n corosynclib-devel
+Summary: The Corosync Cluster Engine Development Kit
+Requires: corosynclib%{?_isa} = %{version}-%{release}
+Requires: pkgconfig
+Provides: corosync-devel = %{version}-%{release}
+Provides: corosync-devel%{?_isa} = %{version}-%{release}
+
+%description -n corosynclib-devel
+This package contains include files and man pages used to develop using
+The Corosync Cluster Engine APIs.
+
+%files -n corosynclib-devel
+%doc LICENSE
+%dir %{_includedir}/corosync/
+%{_includedir}/corosync/corodefs.h
+%{_includedir}/corosync/cfg.h
+%{_includedir}/corosync/cmap.h
+%{_includedir}/corosync/corotypes.h
+%{_includedir}/corosync/cpg.h
+%{_includedir}/corosync/hdb.h
+%{_includedir}/corosync/sam.h
+%{_includedir}/corosync/quorum.h
+%{_includedir}/corosync/votequorum.h
+%{_libdir}/libcfg.so
+%{_libdir}/libcpg.so
+%{_libdir}/libcmap.so
+%{_libdir}/libquorum.so
+%{_libdir}/libvotequorum.so
+%{_libdir}/libsam.so
+%{_libdir}/libcorosync_common.so
+%{_libdir}/pkgconfig/*.pc
+%{_mandir}/man3/cpg_*3*
+%{_mandir}/man3/quorum_*3*
+%{_mandir}/man3/votequorum_*3*
+%{_mandir}/man3/sam_*3*
+%{_mandir}/man3/cmap_*3*
+
+%if %{with vqsim}
+%package -n corosync-vqsim
+Summary: The Corosync Cluster Engine - Votequorum Simulator
+Requires: corosynclib%{?_isa} = %{version}-%{release}
+Requires: pkgconfig
+
+%description -n corosync-vqsim
+A command-line simulator for the corosync votequorum subsystem.
+It uses the same code as the corosync quorum system but forks
+them into subprocesses to simulate nodes.
+Nodes can be added and removed as well as partitioned (to simulate
+network splits)
+
+%files -n corosync-vqsim
+%doc LICENSE
+%{_bindir}/corosync-vqsim
+%{_mandir}/man8/corosync-vqsim.8*
+%endif
+
+%changelog
+* @date@ Autotools generated version <nobody@nowhere.org> - @version@-1-@numcomm@.@alphatag@.@dirty@
+- Autotools generated version
diff --git a/depcomp b/depcomp
new file mode 100755
index 0000000..4ebd5b3
--- /dev/null
+++ b/depcomp
@@ -0,0 +1,791 @@
+#! /bin/sh
+# depcomp - compile a program generating dependencies as side-effects
+
+scriptversion=2013-05-30.07; # UTC
+
+# Copyright (C) 1999-2013 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, 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, see <http://www.gnu.org/licenses/>.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>.
+
+case $1 in
+ '')
+ echo "$0: No command. Try '$0 --help' for more information." 1>&2
+ exit 1;
+ ;;
+ -h | --h*)
+ cat <<\EOF
+Usage: depcomp [--help] [--version] PROGRAM [ARGS]
+
+Run PROGRAMS ARGS to compile a file, generating dependencies
+as side-effects.
+
+Environment variables:
+ depmode Dependency tracking mode.
+ source Source file read by 'PROGRAMS ARGS'.
+ object Object file output by 'PROGRAMS ARGS'.
+ DEPDIR directory where to store dependencies.
+ depfile Dependency file to output.
+ tmpdepfile Temporary file to use when outputting dependencies.
+ libtool Whether libtool is used (yes/no).
+
+Report bugs to <bug-automake@gnu.org>.
+EOF
+ exit $?
+ ;;
+ -v | --v*)
+ echo "depcomp $scriptversion"
+ exit $?
+ ;;
+esac
+
+# Get the directory component of the given path, and save it in the
+# global variables '$dir'. Note that this directory component will
+# be either empty or ending with a '/' character. This is deliberate.
+set_dir_from ()
+{
+ case $1 in
+ */*) dir=`echo "$1" | sed -e 's|/[^/]*$|/|'`;;
+ *) dir=;;
+ esac
+}
+
+# Get the suffix-stripped basename of the given path, and save it the
+# global variable '$base'.
+set_base_from ()
+{
+ base=`echo "$1" | sed -e 's|^.*/||' -e 's/\.[^.]*$//'`
+}
+
+# If no dependency file was actually created by the compiler invocation,
+# we still have to create a dummy depfile, to avoid errors with the
+# Makefile "include basename.Plo" scheme.
+make_dummy_depfile ()
+{
+ echo "#dummy" > "$depfile"
+}
+
+# Factor out some common post-processing of the generated depfile.
+# Requires the auxiliary global variable '$tmpdepfile' to be set.
+aix_post_process_depfile ()
+{
+ # If the compiler actually managed to produce a dependency file,
+ # post-process it.
+ if test -f "$tmpdepfile"; then
+ # Each line is of the form 'foo.o: dependency.h'.
+ # Do two passes, one to just change these to
+ # $object: dependency.h
+ # and one to simply output
+ # dependency.h:
+ # which is needed to avoid the deleted-header problem.
+ { sed -e "s,^.*\.[$lower]*:,$object:," < "$tmpdepfile"
+ sed -e "s,^.*\.[$lower]*:[$tab ]*,," -e 's,$,:,' < "$tmpdepfile"
+ } > "$depfile"
+ rm -f "$tmpdepfile"
+ else
+ make_dummy_depfile
+ fi
+}
+
+# A tabulation character.
+tab=' '
+# A newline character.
+nl='
+'
+# Character ranges might be problematic outside the C locale.
+# These definitions help.
+upper=ABCDEFGHIJKLMNOPQRSTUVWXYZ
+lower=abcdefghijklmnopqrstuvwxyz
+digits=0123456789
+alpha=${upper}${lower}
+
+if test -z "$depmode" || test -z "$source" || test -z "$object"; then
+ echo "depcomp: Variables source, object and depmode must be set" 1>&2
+ exit 1
+fi
+
+# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po.
+depfile=${depfile-`echo "$object" |
+ sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`}
+tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
+
+rm -f "$tmpdepfile"
+
+# Avoid interferences from the environment.
+gccflag= dashmflag=
+
+# Some modes work just like other modes, but use different flags. We
+# parameterize here, but still list the modes in the big case below,
+# to make depend.m4 easier to write. Note that we *cannot* use a case
+# here, because this file can only contain one case statement.
+if test "$depmode" = hp; then
+ # HP compiler uses -M and no extra arg.
+ gccflag=-M
+ depmode=gcc
+fi
+
+if test "$depmode" = dashXmstdout; then
+ # This is just like dashmstdout with a different argument.
+ dashmflag=-xM
+ depmode=dashmstdout
+fi
+
+cygpath_u="cygpath -u -f -"
+if test "$depmode" = msvcmsys; then
+ # This is just like msvisualcpp but w/o cygpath translation.
+ # Just convert the backslash-escaped backslashes to single forward
+ # slashes to satisfy depend.m4
+ cygpath_u='sed s,\\\\,/,g'
+ depmode=msvisualcpp
+fi
+
+if test "$depmode" = msvc7msys; then
+ # This is just like msvc7 but w/o cygpath translation.
+ # Just convert the backslash-escaped backslashes to single forward
+ # slashes to satisfy depend.m4
+ cygpath_u='sed s,\\\\,/,g'
+ depmode=msvc7
+fi
+
+if test "$depmode" = xlc; then
+ # IBM C/C++ Compilers xlc/xlC can output gcc-like dependency information.
+ gccflag=-qmakedep=gcc,-MF
+ depmode=gcc
+fi
+
+case "$depmode" in
+gcc3)
+## gcc 3 implements dependency tracking that does exactly what
+## we want. Yay! Note: for some reason libtool 1.4 doesn't like
+## it if -MD -MP comes after the -MF stuff. Hmm.
+## Unfortunately, FreeBSD c89 acceptance of flags depends upon
+## the command line argument order; so add the flags where they
+## appear in depend2.am. Note that the slowdown incurred here
+## affects only configure: in makefiles, %FASTDEP% shortcuts this.
+ for arg
+ do
+ case $arg in
+ -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;;
+ *) set fnord "$@" "$arg" ;;
+ esac
+ shift # fnord
+ shift # $arg
+ done
+ "$@"
+ stat=$?
+ if test $stat -ne 0; then
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ mv "$tmpdepfile" "$depfile"
+ ;;
+
+gcc)
+## Note that this doesn't just cater to obsosete pre-3.x GCC compilers.
+## but also to in-use compilers like IMB xlc/xlC and the HP C compiler.
+## (see the conditional assignment to $gccflag above).
+## There are various ways to get dependency output from gcc. Here's
+## why we pick this rather obscure method:
+## - Don't want to use -MD because we'd like the dependencies to end
+## up in a subdir. Having to rename by hand is ugly.
+## (We might end up doing this anyway to support other compilers.)
+## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
+## -MM, not -M (despite what the docs say). Also, it might not be
+## supported by the other compilers which use the 'gcc' depmode.
+## - Using -M directly means running the compiler twice (even worse
+## than renaming).
+ if test -z "$gccflag"; then
+ gccflag=-MD,
+ fi
+ "$@" -Wp,"$gccflag$tmpdepfile"
+ stat=$?
+ if test $stat -ne 0; then
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ rm -f "$depfile"
+ echo "$object : \\" > "$depfile"
+ # The second -e expression handles DOS-style file names with drive
+ # letters.
+ sed -e 's/^[^:]*: / /' \
+ -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
+## This next piece of magic avoids the "deleted header file" problem.
+## The problem is that when a header file which appears in a .P file
+## is deleted, the dependency causes make to die (because there is
+## typically no way to rebuild the header). We avoid this by adding
+## dummy dependencies for each header file. Too bad gcc doesn't do
+## this for us directly.
+## Some versions of gcc put a space before the ':'. On the theory
+## that the space means something, we add a space to the output as
+## well. hp depmode also adds that space, but also prefixes the VPATH
+## to the object. Take care to not repeat it in the output.
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly. Breaking it into two sed invocations is a workaround.
+ tr ' ' "$nl" < "$tmpdepfile" \
+ | sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \
+ | sed -e 's/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+hp)
+ # This case exists only to let depend.m4 do its work. It works by
+ # looking at the text of this script. This case will never be run,
+ # since it is checked for above.
+ exit 1
+ ;;
+
+sgi)
+ if test "$libtool" = yes; then
+ "$@" "-Wp,-MDupdate,$tmpdepfile"
+ else
+ "$@" -MDupdate "$tmpdepfile"
+ fi
+ stat=$?
+ if test $stat -ne 0; then
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ rm -f "$depfile"
+
+ if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files
+ echo "$object : \\" > "$depfile"
+ # Clip off the initial element (the dependent). Don't try to be
+ # clever and replace this with sed code, as IRIX sed won't handle
+ # lines with more than a fixed number of characters (4096 in
+ # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines;
+ # the IRIX cc adds comments like '#:fec' to the end of the
+ # dependency line.
+ tr ' ' "$nl" < "$tmpdepfile" \
+ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' \
+ | tr "$nl" ' ' >> "$depfile"
+ echo >> "$depfile"
+ # The second pass generates a dummy entry for each header file.
+ tr ' ' "$nl" < "$tmpdepfile" \
+ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
+ >> "$depfile"
+ else
+ make_dummy_depfile
+ fi
+ rm -f "$tmpdepfile"
+ ;;
+
+xlc)
+ # This case exists only to let depend.m4 do its work. It works by
+ # looking at the text of this script. This case will never be run,
+ # since it is checked for above.
+ exit 1
+ ;;
+
+aix)
+ # The C for AIX Compiler uses -M and outputs the dependencies
+ # in a .u file. In older versions, this file always lives in the
+ # current directory. Also, the AIX compiler puts '$object:' at the
+ # start of each line; $object doesn't have directory information.
+ # Version 6 uses the directory in both cases.
+ set_dir_from "$object"
+ set_base_from "$object"
+ if test "$libtool" = yes; then
+ tmpdepfile1=$dir$base.u
+ tmpdepfile2=$base.u
+ tmpdepfile3=$dir.libs/$base.u
+ "$@" -Wc,-M
+ else
+ tmpdepfile1=$dir$base.u
+ tmpdepfile2=$dir$base.u
+ tmpdepfile3=$dir$base.u
+ "$@" -M
+ fi
+ stat=$?
+ if test $stat -ne 0; then
+ rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
+ exit $stat
+ fi
+
+ for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
+ do
+ test -f "$tmpdepfile" && break
+ done
+ aix_post_process_depfile
+ ;;
+
+tcc)
+ # tcc (Tiny C Compiler) understand '-MD -MF file' since version 0.9.26
+ # FIXME: That version still under development at the moment of writing.
+ # Make that this statement remains true also for stable, released
+ # versions.
+ # It will wrap lines (doesn't matter whether long or short) with a
+ # trailing '\', as in:
+ #
+ # foo.o : \
+ # foo.c \
+ # foo.h \
+ #
+ # It will put a trailing '\' even on the last line, and will use leading
+ # spaces rather than leading tabs (at least since its commit 0394caf7
+ # "Emit spaces for -MD").
+ "$@" -MD -MF "$tmpdepfile"
+ stat=$?
+ if test $stat -ne 0; then
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ rm -f "$depfile"
+ # Each non-empty line is of the form 'foo.o : \' or ' dep.h \'.
+ # We have to change lines of the first kind to '$object: \'.
+ sed -e "s|.*:|$object :|" < "$tmpdepfile" > "$depfile"
+ # And for each line of the second kind, we have to emit a 'dep.h:'
+ # dummy dependency, to avoid the deleted-header problem.
+ sed -n -e 's|^ *\(.*\) *\\$|\1:|p' < "$tmpdepfile" >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+## The order of this option in the case statement is important, since the
+## shell code in configure will try each of these formats in the order
+## listed in this file. A plain '-MD' option would be understood by many
+## compilers, so we must ensure this comes after the gcc and icc options.
+pgcc)
+ # Portland's C compiler understands '-MD'.
+ # Will always output deps to 'file.d' where file is the root name of the
+ # source file under compilation, even if file resides in a subdirectory.
+ # The object file name does not affect the name of the '.d' file.
+ # pgcc 10.2 will output
+ # foo.o: sub/foo.c sub/foo.h
+ # and will wrap long lines using '\' :
+ # foo.o: sub/foo.c ... \
+ # sub/foo.h ... \
+ # ...
+ set_dir_from "$object"
+ # Use the source, not the object, to determine the base name, since
+ # that's sadly what pgcc will do too.
+ set_base_from "$source"
+ tmpdepfile=$base.d
+
+ # For projects that build the same source file twice into different object
+ # files, the pgcc approach of using the *source* file root name can cause
+ # problems in parallel builds. Use a locking strategy to avoid stomping on
+ # the same $tmpdepfile.
+ lockdir=$base.d-lock
+ trap "
+ echo '$0: caught signal, cleaning up...' >&2
+ rmdir '$lockdir'
+ exit 1
+ " 1 2 13 15
+ numtries=100
+ i=$numtries
+ while test $i -gt 0; do
+ # mkdir is a portable test-and-set.
+ if mkdir "$lockdir" 2>/dev/null; then
+ # This process acquired the lock.
+ "$@" -MD
+ stat=$?
+ # Release the lock.
+ rmdir "$lockdir"
+ break
+ else
+ # If the lock is being held by a different process, wait
+ # until the winning process is done or we timeout.
+ while test -d "$lockdir" && test $i -gt 0; do
+ sleep 1
+ i=`expr $i - 1`
+ done
+ fi
+ i=`expr $i - 1`
+ done
+ trap - 1 2 13 15
+ if test $i -le 0; then
+ echo "$0: failed to acquire lock after $numtries attempts" >&2
+ echo "$0: check lockdir '$lockdir'" >&2
+ exit 1
+ fi
+
+ if test $stat -ne 0; then
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ rm -f "$depfile"
+ # Each line is of the form `foo.o: dependent.h',
+ # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'.
+ # Do two passes, one to just change these to
+ # `$object: dependent.h' and one to simply `dependent.h:'.
+ sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile"
+ # Some versions of the HPUX 10.20 sed can't process this invocation
+ # correctly. Breaking it into two sed invocations is a workaround.
+ sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" \
+ | sed -e 's/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+hp2)
+ # The "hp" stanza above does not work with aCC (C++) and HP's ia64
+ # compilers, which have integrated preprocessors. The correct option
+ # to use with these is +Maked; it writes dependencies to a file named
+ # 'foo.d', which lands next to the object file, wherever that
+ # happens to be.
+ # Much of this is similar to the tru64 case; see comments there.
+ set_dir_from "$object"
+ set_base_from "$object"
+ if test "$libtool" = yes; then
+ tmpdepfile1=$dir$base.d
+ tmpdepfile2=$dir.libs/$base.d
+ "$@" -Wc,+Maked
+ else
+ tmpdepfile1=$dir$base.d
+ tmpdepfile2=$dir$base.d
+ "$@" +Maked
+ fi
+ stat=$?
+ if test $stat -ne 0; then
+ rm -f "$tmpdepfile1" "$tmpdepfile2"
+ exit $stat
+ fi
+
+ for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2"
+ do
+ test -f "$tmpdepfile" && break
+ done
+ if test -f "$tmpdepfile"; then
+ sed -e "s,^.*\.[$lower]*:,$object:," "$tmpdepfile" > "$depfile"
+ # Add 'dependent.h:' lines.
+ sed -ne '2,${
+ s/^ *//
+ s/ \\*$//
+ s/$/:/
+ p
+ }' "$tmpdepfile" >> "$depfile"
+ else
+ make_dummy_depfile
+ fi
+ rm -f "$tmpdepfile" "$tmpdepfile2"
+ ;;
+
+tru64)
+ # The Tru64 compiler uses -MD to generate dependencies as a side
+ # effect. 'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'.
+ # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
+ # dependencies in 'foo.d' instead, so we check for that too.
+ # Subdirectories are respected.
+ set_dir_from "$object"
+ set_base_from "$object"
+
+ if test "$libtool" = yes; then
+ # Libtool generates 2 separate objects for the 2 libraries. These
+ # two compilations output dependencies in $dir.libs/$base.o.d and
+ # in $dir$base.o.d. We have to check for both files, because
+ # one of the two compilations can be disabled. We should prefer
+ # $dir$base.o.d over $dir.libs/$base.o.d because the latter is
+ # automatically cleaned when .libs/ is deleted, while ignoring
+ # the former would cause a distcleancheck panic.
+ tmpdepfile1=$dir$base.o.d # libtool 1.5
+ tmpdepfile2=$dir.libs/$base.o.d # Likewise.
+ tmpdepfile3=$dir.libs/$base.d # Compaq CCC V6.2-504
+ "$@" -Wc,-MD
+ else
+ tmpdepfile1=$dir$base.d
+ tmpdepfile2=$dir$base.d
+ tmpdepfile3=$dir$base.d
+ "$@" -MD
+ fi
+
+ stat=$?
+ if test $stat -ne 0; then
+ rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
+ exit $stat
+ fi
+
+ for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
+ do
+ test -f "$tmpdepfile" && break
+ done
+ # Same post-processing that is required for AIX mode.
+ aix_post_process_depfile
+ ;;
+
+msvc7)
+ if test "$libtool" = yes; then
+ showIncludes=-Wc,-showIncludes
+ else
+ showIncludes=-showIncludes
+ fi
+ "$@" $showIncludes > "$tmpdepfile"
+ stat=$?
+ grep -v '^Note: including file: ' "$tmpdepfile"
+ if test $stat -ne 0; then
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ rm -f "$depfile"
+ echo "$object : \\" > "$depfile"
+ # The first sed program below extracts the file names and escapes
+ # backslashes for cygpath. The second sed program outputs the file
+ # name when reading, but also accumulates all include files in the
+ # hold buffer in order to output them again at the end. This only
+ # works with sed implementations that can handle large buffers.
+ sed < "$tmpdepfile" -n '
+/^Note: including file: *\(.*\)/ {
+ s//\1/
+ s/\\/\\\\/g
+ p
+}' | $cygpath_u | sort -u | sed -n '
+s/ /\\ /g
+s/\(.*\)/'"$tab"'\1 \\/p
+s/.\(.*\) \\/\1:/
+H
+$ {
+ s/.*/'"$tab"'/
+ G
+ p
+}' >> "$depfile"
+ echo >> "$depfile" # make sure the fragment doesn't end with a backslash
+ rm -f "$tmpdepfile"
+ ;;
+
+msvc7msys)
+ # This case exists only to let depend.m4 do its work. It works by
+ # looking at the text of this script. This case will never be run,
+ # since it is checked for above.
+ exit 1
+ ;;
+
+#nosideeffect)
+ # This comment above is used by automake to tell side-effect
+ # dependency tracking mechanisms from slower ones.
+
+dashmstdout)
+ # Important note: in order to support this mode, a compiler *must*
+ # always write the preprocessed file to stdout, regardless of -o.
+ "$@" || exit $?
+
+ # Remove the call to Libtool.
+ if test "$libtool" = yes; then
+ while test "X$1" != 'X--mode=compile'; do
+ shift
+ done
+ shift
+ fi
+
+ # Remove '-o $object'.
+ IFS=" "
+ for arg
+ do
+ case $arg in
+ -o)
+ shift
+ ;;
+ $object)
+ shift
+ ;;
+ *)
+ set fnord "$@" "$arg"
+ shift # fnord
+ shift # $arg
+ ;;
+ esac
+ done
+
+ test -z "$dashmflag" && dashmflag=-M
+ # Require at least two characters before searching for ':'
+ # in the target name. This is to cope with DOS-style filenames:
+ # a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise.
+ "$@" $dashmflag |
+ sed "s|^[$tab ]*[^:$tab ][^:][^:]*:[$tab ]*|$object: |" > "$tmpdepfile"
+ rm -f "$depfile"
+ cat < "$tmpdepfile" > "$depfile"
+ # Some versions of the HPUX 10.20 sed can't process this sed invocation
+ # correctly. Breaking it into two sed invocations is a workaround.
+ tr ' ' "$nl" < "$tmpdepfile" \
+ | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \
+ | sed -e 's/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+dashXmstdout)
+ # This case only exists to satisfy depend.m4. It is never actually
+ # run, as this mode is specially recognized in the preamble.
+ exit 1
+ ;;
+
+makedepend)
+ "$@" || exit $?
+ # Remove any Libtool call
+ if test "$libtool" = yes; then
+ while test "X$1" != 'X--mode=compile'; do
+ shift
+ done
+ shift
+ fi
+ # X makedepend
+ shift
+ cleared=no eat=no
+ for arg
+ do
+ case $cleared in
+ no)
+ set ""; shift
+ cleared=yes ;;
+ esac
+ if test $eat = yes; then
+ eat=no
+ continue
+ fi
+ case "$arg" in
+ -D*|-I*)
+ set fnord "$@" "$arg"; shift ;;
+ # Strip any option that makedepend may not understand. Remove
+ # the object too, otherwise makedepend will parse it as a source file.
+ -arch)
+ eat=yes ;;
+ -*|$object)
+ ;;
+ *)
+ set fnord "$@" "$arg"; shift ;;
+ esac
+ done
+ obj_suffix=`echo "$object" | sed 's/^.*\././'`
+ touch "$tmpdepfile"
+ ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@"
+ rm -f "$depfile"
+ # makedepend may prepend the VPATH from the source file name to the object.
+ # No need to regex-escape $object, excess matching of '.' is harmless.
+ sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile"
+ # Some versions of the HPUX 10.20 sed can't process the last invocation
+ # correctly. Breaking it into two sed invocations is a workaround.
+ sed '1,2d' "$tmpdepfile" \
+ | tr ' ' "$nl" \
+ | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \
+ | sed -e 's/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile" "$tmpdepfile".bak
+ ;;
+
+cpp)
+ # Important note: in order to support this mode, a compiler *must*
+ # always write the preprocessed file to stdout.
+ "$@" || exit $?
+
+ # Remove the call to Libtool.
+ if test "$libtool" = yes; then
+ while test "X$1" != 'X--mode=compile'; do
+ shift
+ done
+ shift
+ fi
+
+ # Remove '-o $object'.
+ IFS=" "
+ for arg
+ do
+ case $arg in
+ -o)
+ shift
+ ;;
+ $object)
+ shift
+ ;;
+ *)
+ set fnord "$@" "$arg"
+ shift # fnord
+ shift # $arg
+ ;;
+ esac
+ done
+
+ "$@" -E \
+ | sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
+ -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
+ | sed '$ s: \\$::' > "$tmpdepfile"
+ rm -f "$depfile"
+ echo "$object : \\" > "$depfile"
+ cat < "$tmpdepfile" >> "$depfile"
+ sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+msvisualcpp)
+ # Important note: in order to support this mode, a compiler *must*
+ # always write the preprocessed file to stdout.
+ "$@" || exit $?
+
+ # Remove the call to Libtool.
+ if test "$libtool" = yes; then
+ while test "X$1" != 'X--mode=compile'; do
+ shift
+ done
+ shift
+ fi
+
+ IFS=" "
+ for arg
+ do
+ case "$arg" in
+ -o)
+ shift
+ ;;
+ $object)
+ shift
+ ;;
+ "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
+ set fnord "$@"
+ shift
+ shift
+ ;;
+ *)
+ set fnord "$@" "$arg"
+ shift
+ shift
+ ;;
+ esac
+ done
+ "$@" -E 2>/dev/null |
+ sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile"
+ rm -f "$depfile"
+ echo "$object : \\" > "$depfile"
+ sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile"
+ echo "$tab" >> "$depfile"
+ sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+msvcmsys)
+ # This case exists only to let depend.m4 do its work. It works by
+ # looking at the text of this script. This case will never be run,
+ # since it is checked for above.
+ exit 1
+ ;;
+
+none)
+ exec "$@"
+ ;;
+
+*)
+ echo "Unknown depmode $depmode" 1>&2
+ exit 1
+ ;;
+esac
+
+exit 0
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
diff --git a/exec/Makefile.am b/exec/Makefile.am
new file mode 100644
index 0000000..1c31f8c
--- /dev/null
+++ b/exec/Makefile.am
@@ -0,0 +1,70 @@
+# Copyright (c) 2009 Red Hat, Inc.
+#
+# Authors: Andrew Beekhof
+# Steven Dake (sdake@redhat.com)
+#
+# This software licensed under BSD license, the text of which follows:
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# - Redistributions of source code must retain the above copyright notice,
+# this list of conditions and the following disclaimer.
+# - Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+# - Neither the name of the MontaVista Software, Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from this
+# software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+# THE POSSIBILITY OF SUCH DAMAGE.
+
+MAINTAINERCLEANFILES = Makefile.in
+
+noinst_HEADERS = apidef.h cs_queue.h logconfig.h main.h \
+ quorum.h service.h timer.h totemconfig.h \
+ totemnet.h totemudp.h \
+ totemudpu.h totemsrp.h util.h vsf.h \
+ schedwrk.h sync.h fsm.h votequorum.h vsf_ykd.h \
+ totemknet.h stats.h ipcs_stats.h
+
+sbin_PROGRAMS = corosync
+
+corosync_SOURCES = vsf_ykd.c coroparse.c vsf_quorum.c sync.c \
+ logsys.c cfg.c cmap.c cpg.c pload.c \
+ votequorum.c util.c schedwrk.c main.c \
+ apidef.c quorum.c icmap.c timer.c stats.c \
+ ipc_glue.c service.c logconfig.c totemconfig.c \
+ totemip.c totemnet.c totemudp.c \
+ totemudpu.c totemsrp.c \
+ totempg.c totemknet.c
+
+if BUILD_MONITORING
+corosync_SOURCES += mon.c
+endif
+
+if BUILD_WATCHDOG
+corosync_SOURCES += wd.c
+endif
+
+corosync_CPPFLAGS = -DLOGCONFIG_USE_ICMAP=1
+
+corosync_CFLAGS = $(statgrab_CFLAGS) $(libsystemd_CFLAGS) $(knet_CFLAGS) $(nozzle_CFLAGS)
+
+corosync_LDADD = ../common_lib/libcorosync_common.la \
+ $(LIBQB_LIBS) $(statgrab_LIBS) $(libsystemd_LIBS) $(knet_LIBS) $(nozzle_LIBS)
+
+corosync_DEPENDENCIES = ../common_lib/libcorosync_common.la
+
+lint:
+ -splint $(LINT_FLAGS) $(CPPFLAGS) $(CFLAGS) *.c
diff --git a/exec/Makefile.in b/exec/Makefile.in
new file mode 100644
index 0000000..0fbc6b7
--- /dev/null
+++ b/exec/Makefile.in
@@ -0,0 +1,1218 @@
+# Makefile.in generated by automake 1.13.4 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+# Copyright (c) 2009 Red Hat, Inc.
+#
+# Authors: Andrew Beekhof
+# Steven Dake (sdake@redhat.com)
+#
+# This software licensed under BSD license, the text of which follows:
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# - Redistributions of source code must retain the above copyright notice,
+# this list of conditions and the following disclaimer.
+# - Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+# - Neither the name of the MontaVista Software, Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from this
+# software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+# THE POSSIBILITY OF SUCH DAMAGE.
+
+
+VPATH = @srcdir@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+sbin_PROGRAMS = corosync$(EXEEXT)
+@BUILD_MONITORING_TRUE@am__append_1 = mon.c
+@BUILD_WATCHDOG_TRUE@am__append_2 = wd.c
+subdir = exec
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+ $(top_srcdir)/depcomp $(noinst_HEADERS)
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/lib/libcfg.verso $(top_srcdir)/lib/libcpg.verso \
+ $(top_srcdir)/lib/libquorum.verso \
+ $(top_srcdir)/lib/libsam.verso \
+ $(top_srcdir)/lib/libvotequorum.verso \
+ $(top_srcdir)/lib/libcmap.verso $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/include/corosync/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__installdirs = "$(DESTDIR)$(sbindir)"
+PROGRAMS = $(sbin_PROGRAMS)
+am__corosync_SOURCES_DIST = vsf_ykd.c coroparse.c vsf_quorum.c sync.c \
+ logsys.c cfg.c cmap.c cpg.c pload.c votequorum.c util.c \
+ schedwrk.c main.c apidef.c quorum.c icmap.c timer.c stats.c \
+ ipc_glue.c service.c logconfig.c totemconfig.c totemip.c \
+ totemnet.c totemudp.c totemudpu.c totemsrp.c totempg.c \
+ totemknet.c mon.c wd.c
+@BUILD_MONITORING_TRUE@am__objects_1 = corosync-mon.$(OBJEXT)
+@BUILD_WATCHDOG_TRUE@am__objects_2 = corosync-wd.$(OBJEXT)
+am_corosync_OBJECTS = corosync-vsf_ykd.$(OBJEXT) \
+ corosync-coroparse.$(OBJEXT) corosync-vsf_quorum.$(OBJEXT) \
+ corosync-sync.$(OBJEXT) corosync-logsys.$(OBJEXT) \
+ corosync-cfg.$(OBJEXT) corosync-cmap.$(OBJEXT) \
+ corosync-cpg.$(OBJEXT) corosync-pload.$(OBJEXT) \
+ corosync-votequorum.$(OBJEXT) corosync-util.$(OBJEXT) \
+ corosync-schedwrk.$(OBJEXT) corosync-main.$(OBJEXT) \
+ corosync-apidef.$(OBJEXT) corosync-quorum.$(OBJEXT) \
+ corosync-icmap.$(OBJEXT) corosync-timer.$(OBJEXT) \
+ corosync-stats.$(OBJEXT) corosync-ipc_glue.$(OBJEXT) \
+ corosync-service.$(OBJEXT) corosync-logconfig.$(OBJEXT) \
+ corosync-totemconfig.$(OBJEXT) corosync-totemip.$(OBJEXT) \
+ corosync-totemnet.$(OBJEXT) corosync-totemudp.$(OBJEXT) \
+ corosync-totemudpu.$(OBJEXT) corosync-totemsrp.$(OBJEXT) \
+ corosync-totempg.$(OBJEXT) corosync-totemknet.$(OBJEXT) \
+ $(am__objects_1) $(am__objects_2)
+corosync_OBJECTS = $(am_corosync_OBJECTS)
+am__DEPENDENCIES_1 =
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 =
+corosync_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(corosync_CFLAGS) \
+ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/corosync
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo " CC " $@;
+am__v_CC_1 =
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo " CCLD " $@;
+am__v_CCLD_1 =
+SOURCES = $(corosync_SOURCES)
+DIST_SOURCES = $(am__corosync_SOURCES_DIST)
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+HEADERS = $(noinst_HEADERS)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALLOCA = @ALLOCA@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUGTOOL = @AUGTOOL@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BASHPATH = @BASHPATH@
+BINDGEN = @BINDGEN@
+CARGO = @CARGO@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFG_SONAME = @CFG_SONAME@
+CFLAGS = @CFLAGS@
+CLIPPY = @CLIPPY@
+CMAP_SONAME = @CMAP_SONAME@
+COROSYSCONFDIR = @COROSYSCONFDIR@
+CPG_SONAME = @CPG_SONAME@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DBUS_CFLAGS = @DBUS_CFLAGS@
+DBUS_LIBS = @DBUS_LIBS@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DOT = @DOT@
+DOXYGEN = @DOXYGEN@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GREP = @GREP@
+GROFF = @GROFF@
+INITCONFIGDIR = @INITCONFIGDIR@
+INITDDIR = @INITDDIR@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBQB_CFLAGS = @LIBQB_CFLAGS@
+LIBQB_LIBS = @LIBQB_LIBS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LINT_FLAGS = @LINT_FLAGS@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LOGDIR = @LOGDIR@
+LOGROTATEDIR = @LOGROTATEDIR@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+QUORUM_SONAME = @QUORUM_SONAME@
+RANLIB = @RANLIB@
+RUSTC = @RUSTC@
+RUSTDOC = @RUSTDOC@
+RUSTFMT = @RUSTFMT@
+RUST_FLAGS = @RUST_FLAGS@
+RUST_TARGET_DIR = @RUST_TARGET_DIR@
+SAM_SONAME = @SAM_SONAME@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SNMPCONFIG = @SNMPCONFIG@
+SNMP_LIBS = @SNMP_LIBS@
+SOMAJOR = @SOMAJOR@
+SOMICRO = @SOMICRO@
+SOMINOR = @SOMINOR@
+SONAME = @SONAME@
+STRIP = @STRIP@
+SYSTEMDDIR = @SYSTEMDDIR@
+VERSCRIPT_LDFLAGS = @VERSCRIPT_LDFLAGS@
+VERSION = @VERSION@
+VOTEQUORUM_SONAME = @VOTEQUORUM_SONAME@
+WITH_LIST = @WITH_LIST@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+corosyncrustver = @corosyncrustver@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+knet_CFLAGS = @knet_CFLAGS@
+knet_LIBS = @knet_LIBS@
+libdir = @libdir@
+libexecdir = @libexecdir@
+libsystemd_CFLAGS = @libsystemd_CFLAGS@
+libsystemd_LIBS = @libsystemd_LIBS@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+nozzle_CFLAGS = @nozzle_CFLAGS@
+nozzle_LIBS = @nozzle_LIBS@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+statgrab_CFLAGS = @statgrab_CFLAGS@
+statgrab_LIBS = @statgrab_LIBS@
+statgrabge090_CFLAGS = @statgrabge090_CFLAGS@
+statgrabge090_LIBS = @statgrabge090_LIBS@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+MAINTAINERCLEANFILES = Makefile.in
+noinst_HEADERS = apidef.h cs_queue.h logconfig.h main.h \
+ quorum.h service.h timer.h totemconfig.h \
+ totemnet.h totemudp.h \
+ totemudpu.h totemsrp.h util.h vsf.h \
+ schedwrk.h sync.h fsm.h votequorum.h vsf_ykd.h \
+ totemknet.h stats.h ipcs_stats.h
+
+corosync_SOURCES = vsf_ykd.c coroparse.c vsf_quorum.c sync.c logsys.c \
+ cfg.c cmap.c cpg.c pload.c votequorum.c util.c schedwrk.c \
+ main.c apidef.c quorum.c icmap.c timer.c stats.c ipc_glue.c \
+ service.c logconfig.c totemconfig.c totemip.c totemnet.c \
+ totemudp.c totemudpu.c totemsrp.c totempg.c totemknet.c \
+ $(am__append_1) $(am__append_2)
+corosync_CPPFLAGS = -DLOGCONFIG_USE_ICMAP=1
+corosync_CFLAGS = $(statgrab_CFLAGS) $(libsystemd_CFLAGS) $(knet_CFLAGS) $(nozzle_CFLAGS)
+corosync_LDADD = ../common_lib/libcorosync_common.la \
+ $(LIBQB_LIBS) $(statgrab_LIBS) $(libsystemd_LIBS) $(knet_LIBS) $(nozzle_LIBS)
+
+corosync_DEPENDENCIES = ../common_lib/libcorosync_common.la
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign exec/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign exec/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+install-sbinPROGRAMS: $(sbin_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ @list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(sbindir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(sbindir)" || exit 1; \
+ fi; \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed 's/$(EXEEXT)$$//' | \
+ while read p p1; do if test -f $$p \
+ || test -f $$p1 \
+ ; then echo "$$p"; echo "$$p"; else :; fi; \
+ done | \
+ sed -e 'p;s,.*/,,;n;h' \
+ -e 's|.*|.|' \
+ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \
+ sed 'N;N;N;s,\n, ,g' | \
+ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \
+ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
+ if ($$2 == $$4) files[d] = files[d] " " $$1; \
+ else { print "f", $$3 "/" $$4, $$1; } } \
+ END { for (d in files) print "f", d, files[d] }' | \
+ while read type dir files; do \
+ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
+ test -z "$$files" || { \
+ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(sbindir)$$dir'"; \
+ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(sbindir)$$dir" || exit $$?; \
+ } \
+ ; done
+
+uninstall-sbinPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \
+ files=`for p in $$list; do echo "$$p"; done | \
+ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \
+ -e 's/$$/$(EXEEXT)/' \
+ `; \
+ test -n "$$list" || exit 0; \
+ echo " ( cd '$(DESTDIR)$(sbindir)' && rm -f" $$files ")"; \
+ cd "$(DESTDIR)$(sbindir)" && rm -f $$files
+
+clean-sbinPROGRAMS:
+ @list='$(sbin_PROGRAMS)'; test -n "$$list" || exit 0; \
+ echo " rm -f" $$list; \
+ rm -f $$list || exit $$?; \
+ test -n "$(EXEEXT)" || exit 0; \
+ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f" $$list; \
+ rm -f $$list
+
+corosync$(EXEEXT): $(corosync_OBJECTS) $(corosync_DEPENDENCIES) $(EXTRA_corosync_DEPENDENCIES)
+ @rm -f corosync$(EXEEXT)
+ $(AM_V_CCLD)$(corosync_LINK) $(corosync_OBJECTS) $(corosync_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/corosync-apidef.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/corosync-cfg.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/corosync-cmap.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/corosync-coroparse.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/corosync-cpg.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/corosync-icmap.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/corosync-ipc_glue.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/corosync-logconfig.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/corosync-logsys.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/corosync-main.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/corosync-mon.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/corosync-pload.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/corosync-quorum.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/corosync-schedwrk.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/corosync-service.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/corosync-stats.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/corosync-sync.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/corosync-timer.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/corosync-totemconfig.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/corosync-totemip.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/corosync-totemknet.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/corosync-totemnet.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/corosync-totempg.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/corosync-totemsrp.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/corosync-totemudp.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/corosync-totemudpu.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/corosync-util.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/corosync-votequorum.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/corosync-vsf_quorum.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/corosync-vsf_ykd.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/corosync-wd.Po@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+corosync-vsf_ykd.o: vsf_ykd.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -MT corosync-vsf_ykd.o -MD -MP -MF $(DEPDIR)/corosync-vsf_ykd.Tpo -c -o corosync-vsf_ykd.o `test -f 'vsf_ykd.c' || echo '$(srcdir)/'`vsf_ykd.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/corosync-vsf_ykd.Tpo $(DEPDIR)/corosync-vsf_ykd.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vsf_ykd.c' object='corosync-vsf_ykd.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -c -o corosync-vsf_ykd.o `test -f 'vsf_ykd.c' || echo '$(srcdir)/'`vsf_ykd.c
+
+corosync-vsf_ykd.obj: vsf_ykd.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -MT corosync-vsf_ykd.obj -MD -MP -MF $(DEPDIR)/corosync-vsf_ykd.Tpo -c -o corosync-vsf_ykd.obj `if test -f 'vsf_ykd.c'; then $(CYGPATH_W) 'vsf_ykd.c'; else $(CYGPATH_W) '$(srcdir)/vsf_ykd.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/corosync-vsf_ykd.Tpo $(DEPDIR)/corosync-vsf_ykd.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vsf_ykd.c' object='corosync-vsf_ykd.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -c -o corosync-vsf_ykd.obj `if test -f 'vsf_ykd.c'; then $(CYGPATH_W) 'vsf_ykd.c'; else $(CYGPATH_W) '$(srcdir)/vsf_ykd.c'; fi`
+
+corosync-coroparse.o: coroparse.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -MT corosync-coroparse.o -MD -MP -MF $(DEPDIR)/corosync-coroparse.Tpo -c -o corosync-coroparse.o `test -f 'coroparse.c' || echo '$(srcdir)/'`coroparse.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/corosync-coroparse.Tpo $(DEPDIR)/corosync-coroparse.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coroparse.c' object='corosync-coroparse.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -c -o corosync-coroparse.o `test -f 'coroparse.c' || echo '$(srcdir)/'`coroparse.c
+
+corosync-coroparse.obj: coroparse.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -MT corosync-coroparse.obj -MD -MP -MF $(DEPDIR)/corosync-coroparse.Tpo -c -o corosync-coroparse.obj `if test -f 'coroparse.c'; then $(CYGPATH_W) 'coroparse.c'; else $(CYGPATH_W) '$(srcdir)/coroparse.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/corosync-coroparse.Tpo $(DEPDIR)/corosync-coroparse.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coroparse.c' object='corosync-coroparse.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -c -o corosync-coroparse.obj `if test -f 'coroparse.c'; then $(CYGPATH_W) 'coroparse.c'; else $(CYGPATH_W) '$(srcdir)/coroparse.c'; fi`
+
+corosync-vsf_quorum.o: vsf_quorum.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -MT corosync-vsf_quorum.o -MD -MP -MF $(DEPDIR)/corosync-vsf_quorum.Tpo -c -o corosync-vsf_quorum.o `test -f 'vsf_quorum.c' || echo '$(srcdir)/'`vsf_quorum.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/corosync-vsf_quorum.Tpo $(DEPDIR)/corosync-vsf_quorum.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vsf_quorum.c' object='corosync-vsf_quorum.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -c -o corosync-vsf_quorum.o `test -f 'vsf_quorum.c' || echo '$(srcdir)/'`vsf_quorum.c
+
+corosync-vsf_quorum.obj: vsf_quorum.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -MT corosync-vsf_quorum.obj -MD -MP -MF $(DEPDIR)/corosync-vsf_quorum.Tpo -c -o corosync-vsf_quorum.obj `if test -f 'vsf_quorum.c'; then $(CYGPATH_W) 'vsf_quorum.c'; else $(CYGPATH_W) '$(srcdir)/vsf_quorum.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/corosync-vsf_quorum.Tpo $(DEPDIR)/corosync-vsf_quorum.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vsf_quorum.c' object='corosync-vsf_quorum.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -c -o corosync-vsf_quorum.obj `if test -f 'vsf_quorum.c'; then $(CYGPATH_W) 'vsf_quorum.c'; else $(CYGPATH_W) '$(srcdir)/vsf_quorum.c'; fi`
+
+corosync-sync.o: sync.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -MT corosync-sync.o -MD -MP -MF $(DEPDIR)/corosync-sync.Tpo -c -o corosync-sync.o `test -f 'sync.c' || echo '$(srcdir)/'`sync.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/corosync-sync.Tpo $(DEPDIR)/corosync-sync.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='sync.c' object='corosync-sync.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -c -o corosync-sync.o `test -f 'sync.c' || echo '$(srcdir)/'`sync.c
+
+corosync-sync.obj: sync.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -MT corosync-sync.obj -MD -MP -MF $(DEPDIR)/corosync-sync.Tpo -c -o corosync-sync.obj `if test -f 'sync.c'; then $(CYGPATH_W) 'sync.c'; else $(CYGPATH_W) '$(srcdir)/sync.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/corosync-sync.Tpo $(DEPDIR)/corosync-sync.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='sync.c' object='corosync-sync.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -c -o corosync-sync.obj `if test -f 'sync.c'; then $(CYGPATH_W) 'sync.c'; else $(CYGPATH_W) '$(srcdir)/sync.c'; fi`
+
+corosync-logsys.o: logsys.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -MT corosync-logsys.o -MD -MP -MF $(DEPDIR)/corosync-logsys.Tpo -c -o corosync-logsys.o `test -f 'logsys.c' || echo '$(srcdir)/'`logsys.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/corosync-logsys.Tpo $(DEPDIR)/corosync-logsys.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='logsys.c' object='corosync-logsys.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -c -o corosync-logsys.o `test -f 'logsys.c' || echo '$(srcdir)/'`logsys.c
+
+corosync-logsys.obj: logsys.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -MT corosync-logsys.obj -MD -MP -MF $(DEPDIR)/corosync-logsys.Tpo -c -o corosync-logsys.obj `if test -f 'logsys.c'; then $(CYGPATH_W) 'logsys.c'; else $(CYGPATH_W) '$(srcdir)/logsys.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/corosync-logsys.Tpo $(DEPDIR)/corosync-logsys.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='logsys.c' object='corosync-logsys.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -c -o corosync-logsys.obj `if test -f 'logsys.c'; then $(CYGPATH_W) 'logsys.c'; else $(CYGPATH_W) '$(srcdir)/logsys.c'; fi`
+
+corosync-cfg.o: cfg.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -MT corosync-cfg.o -MD -MP -MF $(DEPDIR)/corosync-cfg.Tpo -c -o corosync-cfg.o `test -f 'cfg.c' || echo '$(srcdir)/'`cfg.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/corosync-cfg.Tpo $(DEPDIR)/corosync-cfg.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cfg.c' object='corosync-cfg.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -c -o corosync-cfg.o `test -f 'cfg.c' || echo '$(srcdir)/'`cfg.c
+
+corosync-cfg.obj: cfg.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -MT corosync-cfg.obj -MD -MP -MF $(DEPDIR)/corosync-cfg.Tpo -c -o corosync-cfg.obj `if test -f 'cfg.c'; then $(CYGPATH_W) 'cfg.c'; else $(CYGPATH_W) '$(srcdir)/cfg.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/corosync-cfg.Tpo $(DEPDIR)/corosync-cfg.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cfg.c' object='corosync-cfg.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -c -o corosync-cfg.obj `if test -f 'cfg.c'; then $(CYGPATH_W) 'cfg.c'; else $(CYGPATH_W) '$(srcdir)/cfg.c'; fi`
+
+corosync-cmap.o: cmap.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -MT corosync-cmap.o -MD -MP -MF $(DEPDIR)/corosync-cmap.Tpo -c -o corosync-cmap.o `test -f 'cmap.c' || echo '$(srcdir)/'`cmap.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/corosync-cmap.Tpo $(DEPDIR)/corosync-cmap.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cmap.c' object='corosync-cmap.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -c -o corosync-cmap.o `test -f 'cmap.c' || echo '$(srcdir)/'`cmap.c
+
+corosync-cmap.obj: cmap.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -MT corosync-cmap.obj -MD -MP -MF $(DEPDIR)/corosync-cmap.Tpo -c -o corosync-cmap.obj `if test -f 'cmap.c'; then $(CYGPATH_W) 'cmap.c'; else $(CYGPATH_W) '$(srcdir)/cmap.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/corosync-cmap.Tpo $(DEPDIR)/corosync-cmap.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cmap.c' object='corosync-cmap.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -c -o corosync-cmap.obj `if test -f 'cmap.c'; then $(CYGPATH_W) 'cmap.c'; else $(CYGPATH_W) '$(srcdir)/cmap.c'; fi`
+
+corosync-cpg.o: cpg.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -MT corosync-cpg.o -MD -MP -MF $(DEPDIR)/corosync-cpg.Tpo -c -o corosync-cpg.o `test -f 'cpg.c' || echo '$(srcdir)/'`cpg.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/corosync-cpg.Tpo $(DEPDIR)/corosync-cpg.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpg.c' object='corosync-cpg.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -c -o corosync-cpg.o `test -f 'cpg.c' || echo '$(srcdir)/'`cpg.c
+
+corosync-cpg.obj: cpg.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -MT corosync-cpg.obj -MD -MP -MF $(DEPDIR)/corosync-cpg.Tpo -c -o corosync-cpg.obj `if test -f 'cpg.c'; then $(CYGPATH_W) 'cpg.c'; else $(CYGPATH_W) '$(srcdir)/cpg.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/corosync-cpg.Tpo $(DEPDIR)/corosync-cpg.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpg.c' object='corosync-cpg.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -c -o corosync-cpg.obj `if test -f 'cpg.c'; then $(CYGPATH_W) 'cpg.c'; else $(CYGPATH_W) '$(srcdir)/cpg.c'; fi`
+
+corosync-pload.o: pload.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -MT corosync-pload.o -MD -MP -MF $(DEPDIR)/corosync-pload.Tpo -c -o corosync-pload.o `test -f 'pload.c' || echo '$(srcdir)/'`pload.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/corosync-pload.Tpo $(DEPDIR)/corosync-pload.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pload.c' object='corosync-pload.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -c -o corosync-pload.o `test -f 'pload.c' || echo '$(srcdir)/'`pload.c
+
+corosync-pload.obj: pload.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -MT corosync-pload.obj -MD -MP -MF $(DEPDIR)/corosync-pload.Tpo -c -o corosync-pload.obj `if test -f 'pload.c'; then $(CYGPATH_W) 'pload.c'; else $(CYGPATH_W) '$(srcdir)/pload.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/corosync-pload.Tpo $(DEPDIR)/corosync-pload.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pload.c' object='corosync-pload.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -c -o corosync-pload.obj `if test -f 'pload.c'; then $(CYGPATH_W) 'pload.c'; else $(CYGPATH_W) '$(srcdir)/pload.c'; fi`
+
+corosync-votequorum.o: votequorum.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -MT corosync-votequorum.o -MD -MP -MF $(DEPDIR)/corosync-votequorum.Tpo -c -o corosync-votequorum.o `test -f 'votequorum.c' || echo '$(srcdir)/'`votequorum.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/corosync-votequorum.Tpo $(DEPDIR)/corosync-votequorum.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='votequorum.c' object='corosync-votequorum.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -c -o corosync-votequorum.o `test -f 'votequorum.c' || echo '$(srcdir)/'`votequorum.c
+
+corosync-votequorum.obj: votequorum.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -MT corosync-votequorum.obj -MD -MP -MF $(DEPDIR)/corosync-votequorum.Tpo -c -o corosync-votequorum.obj `if test -f 'votequorum.c'; then $(CYGPATH_W) 'votequorum.c'; else $(CYGPATH_W) '$(srcdir)/votequorum.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/corosync-votequorum.Tpo $(DEPDIR)/corosync-votequorum.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='votequorum.c' object='corosync-votequorum.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -c -o corosync-votequorum.obj `if test -f 'votequorum.c'; then $(CYGPATH_W) 'votequorum.c'; else $(CYGPATH_W) '$(srcdir)/votequorum.c'; fi`
+
+corosync-util.o: util.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -MT corosync-util.o -MD -MP -MF $(DEPDIR)/corosync-util.Tpo -c -o corosync-util.o `test -f 'util.c' || echo '$(srcdir)/'`util.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/corosync-util.Tpo $(DEPDIR)/corosync-util.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='util.c' object='corosync-util.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -c -o corosync-util.o `test -f 'util.c' || echo '$(srcdir)/'`util.c
+
+corosync-util.obj: util.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -MT corosync-util.obj -MD -MP -MF $(DEPDIR)/corosync-util.Tpo -c -o corosync-util.obj `if test -f 'util.c'; then $(CYGPATH_W) 'util.c'; else $(CYGPATH_W) '$(srcdir)/util.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/corosync-util.Tpo $(DEPDIR)/corosync-util.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='util.c' object='corosync-util.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -c -o corosync-util.obj `if test -f 'util.c'; then $(CYGPATH_W) 'util.c'; else $(CYGPATH_W) '$(srcdir)/util.c'; fi`
+
+corosync-schedwrk.o: schedwrk.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -MT corosync-schedwrk.o -MD -MP -MF $(DEPDIR)/corosync-schedwrk.Tpo -c -o corosync-schedwrk.o `test -f 'schedwrk.c' || echo '$(srcdir)/'`schedwrk.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/corosync-schedwrk.Tpo $(DEPDIR)/corosync-schedwrk.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='schedwrk.c' object='corosync-schedwrk.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -c -o corosync-schedwrk.o `test -f 'schedwrk.c' || echo '$(srcdir)/'`schedwrk.c
+
+corosync-schedwrk.obj: schedwrk.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -MT corosync-schedwrk.obj -MD -MP -MF $(DEPDIR)/corosync-schedwrk.Tpo -c -o corosync-schedwrk.obj `if test -f 'schedwrk.c'; then $(CYGPATH_W) 'schedwrk.c'; else $(CYGPATH_W) '$(srcdir)/schedwrk.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/corosync-schedwrk.Tpo $(DEPDIR)/corosync-schedwrk.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='schedwrk.c' object='corosync-schedwrk.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -c -o corosync-schedwrk.obj `if test -f 'schedwrk.c'; then $(CYGPATH_W) 'schedwrk.c'; else $(CYGPATH_W) '$(srcdir)/schedwrk.c'; fi`
+
+corosync-main.o: main.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -MT corosync-main.o -MD -MP -MF $(DEPDIR)/corosync-main.Tpo -c -o corosync-main.o `test -f 'main.c' || echo '$(srcdir)/'`main.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/corosync-main.Tpo $(DEPDIR)/corosync-main.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='main.c' object='corosync-main.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -c -o corosync-main.o `test -f 'main.c' || echo '$(srcdir)/'`main.c
+
+corosync-main.obj: main.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -MT corosync-main.obj -MD -MP -MF $(DEPDIR)/corosync-main.Tpo -c -o corosync-main.obj `if test -f 'main.c'; then $(CYGPATH_W) 'main.c'; else $(CYGPATH_W) '$(srcdir)/main.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/corosync-main.Tpo $(DEPDIR)/corosync-main.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='main.c' object='corosync-main.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -c -o corosync-main.obj `if test -f 'main.c'; then $(CYGPATH_W) 'main.c'; else $(CYGPATH_W) '$(srcdir)/main.c'; fi`
+
+corosync-apidef.o: apidef.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -MT corosync-apidef.o -MD -MP -MF $(DEPDIR)/corosync-apidef.Tpo -c -o corosync-apidef.o `test -f 'apidef.c' || echo '$(srcdir)/'`apidef.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/corosync-apidef.Tpo $(DEPDIR)/corosync-apidef.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='apidef.c' object='corosync-apidef.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -c -o corosync-apidef.o `test -f 'apidef.c' || echo '$(srcdir)/'`apidef.c
+
+corosync-apidef.obj: apidef.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -MT corosync-apidef.obj -MD -MP -MF $(DEPDIR)/corosync-apidef.Tpo -c -o corosync-apidef.obj `if test -f 'apidef.c'; then $(CYGPATH_W) 'apidef.c'; else $(CYGPATH_W) '$(srcdir)/apidef.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/corosync-apidef.Tpo $(DEPDIR)/corosync-apidef.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='apidef.c' object='corosync-apidef.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -c -o corosync-apidef.obj `if test -f 'apidef.c'; then $(CYGPATH_W) 'apidef.c'; else $(CYGPATH_W) '$(srcdir)/apidef.c'; fi`
+
+corosync-quorum.o: quorum.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -MT corosync-quorum.o -MD -MP -MF $(DEPDIR)/corosync-quorum.Tpo -c -o corosync-quorum.o `test -f 'quorum.c' || echo '$(srcdir)/'`quorum.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/corosync-quorum.Tpo $(DEPDIR)/corosync-quorum.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='quorum.c' object='corosync-quorum.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -c -o corosync-quorum.o `test -f 'quorum.c' || echo '$(srcdir)/'`quorum.c
+
+corosync-quorum.obj: quorum.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -MT corosync-quorum.obj -MD -MP -MF $(DEPDIR)/corosync-quorum.Tpo -c -o corosync-quorum.obj `if test -f 'quorum.c'; then $(CYGPATH_W) 'quorum.c'; else $(CYGPATH_W) '$(srcdir)/quorum.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/corosync-quorum.Tpo $(DEPDIR)/corosync-quorum.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='quorum.c' object='corosync-quorum.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -c -o corosync-quorum.obj `if test -f 'quorum.c'; then $(CYGPATH_W) 'quorum.c'; else $(CYGPATH_W) '$(srcdir)/quorum.c'; fi`
+
+corosync-icmap.o: icmap.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -MT corosync-icmap.o -MD -MP -MF $(DEPDIR)/corosync-icmap.Tpo -c -o corosync-icmap.o `test -f 'icmap.c' || echo '$(srcdir)/'`icmap.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/corosync-icmap.Tpo $(DEPDIR)/corosync-icmap.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='icmap.c' object='corosync-icmap.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -c -o corosync-icmap.o `test -f 'icmap.c' || echo '$(srcdir)/'`icmap.c
+
+corosync-icmap.obj: icmap.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -MT corosync-icmap.obj -MD -MP -MF $(DEPDIR)/corosync-icmap.Tpo -c -o corosync-icmap.obj `if test -f 'icmap.c'; then $(CYGPATH_W) 'icmap.c'; else $(CYGPATH_W) '$(srcdir)/icmap.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/corosync-icmap.Tpo $(DEPDIR)/corosync-icmap.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='icmap.c' object='corosync-icmap.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -c -o corosync-icmap.obj `if test -f 'icmap.c'; then $(CYGPATH_W) 'icmap.c'; else $(CYGPATH_W) '$(srcdir)/icmap.c'; fi`
+
+corosync-timer.o: timer.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -MT corosync-timer.o -MD -MP -MF $(DEPDIR)/corosync-timer.Tpo -c -o corosync-timer.o `test -f 'timer.c' || echo '$(srcdir)/'`timer.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/corosync-timer.Tpo $(DEPDIR)/corosync-timer.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='timer.c' object='corosync-timer.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -c -o corosync-timer.o `test -f 'timer.c' || echo '$(srcdir)/'`timer.c
+
+corosync-timer.obj: timer.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -MT corosync-timer.obj -MD -MP -MF $(DEPDIR)/corosync-timer.Tpo -c -o corosync-timer.obj `if test -f 'timer.c'; then $(CYGPATH_W) 'timer.c'; else $(CYGPATH_W) '$(srcdir)/timer.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/corosync-timer.Tpo $(DEPDIR)/corosync-timer.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='timer.c' object='corosync-timer.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -c -o corosync-timer.obj `if test -f 'timer.c'; then $(CYGPATH_W) 'timer.c'; else $(CYGPATH_W) '$(srcdir)/timer.c'; fi`
+
+corosync-stats.o: stats.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -MT corosync-stats.o -MD -MP -MF $(DEPDIR)/corosync-stats.Tpo -c -o corosync-stats.o `test -f 'stats.c' || echo '$(srcdir)/'`stats.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/corosync-stats.Tpo $(DEPDIR)/corosync-stats.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='stats.c' object='corosync-stats.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -c -o corosync-stats.o `test -f 'stats.c' || echo '$(srcdir)/'`stats.c
+
+corosync-stats.obj: stats.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -MT corosync-stats.obj -MD -MP -MF $(DEPDIR)/corosync-stats.Tpo -c -o corosync-stats.obj `if test -f 'stats.c'; then $(CYGPATH_W) 'stats.c'; else $(CYGPATH_W) '$(srcdir)/stats.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/corosync-stats.Tpo $(DEPDIR)/corosync-stats.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='stats.c' object='corosync-stats.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -c -o corosync-stats.obj `if test -f 'stats.c'; then $(CYGPATH_W) 'stats.c'; else $(CYGPATH_W) '$(srcdir)/stats.c'; fi`
+
+corosync-ipc_glue.o: ipc_glue.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -MT corosync-ipc_glue.o -MD -MP -MF $(DEPDIR)/corosync-ipc_glue.Tpo -c -o corosync-ipc_glue.o `test -f 'ipc_glue.c' || echo '$(srcdir)/'`ipc_glue.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/corosync-ipc_glue.Tpo $(DEPDIR)/corosync-ipc_glue.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ipc_glue.c' object='corosync-ipc_glue.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -c -o corosync-ipc_glue.o `test -f 'ipc_glue.c' || echo '$(srcdir)/'`ipc_glue.c
+
+corosync-ipc_glue.obj: ipc_glue.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -MT corosync-ipc_glue.obj -MD -MP -MF $(DEPDIR)/corosync-ipc_glue.Tpo -c -o corosync-ipc_glue.obj `if test -f 'ipc_glue.c'; then $(CYGPATH_W) 'ipc_glue.c'; else $(CYGPATH_W) '$(srcdir)/ipc_glue.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/corosync-ipc_glue.Tpo $(DEPDIR)/corosync-ipc_glue.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ipc_glue.c' object='corosync-ipc_glue.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -c -o corosync-ipc_glue.obj `if test -f 'ipc_glue.c'; then $(CYGPATH_W) 'ipc_glue.c'; else $(CYGPATH_W) '$(srcdir)/ipc_glue.c'; fi`
+
+corosync-service.o: service.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -MT corosync-service.o -MD -MP -MF $(DEPDIR)/corosync-service.Tpo -c -o corosync-service.o `test -f 'service.c' || echo '$(srcdir)/'`service.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/corosync-service.Tpo $(DEPDIR)/corosync-service.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='service.c' object='corosync-service.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -c -o corosync-service.o `test -f 'service.c' || echo '$(srcdir)/'`service.c
+
+corosync-service.obj: service.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -MT corosync-service.obj -MD -MP -MF $(DEPDIR)/corosync-service.Tpo -c -o corosync-service.obj `if test -f 'service.c'; then $(CYGPATH_W) 'service.c'; else $(CYGPATH_W) '$(srcdir)/service.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/corosync-service.Tpo $(DEPDIR)/corosync-service.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='service.c' object='corosync-service.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -c -o corosync-service.obj `if test -f 'service.c'; then $(CYGPATH_W) 'service.c'; else $(CYGPATH_W) '$(srcdir)/service.c'; fi`
+
+corosync-logconfig.o: logconfig.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -MT corosync-logconfig.o -MD -MP -MF $(DEPDIR)/corosync-logconfig.Tpo -c -o corosync-logconfig.o `test -f 'logconfig.c' || echo '$(srcdir)/'`logconfig.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/corosync-logconfig.Tpo $(DEPDIR)/corosync-logconfig.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='logconfig.c' object='corosync-logconfig.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -c -o corosync-logconfig.o `test -f 'logconfig.c' || echo '$(srcdir)/'`logconfig.c
+
+corosync-logconfig.obj: logconfig.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -MT corosync-logconfig.obj -MD -MP -MF $(DEPDIR)/corosync-logconfig.Tpo -c -o corosync-logconfig.obj `if test -f 'logconfig.c'; then $(CYGPATH_W) 'logconfig.c'; else $(CYGPATH_W) '$(srcdir)/logconfig.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/corosync-logconfig.Tpo $(DEPDIR)/corosync-logconfig.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='logconfig.c' object='corosync-logconfig.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -c -o corosync-logconfig.obj `if test -f 'logconfig.c'; then $(CYGPATH_W) 'logconfig.c'; else $(CYGPATH_W) '$(srcdir)/logconfig.c'; fi`
+
+corosync-totemconfig.o: totemconfig.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -MT corosync-totemconfig.o -MD -MP -MF $(DEPDIR)/corosync-totemconfig.Tpo -c -o corosync-totemconfig.o `test -f 'totemconfig.c' || echo '$(srcdir)/'`totemconfig.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/corosync-totemconfig.Tpo $(DEPDIR)/corosync-totemconfig.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='totemconfig.c' object='corosync-totemconfig.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -c -o corosync-totemconfig.o `test -f 'totemconfig.c' || echo '$(srcdir)/'`totemconfig.c
+
+corosync-totemconfig.obj: totemconfig.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -MT corosync-totemconfig.obj -MD -MP -MF $(DEPDIR)/corosync-totemconfig.Tpo -c -o corosync-totemconfig.obj `if test -f 'totemconfig.c'; then $(CYGPATH_W) 'totemconfig.c'; else $(CYGPATH_W) '$(srcdir)/totemconfig.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/corosync-totemconfig.Tpo $(DEPDIR)/corosync-totemconfig.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='totemconfig.c' object='corosync-totemconfig.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -c -o corosync-totemconfig.obj `if test -f 'totemconfig.c'; then $(CYGPATH_W) 'totemconfig.c'; else $(CYGPATH_W) '$(srcdir)/totemconfig.c'; fi`
+
+corosync-totemip.o: totemip.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -MT corosync-totemip.o -MD -MP -MF $(DEPDIR)/corosync-totemip.Tpo -c -o corosync-totemip.o `test -f 'totemip.c' || echo '$(srcdir)/'`totemip.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/corosync-totemip.Tpo $(DEPDIR)/corosync-totemip.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='totemip.c' object='corosync-totemip.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -c -o corosync-totemip.o `test -f 'totemip.c' || echo '$(srcdir)/'`totemip.c
+
+corosync-totemip.obj: totemip.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -MT corosync-totemip.obj -MD -MP -MF $(DEPDIR)/corosync-totemip.Tpo -c -o corosync-totemip.obj `if test -f 'totemip.c'; then $(CYGPATH_W) 'totemip.c'; else $(CYGPATH_W) '$(srcdir)/totemip.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/corosync-totemip.Tpo $(DEPDIR)/corosync-totemip.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='totemip.c' object='corosync-totemip.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -c -o corosync-totemip.obj `if test -f 'totemip.c'; then $(CYGPATH_W) 'totemip.c'; else $(CYGPATH_W) '$(srcdir)/totemip.c'; fi`
+
+corosync-totemnet.o: totemnet.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -MT corosync-totemnet.o -MD -MP -MF $(DEPDIR)/corosync-totemnet.Tpo -c -o corosync-totemnet.o `test -f 'totemnet.c' || echo '$(srcdir)/'`totemnet.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/corosync-totemnet.Tpo $(DEPDIR)/corosync-totemnet.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='totemnet.c' object='corosync-totemnet.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -c -o corosync-totemnet.o `test -f 'totemnet.c' || echo '$(srcdir)/'`totemnet.c
+
+corosync-totemnet.obj: totemnet.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -MT corosync-totemnet.obj -MD -MP -MF $(DEPDIR)/corosync-totemnet.Tpo -c -o corosync-totemnet.obj `if test -f 'totemnet.c'; then $(CYGPATH_W) 'totemnet.c'; else $(CYGPATH_W) '$(srcdir)/totemnet.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/corosync-totemnet.Tpo $(DEPDIR)/corosync-totemnet.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='totemnet.c' object='corosync-totemnet.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -c -o corosync-totemnet.obj `if test -f 'totemnet.c'; then $(CYGPATH_W) 'totemnet.c'; else $(CYGPATH_W) '$(srcdir)/totemnet.c'; fi`
+
+corosync-totemudp.o: totemudp.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -MT corosync-totemudp.o -MD -MP -MF $(DEPDIR)/corosync-totemudp.Tpo -c -o corosync-totemudp.o `test -f 'totemudp.c' || echo '$(srcdir)/'`totemudp.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/corosync-totemudp.Tpo $(DEPDIR)/corosync-totemudp.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='totemudp.c' object='corosync-totemudp.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -c -o corosync-totemudp.o `test -f 'totemudp.c' || echo '$(srcdir)/'`totemudp.c
+
+corosync-totemudp.obj: totemudp.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -MT corosync-totemudp.obj -MD -MP -MF $(DEPDIR)/corosync-totemudp.Tpo -c -o corosync-totemudp.obj `if test -f 'totemudp.c'; then $(CYGPATH_W) 'totemudp.c'; else $(CYGPATH_W) '$(srcdir)/totemudp.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/corosync-totemudp.Tpo $(DEPDIR)/corosync-totemudp.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='totemudp.c' object='corosync-totemudp.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -c -o corosync-totemudp.obj `if test -f 'totemudp.c'; then $(CYGPATH_W) 'totemudp.c'; else $(CYGPATH_W) '$(srcdir)/totemudp.c'; fi`
+
+corosync-totemudpu.o: totemudpu.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -MT corosync-totemudpu.o -MD -MP -MF $(DEPDIR)/corosync-totemudpu.Tpo -c -o corosync-totemudpu.o `test -f 'totemudpu.c' || echo '$(srcdir)/'`totemudpu.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/corosync-totemudpu.Tpo $(DEPDIR)/corosync-totemudpu.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='totemudpu.c' object='corosync-totemudpu.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -c -o corosync-totemudpu.o `test -f 'totemudpu.c' || echo '$(srcdir)/'`totemudpu.c
+
+corosync-totemudpu.obj: totemudpu.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -MT corosync-totemudpu.obj -MD -MP -MF $(DEPDIR)/corosync-totemudpu.Tpo -c -o corosync-totemudpu.obj `if test -f 'totemudpu.c'; then $(CYGPATH_W) 'totemudpu.c'; else $(CYGPATH_W) '$(srcdir)/totemudpu.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/corosync-totemudpu.Tpo $(DEPDIR)/corosync-totemudpu.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='totemudpu.c' object='corosync-totemudpu.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -c -o corosync-totemudpu.obj `if test -f 'totemudpu.c'; then $(CYGPATH_W) 'totemudpu.c'; else $(CYGPATH_W) '$(srcdir)/totemudpu.c'; fi`
+
+corosync-totemsrp.o: totemsrp.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -MT corosync-totemsrp.o -MD -MP -MF $(DEPDIR)/corosync-totemsrp.Tpo -c -o corosync-totemsrp.o `test -f 'totemsrp.c' || echo '$(srcdir)/'`totemsrp.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/corosync-totemsrp.Tpo $(DEPDIR)/corosync-totemsrp.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='totemsrp.c' object='corosync-totemsrp.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -c -o corosync-totemsrp.o `test -f 'totemsrp.c' || echo '$(srcdir)/'`totemsrp.c
+
+corosync-totemsrp.obj: totemsrp.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -MT corosync-totemsrp.obj -MD -MP -MF $(DEPDIR)/corosync-totemsrp.Tpo -c -o corosync-totemsrp.obj `if test -f 'totemsrp.c'; then $(CYGPATH_W) 'totemsrp.c'; else $(CYGPATH_W) '$(srcdir)/totemsrp.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/corosync-totemsrp.Tpo $(DEPDIR)/corosync-totemsrp.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='totemsrp.c' object='corosync-totemsrp.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -c -o corosync-totemsrp.obj `if test -f 'totemsrp.c'; then $(CYGPATH_W) 'totemsrp.c'; else $(CYGPATH_W) '$(srcdir)/totemsrp.c'; fi`
+
+corosync-totempg.o: totempg.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -MT corosync-totempg.o -MD -MP -MF $(DEPDIR)/corosync-totempg.Tpo -c -o corosync-totempg.o `test -f 'totempg.c' || echo '$(srcdir)/'`totempg.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/corosync-totempg.Tpo $(DEPDIR)/corosync-totempg.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='totempg.c' object='corosync-totempg.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -c -o corosync-totempg.o `test -f 'totempg.c' || echo '$(srcdir)/'`totempg.c
+
+corosync-totempg.obj: totempg.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -MT corosync-totempg.obj -MD -MP -MF $(DEPDIR)/corosync-totempg.Tpo -c -o corosync-totempg.obj `if test -f 'totempg.c'; then $(CYGPATH_W) 'totempg.c'; else $(CYGPATH_W) '$(srcdir)/totempg.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/corosync-totempg.Tpo $(DEPDIR)/corosync-totempg.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='totempg.c' object='corosync-totempg.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -c -o corosync-totempg.obj `if test -f 'totempg.c'; then $(CYGPATH_W) 'totempg.c'; else $(CYGPATH_W) '$(srcdir)/totempg.c'; fi`
+
+corosync-totemknet.o: totemknet.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -MT corosync-totemknet.o -MD -MP -MF $(DEPDIR)/corosync-totemknet.Tpo -c -o corosync-totemknet.o `test -f 'totemknet.c' || echo '$(srcdir)/'`totemknet.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/corosync-totemknet.Tpo $(DEPDIR)/corosync-totemknet.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='totemknet.c' object='corosync-totemknet.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -c -o corosync-totemknet.o `test -f 'totemknet.c' || echo '$(srcdir)/'`totemknet.c
+
+corosync-totemknet.obj: totemknet.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -MT corosync-totemknet.obj -MD -MP -MF $(DEPDIR)/corosync-totemknet.Tpo -c -o corosync-totemknet.obj `if test -f 'totemknet.c'; then $(CYGPATH_W) 'totemknet.c'; else $(CYGPATH_W) '$(srcdir)/totemknet.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/corosync-totemknet.Tpo $(DEPDIR)/corosync-totemknet.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='totemknet.c' object='corosync-totemknet.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -c -o corosync-totemknet.obj `if test -f 'totemknet.c'; then $(CYGPATH_W) 'totemknet.c'; else $(CYGPATH_W) '$(srcdir)/totemknet.c'; fi`
+
+corosync-mon.o: mon.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -MT corosync-mon.o -MD -MP -MF $(DEPDIR)/corosync-mon.Tpo -c -o corosync-mon.o `test -f 'mon.c' || echo '$(srcdir)/'`mon.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/corosync-mon.Tpo $(DEPDIR)/corosync-mon.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='mon.c' object='corosync-mon.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -c -o corosync-mon.o `test -f 'mon.c' || echo '$(srcdir)/'`mon.c
+
+corosync-mon.obj: mon.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -MT corosync-mon.obj -MD -MP -MF $(DEPDIR)/corosync-mon.Tpo -c -o corosync-mon.obj `if test -f 'mon.c'; then $(CYGPATH_W) 'mon.c'; else $(CYGPATH_W) '$(srcdir)/mon.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/corosync-mon.Tpo $(DEPDIR)/corosync-mon.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='mon.c' object='corosync-mon.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -c -o corosync-mon.obj `if test -f 'mon.c'; then $(CYGPATH_W) 'mon.c'; else $(CYGPATH_W) '$(srcdir)/mon.c'; fi`
+
+corosync-wd.o: wd.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -MT corosync-wd.o -MD -MP -MF $(DEPDIR)/corosync-wd.Tpo -c -o corosync-wd.o `test -f 'wd.c' || echo '$(srcdir)/'`wd.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/corosync-wd.Tpo $(DEPDIR)/corosync-wd.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='wd.c' object='corosync-wd.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -c -o corosync-wd.o `test -f 'wd.c' || echo '$(srcdir)/'`wd.c
+
+corosync-wd.obj: wd.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -MT corosync-wd.obj -MD -MP -MF $(DEPDIR)/corosync-wd.Tpo -c -o corosync-wd.obj `if test -f 'wd.c'; then $(CYGPATH_W) 'wd.c'; else $(CYGPATH_W) '$(srcdir)/wd.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/corosync-wd.Tpo $(DEPDIR)/corosync-wd.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='wd.c' object='corosync-wd.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(corosync_CPPFLAGS) $(CPPFLAGS) $(corosync_CFLAGS) $(CFLAGS) -c -o corosync-wd.obj `if test -f 'wd.c'; then $(CYGPATH_W) 'wd.c'; else $(CYGPATH_W) '$(srcdir)/wd.c'; fi`
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(PROGRAMS) $(HEADERS)
+installdirs:
+ for dir in "$(DESTDIR)$(sbindir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+ -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-sbinPROGRAMS \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am: install-sbinPROGRAMS
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-sbinPROGRAMS
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
+ clean-libtool clean-sbinPROGRAMS cscopelist-am ctags ctags-am \
+ distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-dvi install-dvi-am install-exec \
+ install-exec-am install-html install-html-am install-info \
+ install-info-am install-man install-pdf install-pdf-am \
+ install-ps install-ps-am install-sbinPROGRAMS install-strip \
+ installcheck installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags tags-am uninstall uninstall-am uninstall-sbinPROGRAMS
+
+
+lint:
+ -splint $(LINT_FLAGS) $(CPPFLAGS) $(CFLAGS) *.c
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/exec/apidef.c b/exec/apidef.c
new file mode 100644
index 0000000..8805973
--- /dev/null
+++ b/exec/apidef.c
@@ -0,0 +1,149 @@
+/*
+ * Copyright (c) 2008-2012 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Author: Steven Dake (sdake@redhat.com)
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of the MontaVista Software, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <qb/qbutil.h>
+#include <qb/qbloop.h>
+#include <qb/qbipcs.h>
+
+#include <corosync/corotypes.h>
+#include <corosync/totem/totempg.h>
+#include <corosync/totem/totemip.h>
+#include <corosync/totem/totem.h>
+#include <corosync/logsys.h>
+#include "util.h"
+#include "timer.h"
+#include "quorum.h"
+#include "schedwrk.h"
+#include "main.h"
+#include "apidef.h"
+#include "service.h"
+
+LOGSYS_DECLARE_SUBSYS ("APIDEF");
+
+/*
+ * Remove compile warnings about type name changes in corosync_tpg_group
+ */
+typedef int (*typedef_tpg_join) (
+ void *,
+ const struct corosync_tpg_group *,
+ size_t);
+
+typedef int (*typedef_tpg_leave) (void *,
+ const struct corosync_tpg_group *,
+ size_t);
+
+typedef int (*typedef_tpg_groups_mcast_groups) (
+ void *, int,
+ const struct corosync_tpg_group *,
+ size_t groups_cnt,
+ const struct iovec *,
+ unsigned int);
+
+typedef int (*typedef_tpg_groups_send_ok) (
+ void *,
+ const struct corosync_tpg_group *,
+ size_t groups_cnt,
+ struct iovec *,
+ int);
+
+static inline void _corosync_public_exit_error (cs_fatal_error_t err,
+ const char *file,
+ unsigned int line)
+ __attribute__((noreturn));
+static inline void _corosync_public_exit_error (
+ cs_fatal_error_t err, const char *file, unsigned int line)
+{
+ _corosync_exit_error (err, file, line);
+}
+
+static struct corosync_api_v1 apidef_corosync_api_v1 = {
+ .timer_add_duration = corosync_timer_add_duration,
+ .timer_add_absolute = corosync_timer_add_absolute,
+ .timer_delete = corosync_timer_delete,
+ .timer_time_get = cs_timer_time_get,
+ .timer_expire_time_get = corosync_timer_expire_time_get,
+ .ipc_source_set = message_source_set,
+ .ipc_source_is_local = message_source_is_local,
+ .ipc_private_data_get = cs_ipcs_private_data_get,
+ .ipc_response_iov_send = cs_ipcs_response_iov_send,
+ .ipc_response_send = cs_ipcs_response_send,
+ .ipc_dispatch_send = cs_ipcs_dispatch_send,
+ .ipc_dispatch_iov_send = cs_ipcs_dispatch_iov_send,
+ .ipc_refcnt_inc = cs_ipc_refcnt_inc,
+ .ipc_refcnt_dec = cs_ipc_refcnt_dec,
+ .totem_nodeid_get = totempg_my_nodeid_get,
+ .totem_family_get = totempg_my_family_get,
+ .totem_mcast = main_mcast,
+ .totem_ifaces_get = totempg_ifaces_get,
+ .totem_ifaces_print = totempg_ifaces_print,
+ .totem_ip_print = totemip_print,
+ .totem_crypto_set = totempg_crypto_set,
+ .totem_callback_token_create = totempg_callback_token_create,
+ .totem_get_stats = totempg_get_stats,
+ .tpg_init = totempg_groups_initialize,
+ .tpg_exit = NULL, /* missing from totempg api */
+ .tpg_join = (typedef_tpg_join)totempg_groups_join,
+ .tpg_leave = (typedef_tpg_leave)totempg_groups_leave,
+ .tpg_joined_mcast = totempg_groups_mcast_joined,
+ .tpg_joined_reserve = totempg_groups_joined_reserve,
+ .tpg_joined_release = totempg_groups_joined_release,
+ .tpg_groups_mcast = (typedef_tpg_groups_mcast_groups)totempg_groups_mcast_groups,
+ .tpg_groups_reserve = NULL,
+ .tpg_groups_release = NULL,
+ .schedwrk_create = schedwrk_create,
+ .schedwrk_create_nolock = schedwrk_create_nolock,
+ .schedwrk_destroy = schedwrk_destroy,
+ .sync_request = NULL, //sync_request,
+ .quorum_is_quorate = corosync_quorum_is_quorate,
+ .quorum_register_callback = corosync_quorum_register_callback,
+ .quorum_unregister_callback = corosync_quorum_unregister_callback,
+ .quorum_initialize = corosync_quorum_initialize,
+ .error_memory_failure = _corosync_out_of_memory_error,
+ .fatal_error = _corosync_public_exit_error,
+ .shutdown_request = corosync_shutdown_request,
+ .state_dump = corosync_state_dump,
+ .poll_handle_get = cs_poll_handle_get,
+ .poll_dispatch_add = cs_poll_dispatch_add,
+ .poll_dispatch_delete = cs_poll_dispatch_delete
+};
+
+struct corosync_api_v1 *apidef_get (void)
+{
+ return (&apidef_corosync_api_v1);
+}
diff --git a/exec/apidef.h b/exec/apidef.h
new file mode 100644
index 0000000..52812d4
--- /dev/null
+++ b/exec/apidef.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2008-2012 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Author: Steven Dake (sdake@redhat.com)
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of the MontaVista Software, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef APIDEF_H_DEFINED
+#define APIDEF_H_DEFINED
+
+#include <corosync/coroapi.h>
+
+extern struct corosync_api_v1 *apidef_get (void);
+
+#endif /* APIDEF_H_DEFINED*/
diff --git a/exec/cfg.c b/exec/cfg.c
new file mode 100644
index 0000000..fe5f551
--- /dev/null
+++ b/exec/cfg.c
@@ -0,0 +1,1470 @@
+/*
+ * Copyright (c) 2005-2006 MontaVista Software, Inc.
+ * Copyright (c) 2006-2018 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Author: Steven Dake (sdake@redhat.com)
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of the MontaVista Software, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <sys/uio.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stddef.h>
+#include <limits.h>
+#include <errno.h>
+#include <string.h>
+#include <assert.h>
+
+#include <corosync/corotypes.h>
+#include <qb/qbipc_common.h>
+#include <corosync/cfg.h>
+#include <qb/qblist.h>
+#include <qb/qbutil.h>
+#include <corosync/mar_gen.h>
+#include <corosync/totem/totemip.h>
+#include <corosync/totem/totem.h>
+#include <corosync/ipc_cfg.h>
+#include <corosync/logsys.h>
+#include <corosync/coroapi.h>
+#include <corosync/icmap.h>
+#include <corosync/corodefs.h>
+
+#include "totemconfig.h"
+#include "totemknet.h"
+#include "service.h"
+#include "main.h"
+
+LOGSYS_DECLARE_SUBSYS ("CFG");
+
+enum cfg_message_req_types {
+ MESSAGE_REQ_EXEC_CFG_RINGREENABLE = 0,
+ MESSAGE_REQ_EXEC_CFG_KILLNODE = 1,
+ MESSAGE_REQ_EXEC_CFG_SHUTDOWN = 2,
+ MESSAGE_REQ_EXEC_CFG_RELOAD_CONFIG = 3,
+ MESSAGE_REQ_EXEC_CFG_CRYPTO_RECONFIG = 4
+};
+
+/* in milliseconds */
+#define DEFAULT_SHUTDOWN_TIMEOUT 5000
+
+static struct qb_list_head trackers_list;
+
+/*
+ * Variables controlling a requested shutdown
+ */
+static corosync_timer_handle_t shutdown_timer;
+static struct cfg_info *shutdown_con;
+static uint32_t shutdown_flags;
+static int shutdown_yes;
+static int shutdown_no;
+static int shutdown_expected;
+
+struct cfg_info
+{
+ struct qb_list_head list;
+ void *conn;
+ void *tracker_conn;
+ enum {SHUTDOWN_REPLY_UNKNOWN, SHUTDOWN_REPLY_YES, SHUTDOWN_REPLY_NO} shutdown_reply;
+};
+
+static void cfg_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 char *cfg_exec_init_fn (struct corosync_api_v1 *corosync_api_v1);
+
+static struct corosync_api_v1 *api;
+
+static int cfg_lib_init_fn (void *conn);
+
+static int cfg_lib_exit_fn (void *conn);
+
+static void message_handler_req_exec_cfg_ringreenable (
+ const void *message,
+ unsigned int nodeid);
+
+static void message_handler_req_exec_cfg_killnode (
+ const void *message,
+ unsigned int nodeid);
+
+static void message_handler_req_exec_cfg_shutdown (
+ const void *message,
+ unsigned int nodeid);
+
+static void message_handler_req_exec_cfg_reload_config (
+ const void *message,
+ unsigned int nodeid);
+
+static void message_handler_req_exec_cfg_reconfig_crypto (
+ const void *message,
+ unsigned int nodeid);
+
+static void exec_cfg_killnode_endian_convert (void *msg);
+
+static void message_handler_req_lib_cfg_ringstatusget (
+ void *conn,
+ const void *msg);
+
+static void message_handler_req_lib_cfg_nodestatusget (
+ void *conn,
+ const void *msg);
+
+static void message_handler_req_lib_cfg_ringreenable (
+ void *conn,
+ const void *msg);
+
+static void message_handler_req_lib_cfg_killnode (
+ void *conn,
+ const void *msg);
+
+static void message_handler_req_lib_cfg_tryshutdown (
+ void *conn,
+ const void *msg);
+
+static void message_handler_req_lib_cfg_replytoshutdown (
+ void *conn,
+ const void *msg);
+
+static void message_handler_req_lib_cfg_trackstart (
+ void *conn,
+ const void *msg);
+
+static void message_handler_req_lib_cfg_trackstop (
+ void *conn,
+ const void *msg);
+
+static void message_handler_req_lib_cfg_get_node_addrs (
+ void *conn,
+ const void *msg);
+
+static void message_handler_req_lib_cfg_local_get (
+ void *conn,
+ const void *msg);
+
+static void message_handler_req_lib_cfg_reload_config (
+ void *conn,
+ const void *msg);
+
+static void message_handler_req_lib_cfg_reopen_log_files (
+ void *conn,
+ const void *msg);
+
+/*
+ * Service Handler Definition
+ */
+static struct corosync_lib_handler cfg_lib_engine[] =
+{
+ { /* 0 */
+ .lib_handler_fn = message_handler_req_lib_cfg_ringstatusget,
+ .flow_control = CS_LIB_FLOW_CONTROL_REQUIRED
+ },
+ { /* 1 */
+ .lib_handler_fn = message_handler_req_lib_cfg_ringreenable,
+ .flow_control = CS_LIB_FLOW_CONTROL_REQUIRED
+ },
+ { /* 2 */
+ .lib_handler_fn = message_handler_req_lib_cfg_killnode,
+ .flow_control = CS_LIB_FLOW_CONTROL_REQUIRED
+ },
+ { /* 3 */
+ .lib_handler_fn = message_handler_req_lib_cfg_tryshutdown,
+ .flow_control = CS_LIB_FLOW_CONTROL_REQUIRED
+ },
+ { /* 4 */
+ .lib_handler_fn = message_handler_req_lib_cfg_replytoshutdown,
+ .flow_control = CS_LIB_FLOW_CONTROL_REQUIRED
+ },
+ { /* 5 */
+ .lib_handler_fn = message_handler_req_lib_cfg_get_node_addrs,
+ .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED
+ },
+ { /* 6 */
+ .lib_handler_fn = message_handler_req_lib_cfg_local_get,
+ .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED
+ },
+ { /* 7 */
+ .lib_handler_fn = message_handler_req_lib_cfg_reload_config,
+ .flow_control = CS_LIB_FLOW_CONTROL_REQUIRED
+ },
+ { /* 8 */
+ .lib_handler_fn = message_handler_req_lib_cfg_reopen_log_files,
+ .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED
+ },
+ { /* 9 */
+ .lib_handler_fn = message_handler_req_lib_cfg_nodestatusget,
+ .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED
+ },
+ { /* 10 */
+ .lib_handler_fn = message_handler_req_lib_cfg_trackstart,
+ .flow_control = CS_LIB_FLOW_CONTROL_REQUIRED
+ },
+ { /* 11 */
+ .lib_handler_fn = message_handler_req_lib_cfg_trackstop,
+ .flow_control = CS_LIB_FLOW_CONTROL_REQUIRED
+ },
+
+};
+
+static struct corosync_exec_handler cfg_exec_engine[] =
+{
+ { /* 0 */
+ .exec_handler_fn = message_handler_req_exec_cfg_ringreenable,
+ },
+ { /* 1 */
+ .exec_handler_fn = message_handler_req_exec_cfg_killnode,
+ .exec_endian_convert_fn = exec_cfg_killnode_endian_convert
+ },
+ { /* 2 */
+ .exec_handler_fn = message_handler_req_exec_cfg_shutdown,
+ },
+ { /* 3 */
+ .exec_handler_fn = message_handler_req_exec_cfg_reload_config,
+ },
+ { /* 4 */
+ .exec_handler_fn = message_handler_req_exec_cfg_reconfig_crypto,
+ }
+};
+
+/*
+ * Exports the interface for the service
+ */
+struct corosync_service_engine cfg_service_engine = {
+ .name = "corosync configuration service",
+ .id = CFG_SERVICE,
+ .priority = 1,
+ .private_data_size = sizeof(struct cfg_info),
+ .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED,
+ .allow_inquorate = CS_LIB_ALLOW_INQUORATE,
+ .lib_init_fn = cfg_lib_init_fn,
+ .lib_exit_fn = cfg_lib_exit_fn,
+ .lib_engine = cfg_lib_engine,
+ .lib_engine_count = sizeof (cfg_lib_engine) / sizeof (struct corosync_lib_handler),
+ .exec_init_fn = cfg_exec_init_fn,
+ .exec_engine = cfg_exec_engine,
+ .exec_engine_count = sizeof (cfg_exec_engine) / sizeof (struct corosync_exec_handler),
+ .confchg_fn = cfg_confchg_fn
+};
+
+struct corosync_service_engine *cfg_get_service_engine_ver0 (void)
+{
+ return (&cfg_service_engine);
+}
+
+struct req_exec_cfg_ringreenable {
+ struct qb_ipc_request_header header __attribute__((aligned(8)));
+ mar_message_source_t source __attribute__((aligned(8)));
+};
+
+struct req_exec_cfg_reload_config {
+ struct qb_ipc_request_header header __attribute__((aligned(8)));
+ mar_message_source_t source __attribute__((aligned(8)));
+};
+
+struct req_exec_cfg_crypto_reconfig {
+ struct qb_ipc_request_header header __attribute__((aligned(8)));
+ mar_uint32_t phase __attribute__((aligned(8)));
+};
+
+struct req_exec_cfg_killnode {
+ struct qb_ipc_request_header header __attribute__((aligned(8)));
+ mar_uint32_t nodeid __attribute__((aligned(8)));
+ mar_name_t reason __attribute__((aligned(8)));
+};
+
+struct req_exec_cfg_shutdown {
+ struct qb_ipc_request_header header __attribute__((aligned(8)));
+};
+
+/* IMPL */
+
+static char *cfg_exec_init_fn (
+ struct corosync_api_v1 *corosync_api_v1)
+{
+ api = corosync_api_v1;
+
+ qb_list_init(&trackers_list);
+ return (NULL);
+}
+
+static void cfg_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)
+{
+}
+
+/*
+ * Tell other nodes we are shutting down
+ */
+static int send_shutdown(void)
+{
+ struct req_exec_cfg_shutdown req_exec_cfg_shutdown;
+ struct iovec iovec;
+
+ ENTER();
+ req_exec_cfg_shutdown.header.size =
+ sizeof (struct req_exec_cfg_shutdown);
+ req_exec_cfg_shutdown.header.id = SERVICE_ID_MAKE (CFG_SERVICE,
+ MESSAGE_REQ_EXEC_CFG_SHUTDOWN);
+
+ iovec.iov_base = (char *)&req_exec_cfg_shutdown;
+ iovec.iov_len = sizeof (struct req_exec_cfg_shutdown);
+
+ assert (api->totem_mcast (&iovec, 1, TOTEM_SAFE) == 0);
+
+ LEAVE();
+ return 0;
+}
+
+static void send_test_shutdown(void *only_conn, void *exclude_conn, int status)
+{
+ struct res_lib_cfg_testshutdown res_lib_cfg_testshutdown;
+ struct qb_list_head *iter;
+
+ ENTER();
+ res_lib_cfg_testshutdown.header.size = sizeof(struct res_lib_cfg_testshutdown);
+ res_lib_cfg_testshutdown.header.id = MESSAGE_RES_CFG_TESTSHUTDOWN;
+ res_lib_cfg_testshutdown.header.error = status;
+ res_lib_cfg_testshutdown.flags = shutdown_flags;
+
+ if (only_conn) {
+ TRACE1("sending testshutdown to only %p", only_conn);
+ api->ipc_dispatch_send(only_conn, &res_lib_cfg_testshutdown,
+ sizeof(res_lib_cfg_testshutdown));
+ } else {
+ qb_list_for_each(iter, &trackers_list) {
+ struct cfg_info *ci = qb_list_entry(iter, struct cfg_info, list);
+
+ if (ci->conn != exclude_conn) {
+ TRACE1("sending testshutdown to %p", ci->tracker_conn);
+ api->ipc_dispatch_send(ci->tracker_conn, &res_lib_cfg_testshutdown,
+ sizeof(res_lib_cfg_testshutdown));
+ }
+ }
+ }
+ LEAVE();
+}
+
+static void check_shutdown_status(void)
+{
+ ENTER();
+
+ /*
+ * Shutdown client might have gone away
+ */
+ if (!shutdown_con) {
+ LEAVE();
+ return;
+ }
+
+ /*
+ * All replies safely gathered in ?
+ */
+ if (shutdown_yes + shutdown_no >= shutdown_expected) {
+ struct res_lib_cfg_tryshutdown res_lib_cfg_tryshutdown;
+
+ api->timer_delete(shutdown_timer);
+
+ if (shutdown_yes >= shutdown_expected ||
+ shutdown_flags == CFG_SHUTDOWN_FLAG_REGARDLESS) {
+ TRACE1("shutdown confirmed");
+
+ res_lib_cfg_tryshutdown.header.size = sizeof(struct res_lib_cfg_tryshutdown);
+ res_lib_cfg_tryshutdown.header.id = MESSAGE_RES_CFG_TRYSHUTDOWN;
+ res_lib_cfg_tryshutdown.header.error = CS_OK;
+
+ /*
+ * Tell originator that shutdown was confirmed
+ */
+ api->ipc_response_send(shutdown_con->conn, &res_lib_cfg_tryshutdown,
+ sizeof(res_lib_cfg_tryshutdown));
+ shutdown_con = NULL;
+
+ /*
+ * Tell other nodes we are going down
+ */
+ send_shutdown();
+
+ }
+ else {
+
+ TRACE1("shutdown cancelled");
+ res_lib_cfg_tryshutdown.header.size = sizeof(struct res_lib_cfg_tryshutdown);
+ res_lib_cfg_tryshutdown.header.id = MESSAGE_RES_CFG_TRYSHUTDOWN;
+ res_lib_cfg_tryshutdown.header.error = CS_ERR_BUSY;
+
+ /*
+ * Tell originator that shutdown was cancelled
+ */
+ api->ipc_response_send(shutdown_con->conn, &res_lib_cfg_tryshutdown,
+ sizeof(res_lib_cfg_tryshutdown));
+ shutdown_con = NULL;
+ }
+
+ log_printf(LOGSYS_LEVEL_DEBUG, "shutdown decision is: (yes count: %d, no count: %d) flags=%x",
+ shutdown_yes, shutdown_no, shutdown_flags);
+ }
+ LEAVE();
+}
+
+
+/*
+ * Not all nodes responded to the shutdown (in time)
+ */
+static void shutdown_timer_fn(void *arg)
+{
+ ENTER();
+
+ /*
+ * Mark undecideds as "NO"
+ */
+ shutdown_no = shutdown_expected;
+ check_shutdown_status();
+
+ send_test_shutdown(NULL, NULL, CS_ERR_TIMEOUT);
+ LEAVE();
+}
+
+static void remove_ci_from_shutdown(struct cfg_info *ci)
+{
+ ENTER();
+
+ /*
+ * If the controlling shutdown process has quit, then cancel the
+ * shutdown session
+ */
+ if (ci == shutdown_con) {
+ shutdown_con = NULL;
+ api->timer_delete(shutdown_timer);
+ }
+
+ if (!qb_list_empty(&ci->list)) {
+ qb_list_del(&ci->list);
+ qb_list_init(&ci->list);
+
+ /*
+ * Remove our option
+ */
+ if (shutdown_con) {
+ if (ci->shutdown_reply == SHUTDOWN_REPLY_YES)
+ shutdown_yes--;
+ if (ci->shutdown_reply == SHUTDOWN_REPLY_NO)
+ shutdown_no--;
+ }
+
+ /*
+ * If we are leaving, then that's an implicit YES to shutdown
+ */
+ ci->shutdown_reply = SHUTDOWN_REPLY_YES;
+ shutdown_yes++;
+
+ check_shutdown_status();
+ }
+ LEAVE();
+}
+
+
+int cfg_lib_exit_fn (void *conn)
+{
+ struct cfg_info *ci = (struct cfg_info *)api->ipc_private_data_get (conn);
+
+ ENTER();
+ remove_ci_from_shutdown(ci);
+ LEAVE();
+ return (0);
+}
+
+static int cfg_lib_init_fn (void *conn)
+{
+ struct cfg_info *ci = (struct cfg_info *)api->ipc_private_data_get (conn);
+
+ ENTER();
+ qb_list_init(&ci->list);
+ LEAVE();
+
+ return (0);
+}
+
+/*
+ * Executive message handlers
+ */
+static void message_handler_req_exec_cfg_ringreenable (
+ const void *message,
+ unsigned int nodeid)
+{
+ ENTER();
+
+ LEAVE();
+}
+
+static void exec_cfg_killnode_endian_convert (void *msg)
+{
+ struct req_exec_cfg_killnode *req_exec_cfg_killnode =
+ (struct req_exec_cfg_killnode *)msg;
+ ENTER();
+
+ swab_mar_name_t(&req_exec_cfg_killnode->reason);
+ LEAVE();
+}
+
+
+static void message_handler_req_exec_cfg_killnode (
+ const void *message,
+ unsigned int nodeid)
+{
+ const struct req_exec_cfg_killnode *req_exec_cfg_killnode = message;
+ cs_name_t reason;
+
+ ENTER();
+ log_printf(LOGSYS_LEVEL_DEBUG, "request to kill node " CS_PRI_NODE_ID " (us=" CS_PRI_NODE_ID ")",
+ req_exec_cfg_killnode->nodeid, api->totem_nodeid_get());
+ if (req_exec_cfg_killnode->nodeid == api->totem_nodeid_get()) {
+ marshall_from_mar_name_t(&reason, &req_exec_cfg_killnode->reason);
+ log_printf(LOGSYS_LEVEL_NOTICE, "Killed by node " CS_PRI_NODE_ID " : %s",
+ nodeid, reason.value);
+ corosync_fatal_error(COROSYNC_FATAL_ERROR_EXIT);
+ }
+ LEAVE();
+}
+
+/*
+ * Self shutdown
+ */
+static void message_handler_req_exec_cfg_shutdown (
+ const void *message,
+ unsigned int nodeid)
+{
+ ENTER();
+
+ log_printf(LOGSYS_LEVEL_NOTICE, "Node " CS_PRI_NODE_ID " was shut down by sysadmin", nodeid);
+ if (nodeid == api->totem_nodeid_get()) {
+ api->shutdown_request();
+ }
+ LEAVE();
+}
+
+/* strcmp replacement that can handle NULLs */
+static int nullcheck_strcmp(const char* left, const char *right)
+{
+ if (!left && right)
+ return -1;
+ if (left && !right)
+ return 1;
+
+ if (!left && !right)
+ return 0;
+
+ return strcmp(left, right);
+}
+
+/*
+ * If a key has changed value in the new file, then warn the user and remove it from the temp_map
+ */
+static void delete_and_notify_if_changed(icmap_map_t temp_map, const char *key_name)
+{
+ if (!(icmap_key_value_eq(temp_map, key_name, icmap_get_global_map(), key_name))) {
+ if (icmap_delete_r(temp_map, key_name) == CS_OK) {
+ log_printf(LOGSYS_LEVEL_NOTICE, "Modified entry '%s' in corosync.conf cannot be changed at run-time", key_name);
+ }
+ }
+}
+/*
+ * Remove any keys from the new config file that in the new corosync.conf but that
+ * cannot be changed at run time. A log message will be issued for each
+ * entry that the user wants to change but they cannot.
+ *
+ * Add more here as needed.
+ */
+static void remove_ro_entries(icmap_map_t temp_map)
+{
+#ifndef HAVE_KNET_CRYPTO_RECONF
+ delete_and_notify_if_changed(temp_map, "totem.secauth");
+ delete_and_notify_if_changed(temp_map, "totem.crypto_hash");
+ delete_and_notify_if_changed(temp_map, "totem.crypto_cipher");
+ delete_and_notify_if_changed(temp_map, "totem.keyfile");
+ delete_and_notify_if_changed(temp_map, "totem.key");
+#endif
+ delete_and_notify_if_changed(temp_map, "totem.version");
+ delete_and_notify_if_changed(temp_map, "totem.threads");
+ delete_and_notify_if_changed(temp_map, "totem.ip_version");
+ delete_and_notify_if_changed(temp_map, "totem.rrp_mode");
+ delete_and_notify_if_changed(temp_map, "totem.netmtu");
+ delete_and_notify_if_changed(temp_map, "totem.interface.ringnumber");
+ delete_and_notify_if_changed(temp_map, "totem.interface.bindnetaddr");
+ delete_and_notify_if_changed(temp_map, "totem.interface.mcastaddr");
+ delete_and_notify_if_changed(temp_map, "totem.interface.broadcast");
+ delete_and_notify_if_changed(temp_map, "totem.interface.mcastport");
+ delete_and_notify_if_changed(temp_map, "totem.interface.ttl");
+ delete_and_notify_if_changed(temp_map, "totem.transport");
+ delete_and_notify_if_changed(temp_map, "totem.cluster_name");
+ delete_and_notify_if_changed(temp_map, "quorum.provider");
+ delete_and_notify_if_changed(temp_map, "system.move_to_root_cgroup");
+ delete_and_notify_if_changed(temp_map, "system.allow_knet_handle_fallback");
+ delete_and_notify_if_changed(temp_map, "system.sched_rr");
+ delete_and_notify_if_changed(temp_map, "system.priority");
+ delete_and_notify_if_changed(temp_map, "system.qb_ipc_type");
+ delete_and_notify_if_changed(temp_map, "system.state_dir");
+}
+
+/*
+ * Remove entries that exist in the global map, but not in the temp_map, this will
+ * cause delete notifications to be sent to any listeners.
+ *
+ * NOTE: This routine depends entirely on the keys returned by the iterators
+ * being in alpha-sorted order.
+ */
+static void remove_deleted_entries(icmap_map_t temp_map, const char *prefix)
+{
+ icmap_iter_t old_iter;
+ icmap_iter_t new_iter;
+ const char *old_key, *new_key;
+ int ret;
+
+ old_iter = icmap_iter_init(prefix);
+ new_iter = icmap_iter_init_r(temp_map, prefix);
+
+ old_key = icmap_iter_next(old_iter, NULL, NULL);
+ new_key = icmap_iter_next(new_iter, NULL, NULL);
+
+ while (old_key || new_key) {
+ ret = nullcheck_strcmp(old_key, new_key);
+ if ((ret < 0 && old_key) || !new_key) {
+ /*
+ * new_key is greater, a line (or more) has been deleted
+ * Continue until old is >= new
+ */
+ do {
+ /* Remove it from icmap & send notifications */
+ icmap_delete(old_key);
+
+ old_key = icmap_iter_next(old_iter, NULL, NULL);
+ ret = nullcheck_strcmp(old_key, new_key);
+ } while (ret < 0 && old_key);
+ }
+ else if ((ret > 0 && new_key) || !old_key) {
+ /*
+ * old_key is greater, a line (or more) has been added
+ * Continue until new is >= old
+ *
+ * we don't need to do anything special with this like tell
+ * icmap. That will happen when we copy the values over
+ */
+ do {
+ new_key = icmap_iter_next(new_iter, NULL, NULL);
+ ret = nullcheck_strcmp(old_key, new_key);
+ } while (ret > 0 && new_key);
+ }
+ if (ret == 0) {
+ new_key = icmap_iter_next(new_iter, NULL, NULL);
+ old_key = icmap_iter_next(old_iter, NULL, NULL);
+ }
+ }
+ icmap_iter_finalize(new_iter);
+ icmap_iter_finalize(old_iter);
+}
+
+/*
+ * Reload configuration file
+ */
+static void message_handler_req_exec_cfg_reload_config (
+ const void *message,
+ unsigned int nodeid)
+{
+ const struct req_exec_cfg_reload_config *req_exec_cfg_reload_config = message;
+ struct res_lib_cfg_reload_config res_lib_cfg_reload_config;
+ struct totem_config new_config;
+ icmap_map_t temp_map;
+ const char *error_string;
+ int res = CS_OK;
+
+ ENTER();
+
+ log_printf(LOGSYS_LEVEL_NOTICE, "Config reload requested by node " CS_PRI_NODE_ID, nodeid);
+
+ icmap_set_uint8("config.totemconfig_reload_in_progress", 1);
+
+ /* Make sure there is no rubbish in this that might be checked, even on error */
+ memset(&new_config, 0, sizeof(new_config));
+ /*
+ * Set up a new hashtable as a staging area.
+ */
+ if ((res = icmap_init_r(&temp_map)) != CS_OK) {
+ log_printf(LOGSYS_LEVEL_ERROR, "Unable to create temporary icmap. config file reload cancelled\n");
+ goto reload_fini_nomap;
+ }
+
+ /*
+ * Load new config into the temporary map
+ */
+ res = coroparse_configparse(temp_map, &error_string);
+ if (res == -1) {
+ log_printf (LOGSYS_LEVEL_ERROR, "Unable to reload config file: %s", error_string);
+ res = CS_ERR_INVALID_PARAM;
+ goto reload_fini_nofree;
+ }
+
+ /* Signal start of the reload process */
+ icmap_set_uint8("config.reload_in_progress", 1);
+
+ /* Detect deleted entries and remove them from the main icmap hashtable */
+ remove_deleted_entries(temp_map, "logging.");
+ remove_deleted_entries(temp_map, "totem.");
+ remove_deleted_entries(temp_map, "nodelist.");
+ remove_deleted_entries(temp_map, "quorum.");
+ remove_deleted_entries(temp_map, "uidgid.config.");
+ remove_deleted_entries(temp_map, "nozzle.");
+
+ /* Remove entries that cannot be changed */
+ remove_ro_entries(temp_map);
+
+ /* Take a copy of the current setup so we can check what has changed */
+ memset(&new_config, 0, sizeof(new_config));
+ new_config.orig_interfaces = malloc (sizeof (struct totem_interface) * INTERFACE_MAX);
+ assert(new_config.orig_interfaces != NULL);
+
+ totempg_get_config(&new_config);
+ new_config.crypto_changed = 0;
+
+ new_config.interfaces = malloc (sizeof (struct totem_interface) * INTERFACE_MAX);
+ assert(new_config.interfaces != NULL);
+ memset(new_config.interfaces, 0, sizeof (struct totem_interface) * INTERFACE_MAX);
+
+ /* For UDP[U] the configuration on link0 is static (apart from the nodelist) and only read at
+ startup. So preserve it here */
+ if ( (new_config.transport_number == TOTEM_TRANSPORT_UDP) ||
+ (new_config.transport_number == TOTEM_TRANSPORT_UDPU)) {
+ memcpy(&new_config.interfaces[0], &new_config.orig_interfaces[0],
+ sizeof(struct totem_interface));
+ }
+
+ /* Calculate new node and interface definitions */
+ if (totemconfig_configure_new_params(&new_config, temp_map, &error_string) == -1) {
+ log_printf (LOGSYS_LEVEL_ERROR, "Cannot configure new interface definitions: %s\n", error_string);
+ res = CS_ERR_INVALID_PARAM;
+ goto reload_fini;
+ }
+
+ /* Read from temp_map into new_config */
+ totem_volatile_config_read(&new_config, temp_map, NULL);
+
+ /* Get updated crypto parameters. Will set a flag in new_config if things have changed */
+ if (totem_reread_crypto_config(&new_config, temp_map, &error_string) == -1) {
+ log_printf (LOGSYS_LEVEL_ERROR, "Crypto configuration is not valid: %s\n", error_string);
+ res = CS_ERR_INVALID_PARAM;
+ goto reload_fini;
+ }
+
+ /* Validate dynamic parameters */
+ if (totem_volatile_config_validate(&new_config, temp_map, &error_string) == -1) {
+ log_printf (LOGSYS_LEVEL_ERROR, "Configuration is not valid: %s\n", error_string);
+ res = CS_ERR_INVALID_PARAM;
+ goto reload_fini;
+ }
+
+ /* Save this here so we can get at it for the later phases of crypto change */
+ if (new_config.crypto_changed) {
+#ifndef HAVE_KNET_CRYPTO_RECONF
+ new_config.crypto_changed = 0;
+ log_printf (LOGSYS_LEVEL_ERROR, "Crypto reconfiguration is not supported by the linked version of knet\n");
+ res = CS_ERR_INVALID_PARAM;
+ goto reload_fini;
+#endif
+ }
+
+ /*
+ * Copy new keys into live config.
+ */
+ if ( (res = icmap_copy_map(icmap_get_global_map(), temp_map)) != CS_OK) {
+ log_printf (LOGSYS_LEVEL_ERROR, "Error making new config live. cmap database may be inconsistent\n");
+ /* Return res from icmap */
+ goto reload_fini;
+ }
+
+ /* Copy into live system */
+ totempg_put_config(&new_config);
+ totemconfig_commit_new_params(&new_config, temp_map);
+ free(new_config.interfaces);
+
+reload_fini:
+ /* All done - let clients know */
+ icmap_set_int32("config.reload_status", res);
+ icmap_set_uint8("config.totemconfig_reload_in_progress", 0);
+ icmap_set_uint8("config.reload_in_progress", 0);
+
+ /* Finished with the temporary storage */
+ free(new_config.orig_interfaces);
+
+reload_fini_nofree:
+ icmap_fini_r(temp_map);
+
+reload_fini_nomap:
+
+ /* If crypto was changed, now it's loaded on all nodes we can enable it.
+ * Each node sends its own PHASE message so we're not relying on the leader
+ * node to survive the transition
+ */
+ if (new_config.crypto_changed) {
+ struct req_exec_cfg_crypto_reconfig req_exec_cfg_crypto_reconfig;
+ struct iovec iovec;
+
+ req_exec_cfg_crypto_reconfig.header.size =
+ sizeof (struct req_exec_cfg_crypto_reconfig);
+ req_exec_cfg_crypto_reconfig.header.id = SERVICE_ID_MAKE (CFG_SERVICE,
+ MESSAGE_REQ_EXEC_CFG_CRYPTO_RECONFIG);
+ req_exec_cfg_crypto_reconfig.phase = CRYPTO_RECONFIG_PHASE_ACTIVATE;
+
+ iovec.iov_base = (char *)&req_exec_cfg_crypto_reconfig;
+ iovec.iov_len = sizeof (struct req_exec_cfg_crypto_reconfig);
+
+ assert (api->totem_mcast (&iovec, 1, TOTEM_SAFE) == 0);
+ }
+
+ /* All done, return result to the caller if it was on this system */
+ if (nodeid == api->totem_nodeid_get()) {
+ res_lib_cfg_reload_config.header.size = sizeof(res_lib_cfg_reload_config);
+ res_lib_cfg_reload_config.header.id = MESSAGE_RES_CFG_RELOAD_CONFIG;
+ res_lib_cfg_reload_config.header.error = res;
+ api->ipc_response_send(req_exec_cfg_reload_config->source.conn,
+ &res_lib_cfg_reload_config,
+ sizeof(res_lib_cfg_reload_config));
+ api->ipc_refcnt_dec(req_exec_cfg_reload_config->source.conn);;
+ }
+
+ LEAVE();
+}
+
+/* Handle the phases of crypto reload
+ * The first time we are called is after the new crypto config has been loaded
+ * but not activated.
+ *
+ * 1 - activate the new crypto configuration
+ * 2 - clear out the old configuration
+ */
+static void message_handler_req_exec_cfg_reconfig_crypto (
+ const void *message,
+ unsigned int nodeid)
+{
+ const struct req_exec_cfg_crypto_reconfig *req_exec_cfg_crypto_reconfig = message;
+
+ /* Got our own reconfig message */
+ if (nodeid == api->totem_nodeid_get()) {
+ log_printf (LOGSYS_LEVEL_DEBUG, "Crypto reconfiguration phase %d", req_exec_cfg_crypto_reconfig->phase);
+
+ /* Do the deed */
+ totempg_crypto_reconfigure_phase(req_exec_cfg_crypto_reconfig->phase);
+
+ /* Move to the next phase if not finished */
+ if (req_exec_cfg_crypto_reconfig->phase < CRYPTO_RECONFIG_PHASE_CLEANUP) {
+ struct req_exec_cfg_crypto_reconfig req_exec_cfg_crypto_reconfig2;
+ struct iovec iovec;
+
+ req_exec_cfg_crypto_reconfig2.header.size =
+ sizeof (struct req_exec_cfg_crypto_reconfig);
+ req_exec_cfg_crypto_reconfig2.header.id = SERVICE_ID_MAKE (CFG_SERVICE,
+ MESSAGE_REQ_EXEC_CFG_CRYPTO_RECONFIG);
+ req_exec_cfg_crypto_reconfig2.phase = CRYPTO_RECONFIG_PHASE_CLEANUP;
+
+ iovec.iov_base = (char *)&req_exec_cfg_crypto_reconfig2;
+ iovec.iov_len = sizeof (struct req_exec_cfg_crypto_reconfig);
+
+ assert (api->totem_mcast (&iovec, 1, TOTEM_SAFE) == 0);
+ }
+ }
+}
+
+
+/*
+ * Library Interface Implementation
+ */
+static void message_handler_req_lib_cfg_ringstatusget (
+ void *conn,
+ const void *msg)
+{
+ struct res_lib_cfg_ringstatusget res_lib_cfg_ringstatusget;
+ struct totem_ip_address interfaces[INTERFACE_MAX];
+ unsigned int iface_count;
+ char **status;
+ const char *totem_ip_string;
+ char ifname[CFG_INTERFACE_NAME_MAX_LEN];
+ unsigned int iface_ids[INTERFACE_MAX];
+ unsigned int i;
+ cs_error_t res = CS_OK;
+
+ ENTER();
+
+ res_lib_cfg_ringstatusget.header.id = MESSAGE_RES_CFG_RINGSTATUSGET;
+ res_lib_cfg_ringstatusget.header.size = sizeof (struct res_lib_cfg_ringstatusget);
+
+ api->totem_ifaces_get (
+ api->totem_nodeid_get(),
+ iface_ids,
+ interfaces,
+ INTERFACE_MAX,
+ &status,
+ &iface_count);
+
+ assert(iface_count <= CFG_MAX_INTERFACES);
+
+ res_lib_cfg_ringstatusget.interface_count = iface_count;
+
+ for (i = 0; i < iface_count; i++) {
+ totem_ip_string
+ = (const char *)api->totem_ip_print (&interfaces[i]);
+
+ if (!totem_ip_string) {
+ totem_ip_string="";
+ }
+
+ /* Allow for i/f number at the start */
+ if (strlen(totem_ip_string) >= CFG_INTERFACE_NAME_MAX_LEN-3) {
+ log_printf(LOGSYS_LEVEL_ERROR, "String representation of interface %u is too long", i);
+ res = CS_ERR_NAME_TOO_LONG;
+ goto send_response;
+ }
+ snprintf(ifname, sizeof(ifname), "%d %s", iface_ids[i], totem_ip_string);
+
+ if (strlen(status[i]) >= CFG_INTERFACE_STATUS_MAX_LEN) {
+ log_printf(LOGSYS_LEVEL_ERROR, "Status string for interface %u is too long", i);
+ res = CS_ERR_NAME_TOO_LONG;
+ goto send_response;
+ }
+
+ strcpy ((char *)&res_lib_cfg_ringstatusget.interface_status[i],
+ status[i]);
+ strcpy ((char *)&res_lib_cfg_ringstatusget.interface_name[i],
+ ifname);
+ }
+
+send_response:
+ res_lib_cfg_ringstatusget.header.error = res;
+ api->ipc_response_send (
+ conn,
+ &res_lib_cfg_ringstatusget,
+ sizeof (struct res_lib_cfg_ringstatusget));
+
+ LEAVE();
+}
+
+
+static void message_handler_req_lib_cfg_nodestatusget (
+ void *conn,
+ const void *msg)
+{
+ struct res_lib_cfg_nodestatusget_version res_lib_cfg_nodestatusget_version;
+ struct res_lib_cfg_nodestatusget_v1 res_lib_cfg_nodestatusget_v1;
+ void *res_lib_cfg_nodestatusget_ptr = NULL;
+ size_t res_lib_cfg_nodestatusget_size;
+ struct req_lib_cfg_nodestatusget *req_lib_cfg_nodestatusget = (struct req_lib_cfg_nodestatusget *)msg;
+ struct totem_node_status node_status;
+ int i;
+
+ ENTER();
+
+ memset(&node_status, 0, sizeof(node_status));
+ if (totempg_nodestatus_get(req_lib_cfg_nodestatusget->nodeid, &node_status) != 0) {
+ res_lib_cfg_nodestatusget_ptr = &res_lib_cfg_nodestatusget_version;
+ res_lib_cfg_nodestatusget_size = sizeof(res_lib_cfg_nodestatusget_version);
+
+ res_lib_cfg_nodestatusget_version.header.error = CS_ERR_FAILED_OPERATION;
+ res_lib_cfg_nodestatusget_version.header.id = MESSAGE_RES_CFG_NODESTATUSGET;
+ res_lib_cfg_nodestatusget_version.header.size = res_lib_cfg_nodestatusget_size;
+
+ goto ipc_response_send;
+ }
+
+ /* Currently only one structure version supported */
+ switch (req_lib_cfg_nodestatusget->version) {
+ case CFG_NODE_STATUS_V1:
+ res_lib_cfg_nodestatusget_ptr = &res_lib_cfg_nodestatusget_v1;
+ res_lib_cfg_nodestatusget_size = sizeof(res_lib_cfg_nodestatusget_v1);
+
+ res_lib_cfg_nodestatusget_v1.header.error = CS_OK;
+ res_lib_cfg_nodestatusget_v1.header.id = MESSAGE_RES_CFG_NODESTATUSGET;
+ res_lib_cfg_nodestatusget_v1.header.size = res_lib_cfg_nodestatusget_size;
+
+ res_lib_cfg_nodestatusget_v1.node_status.version = CFG_NODE_STATUS_V1;
+ res_lib_cfg_nodestatusget_v1.node_status.nodeid = req_lib_cfg_nodestatusget->nodeid;
+ res_lib_cfg_nodestatusget_v1.node_status.reachable = node_status.reachable;
+ res_lib_cfg_nodestatusget_v1.node_status.remote = node_status.remote;
+ res_lib_cfg_nodestatusget_v1.node_status.external = node_status.external;
+ res_lib_cfg_nodestatusget_v1.node_status.onwire_min = node_status.onwire_min;
+ res_lib_cfg_nodestatusget_v1.node_status.onwire_max = node_status.onwire_max;
+ res_lib_cfg_nodestatusget_v1.node_status.onwire_ver = node_status.onwire_ver;
+
+ for (i=0; i < KNET_MAX_LINK; i++) {
+ res_lib_cfg_nodestatusget_v1.node_status.link_status[i].enabled = node_status.link_status[i].enabled;
+ res_lib_cfg_nodestatusget_v1.node_status.link_status[i].connected = node_status.link_status[i].connected;
+ res_lib_cfg_nodestatusget_v1.node_status.link_status[i].dynconnected = node_status.link_status[i].dynconnected;
+ res_lib_cfg_nodestatusget_v1.node_status.link_status[i].mtu = node_status.link_status[i].mtu;
+ memcpy(res_lib_cfg_nodestatusget_v1.node_status.link_status[i].src_ipaddr,
+ node_status.link_status[i].src_ipaddr, CFG_MAX_HOST_LEN);
+ memcpy(res_lib_cfg_nodestatusget_v1.node_status.link_status[i].dst_ipaddr,
+ node_status.link_status[i].dst_ipaddr, CFG_MAX_HOST_LEN);
+ }
+ break;
+ default:
+ /*
+ * Unsupported version requested
+ */
+ res_lib_cfg_nodestatusget_ptr = &res_lib_cfg_nodestatusget_version;
+ res_lib_cfg_nodestatusget_size = sizeof(res_lib_cfg_nodestatusget_version);
+
+ res_lib_cfg_nodestatusget_version.header.error = CS_ERR_NOT_SUPPORTED;
+ res_lib_cfg_nodestatusget_version.header.id = MESSAGE_RES_CFG_NODESTATUSGET;
+ res_lib_cfg_nodestatusget_version.header.size = res_lib_cfg_nodestatusget_size;
+ break;
+ }
+
+ipc_response_send:
+ api->ipc_response_send (
+ conn,
+ res_lib_cfg_nodestatusget_ptr,
+ res_lib_cfg_nodestatusget_size);
+
+ LEAVE();
+}
+
+static void message_handler_req_lib_cfg_trackstart (
+ void *conn,
+ const void *msg)
+{
+ struct cfg_info *ci = (struct cfg_info *)api->ipc_private_data_get (conn);
+ struct res_lib_cfg_trackstart res_lib_cfg_trackstart;
+
+ ENTER();
+
+ /*
+ * We only do shutdown tracking at the moment
+ */
+ if (qb_list_empty(&ci->list)) {
+ qb_list_add(&ci->list, &trackers_list);
+ ci->tracker_conn = conn;
+
+ if (shutdown_con) {
+ /*
+ * Shutdown already in progress, ask the newcomer's opinion
+ */
+ ci->shutdown_reply = SHUTDOWN_REPLY_UNKNOWN;
+ shutdown_expected++;
+ send_test_shutdown(conn, NULL, CS_OK);
+ }
+ }
+
+ res_lib_cfg_trackstart.header.size = sizeof(struct res_lib_cfg_trackstart);
+ res_lib_cfg_trackstart.header.id = MESSAGE_RES_CFG_STATETRACKSTART;
+ res_lib_cfg_trackstart.header.error = CS_OK;
+
+ api->ipc_response_send(conn, &res_lib_cfg_trackstart,
+ sizeof(res_lib_cfg_trackstart));
+
+ LEAVE();
+}
+
+static void message_handler_req_lib_cfg_trackstop (
+ void *conn,
+ const void *msg)
+{
+ struct cfg_info *ci = (struct cfg_info *)api->ipc_private_data_get (conn);
+ struct res_lib_cfg_trackstop res_lib_cfg_trackstop;
+
+ ENTER();
+ remove_ci_from_shutdown(ci);
+
+ res_lib_cfg_trackstop.header.size = sizeof(struct res_lib_cfg_trackstop);
+ res_lib_cfg_trackstop.header.id = MESSAGE_RES_CFG_STATETRACKSTOP;
+ res_lib_cfg_trackstop.header.error = CS_OK;
+
+ api->ipc_response_send(conn, &res_lib_cfg_trackstop,
+ sizeof(res_lib_cfg_trackstop));
+ LEAVE();
+}
+
+static void message_handler_req_lib_cfg_ringreenable (
+ void *conn,
+ const void *msg)
+{
+ struct res_lib_cfg_ringreenable res_lib_cfg_ringreenable;
+ ENTER();
+
+ res_lib_cfg_ringreenable.header.id = MESSAGE_RES_CFG_RINGREENABLE;
+ res_lib_cfg_ringreenable.header.size = sizeof (struct res_lib_cfg_ringreenable);
+ res_lib_cfg_ringreenable.header.error = CS_ERR_NOT_SUPPORTED;
+ api->ipc_response_send (
+ conn, &res_lib_cfg_ringreenable,
+ sizeof (struct res_lib_cfg_ringreenable));
+
+ LEAVE();
+}
+
+static void message_handler_req_lib_cfg_killnode (
+ void *conn,
+ const void *msg)
+{
+ const struct req_lib_cfg_killnode *req_lib_cfg_killnode = msg;
+ struct res_lib_cfg_killnode res_lib_cfg_killnode;
+ struct req_exec_cfg_killnode req_exec_cfg_killnode;
+ struct iovec iovec;
+ char key_name[ICMAP_KEYNAME_MAXLEN];
+ char tmp_key[ICMAP_KEYNAME_MAXLEN + 1];
+ icmap_map_t map;
+ icmap_iter_t iter;
+ const char *iter_key;
+ uint32_t nodeid;
+ char *status_str = NULL;
+ int match_nodeid_flag = 0;
+ cs_error_t error = CS_OK;
+
+ ENTER();
+
+ map = icmap_get_global_map();
+ iter = icmap_iter_init_r(map, "runtime.members.");
+ while ((iter_key = icmap_iter_next(iter, NULL, NULL)) != NULL) {
+ if (sscanf(iter_key, "runtime.members.%u.%s", &nodeid, key_name) != 2) {
+ continue;
+ }
+ if (strcmp(key_name, "status") != 0) {
+ continue;
+ }
+ if (nodeid != req_lib_cfg_killnode->nodeid) {
+ continue;
+ }
+ match_nodeid_flag = 1;
+ snprintf(tmp_key, ICMAP_KEYNAME_MAXLEN, "runtime.members.%u.status", nodeid);
+ if (icmap_get_string_r(map, tmp_key, &status_str) != CS_OK) {
+ error = CS_ERR_LIBRARY;
+ goto send_response;
+ }
+ if (strcmp(status_str, "joined") != 0) {
+ error = CS_ERR_NOT_EXIST;
+ goto send_response;
+ }
+ break;
+ }
+
+ if (!match_nodeid_flag) {
+ error = CS_ERR_NOT_EXIST;
+ goto send_response;
+ }
+
+ req_exec_cfg_killnode.header.size =
+ sizeof (struct req_exec_cfg_killnode);
+ req_exec_cfg_killnode.header.id = SERVICE_ID_MAKE (CFG_SERVICE,
+ MESSAGE_REQ_EXEC_CFG_KILLNODE);
+ req_exec_cfg_killnode.nodeid = req_lib_cfg_killnode->nodeid;
+ marshall_to_mar_name_t(&req_exec_cfg_killnode.reason, &req_lib_cfg_killnode->reason);
+
+ iovec.iov_base = (char *)&req_exec_cfg_killnode;
+ iovec.iov_len = sizeof (struct req_exec_cfg_killnode);
+
+ (void)api->totem_mcast (&iovec, 1, TOTEM_SAFE);
+
+send_response:
+ res_lib_cfg_killnode.header.size = sizeof(struct res_lib_cfg_killnode);
+ res_lib_cfg_killnode.header.id = MESSAGE_RES_CFG_KILLNODE;
+ res_lib_cfg_killnode.header.error = error;
+
+ api->ipc_response_send(conn, &res_lib_cfg_killnode,
+ sizeof(res_lib_cfg_killnode));
+
+ free(status_str);
+ icmap_iter_finalize(iter);
+ LEAVE();
+}
+
+
+static void message_handler_req_lib_cfg_tryshutdown (
+ void *conn,
+ const void *msg)
+{
+ struct cfg_info *ci = (struct cfg_info *)api->ipc_private_data_get (conn);
+ const struct req_lib_cfg_tryshutdown *req_lib_cfg_tryshutdown = msg;
+ struct qb_list_head *iter;
+
+ ENTER();
+
+ if (req_lib_cfg_tryshutdown->flags == CFG_SHUTDOWN_FLAG_IMMEDIATE) {
+ struct res_lib_cfg_tryshutdown res_lib_cfg_tryshutdown;
+
+ /*
+ * Tell other nodes
+ */
+ send_shutdown();
+
+ res_lib_cfg_tryshutdown.header.size = sizeof(struct res_lib_cfg_tryshutdown);
+ res_lib_cfg_tryshutdown.header.id = MESSAGE_RES_CFG_TRYSHUTDOWN;
+ res_lib_cfg_tryshutdown.header.error = CS_OK;
+ api->ipc_response_send(conn, &res_lib_cfg_tryshutdown,
+ sizeof(res_lib_cfg_tryshutdown));
+
+ LEAVE();
+ return;
+ }
+
+ /*
+ * Shutdown in progress, return an error
+ */
+ if (shutdown_con) {
+ struct res_lib_cfg_tryshutdown res_lib_cfg_tryshutdown;
+
+ res_lib_cfg_tryshutdown.header.size = sizeof(struct res_lib_cfg_tryshutdown);
+ res_lib_cfg_tryshutdown.header.id = MESSAGE_RES_CFG_TRYSHUTDOWN;
+ res_lib_cfg_tryshutdown.header.error = CS_ERR_EXIST;
+
+ api->ipc_response_send(conn, &res_lib_cfg_tryshutdown,
+ sizeof(res_lib_cfg_tryshutdown));
+
+
+ LEAVE();
+
+ return;
+ }
+
+ ci->conn = conn;
+ shutdown_con = (struct cfg_info *)api->ipc_private_data_get (conn);
+ shutdown_flags = req_lib_cfg_tryshutdown->flags;
+ shutdown_yes = 0;
+ shutdown_no = 0;
+
+ /*
+ * Count the number of listeners
+ */
+ shutdown_expected = 0;
+
+ qb_list_for_each(iter, &trackers_list) {
+ struct cfg_info *testci = qb_list_entry(iter, struct cfg_info, list);
+ /*
+ * It is assumed that we will allow shutdown
+ */
+ if (testci != ci) {
+ testci->shutdown_reply = SHUTDOWN_REPLY_UNKNOWN;
+ shutdown_expected++;
+ }
+ }
+
+ /*
+ * If no-one is listening for events then we can just go down now
+ */
+ if (shutdown_expected == 0) {
+ struct res_lib_cfg_tryshutdown res_lib_cfg_tryshutdown;
+
+ res_lib_cfg_tryshutdown.header.size = sizeof(struct res_lib_cfg_tryshutdown);
+ res_lib_cfg_tryshutdown.header.id = MESSAGE_RES_CFG_TRYSHUTDOWN;
+ res_lib_cfg_tryshutdown.header.error = CS_OK;
+
+ /*
+ * Tell originator that shutdown was confirmed
+ */
+ api->ipc_response_send(conn, &res_lib_cfg_tryshutdown,
+ sizeof(res_lib_cfg_tryshutdown));
+
+ send_shutdown();
+ LEAVE();
+ return;
+ }
+ else {
+ unsigned int shutdown_timeout = DEFAULT_SHUTDOWN_TIMEOUT;
+
+ /*
+ * Look for a shutdown timeout in configuration map
+ */
+ icmap_get_uint32("cfg.shutdown_timeout", &shutdown_timeout);
+
+ /*
+ * Start the timer. If we don't get a full set of replies before this goes
+ * off we'll cancel the shutdown
+ */
+ api->timer_add_duration((unsigned long long)shutdown_timeout*QB_TIME_NS_IN_MSEC, NULL,
+ shutdown_timer_fn, &shutdown_timer);
+
+ /*
+ * Tell the users we would like to shut down
+ */
+ send_test_shutdown(NULL, conn, CS_OK);
+ }
+
+ /*
+ * We don't sent a reply to the caller here.
+ * We send it when we know if we can shut down or not
+ */
+
+ LEAVE();
+}
+
+static void message_handler_req_lib_cfg_replytoshutdown (
+ void *conn,
+ const void *msg)
+{
+ struct cfg_info *ci = (struct cfg_info *)api->ipc_private_data_get (conn);
+ const struct req_lib_cfg_replytoshutdown *req_lib_cfg_replytoshutdown = msg;
+ struct res_lib_cfg_replytoshutdown res_lib_cfg_replytoshutdown;
+ int status = CS_OK;
+
+ ENTER();
+ if (!shutdown_con) {
+ status = CS_ERR_ACCESS;
+ goto exit_fn;
+ }
+
+ if (req_lib_cfg_replytoshutdown->response) {
+ shutdown_yes++;
+ ci->shutdown_reply = SHUTDOWN_REPLY_YES;
+ }
+ else {
+ shutdown_no++;
+ ci->shutdown_reply = SHUTDOWN_REPLY_NO;
+ }
+ check_shutdown_status();
+
+exit_fn:
+ res_lib_cfg_replytoshutdown.header.error = status;
+ res_lib_cfg_replytoshutdown.header.id = MESSAGE_RES_CFG_REPLYTOSHUTDOWN;
+ res_lib_cfg_replytoshutdown.header.size = sizeof(res_lib_cfg_replytoshutdown);
+
+ api->ipc_response_send(conn, &res_lib_cfg_replytoshutdown,
+ sizeof(res_lib_cfg_replytoshutdown));
+
+ LEAVE();
+}
+
+static void message_handler_req_lib_cfg_get_node_addrs (void *conn,
+ const void *msg)
+{
+ struct totem_ip_address node_ifs[INTERFACE_MAX];
+ unsigned int iface_ids[INTERFACE_MAX];
+ char buf[PIPE_BUF];
+ char **status;
+ unsigned int num_interfaces = 0;
+ struct sockaddr_storage *ss;
+ int ret = CS_OK;
+ int i;
+ int live_addrs = 0;
+ const struct req_lib_cfg_get_node_addrs *req_lib_cfg_get_node_addrs = msg;
+ struct res_lib_cfg_get_node_addrs *res_lib_cfg_get_node_addrs = (struct res_lib_cfg_get_node_addrs *)buf;
+ unsigned int nodeid = req_lib_cfg_get_node_addrs->nodeid;
+ char *addr_buf;
+
+ if (nodeid == 0)
+ nodeid = api->totem_nodeid_get();
+
+ if (api->totem_ifaces_get(nodeid, iface_ids, node_ifs, INTERFACE_MAX, &status, &num_interfaces)) {
+ ret = CS_ERR_EXIST;
+ num_interfaces = 0;
+ }
+
+ res_lib_cfg_get_node_addrs->header.size = sizeof(struct res_lib_cfg_get_node_addrs) + (num_interfaces * TOTEMIP_ADDRLEN);
+ res_lib_cfg_get_node_addrs->header.id = MESSAGE_RES_CFG_GET_NODE_ADDRS;
+ res_lib_cfg_get_node_addrs->header.error = ret;
+ if (num_interfaces) {
+ res_lib_cfg_get_node_addrs->family = node_ifs[0].family;
+ for (i = 0, addr_buf = (char *)res_lib_cfg_get_node_addrs->addrs;
+ i < num_interfaces; i++) {
+ ss = (struct sockaddr_storage *)&node_ifs[i].addr;
+ if (ss->ss_family) {
+ memcpy(addr_buf, node_ifs[i].addr, TOTEMIP_ADDRLEN);
+ live_addrs++;
+ addr_buf += TOTEMIP_ADDRLEN;
+ }
+ }
+ res_lib_cfg_get_node_addrs->num_addrs = live_addrs;
+ } else {
+ res_lib_cfg_get_node_addrs->header.error = CS_ERR_NOT_EXIST;
+ }
+ api->ipc_response_send(conn, res_lib_cfg_get_node_addrs, res_lib_cfg_get_node_addrs->header.size);
+}
+
+static void message_handler_req_lib_cfg_local_get (void *conn, const void *msg)
+{
+ struct res_lib_cfg_local_get res_lib_cfg_local_get;
+
+ res_lib_cfg_local_get.header.size = sizeof(res_lib_cfg_local_get);
+ res_lib_cfg_local_get.header.id = MESSAGE_RES_CFG_LOCAL_GET;
+ res_lib_cfg_local_get.header.error = CS_OK;
+ res_lib_cfg_local_get.local_nodeid = api->totem_nodeid_get ();
+
+ api->ipc_response_send(conn, &res_lib_cfg_local_get,
+ sizeof(res_lib_cfg_local_get));
+}
+
+static void message_handler_req_lib_cfg_reload_config (void *conn, const void *msg)
+{
+ struct req_exec_cfg_reload_config req_exec_cfg_reload_config;
+ struct iovec iovec;
+
+ ENTER();
+
+ req_exec_cfg_reload_config.header.size =
+ sizeof (struct req_exec_cfg_reload_config);
+ req_exec_cfg_reload_config.header.id = SERVICE_ID_MAKE (CFG_SERVICE,
+ MESSAGE_REQ_EXEC_CFG_RELOAD_CONFIG);
+ api->ipc_source_set (&req_exec_cfg_reload_config.source, conn);
+ api->ipc_refcnt_inc(conn);
+
+ iovec.iov_base = (char *)&req_exec_cfg_reload_config;
+ iovec.iov_len = sizeof (struct req_exec_cfg_reload_config);
+
+ assert (api->totem_mcast (&iovec, 1, TOTEM_SAFE) == 0);
+
+ LEAVE();
+}
+
+static void message_handler_req_lib_cfg_reopen_log_files (void *conn, const void *msg)
+{
+ struct res_lib_cfg_reopen_log_files res_lib_cfg_reopen_log_files;
+ cs_error_t res;
+
+ ENTER();
+
+ log_printf(LOGSYS_LEVEL_DEBUG, "Reopening logging files\n");
+
+ res = logsys_reopen_log_files();
+
+ res_lib_cfg_reopen_log_files.header.size = sizeof(res_lib_cfg_reopen_log_files);
+ res_lib_cfg_reopen_log_files.header.id = MESSAGE_RES_CFG_REOPEN_LOG_FILES;
+ res_lib_cfg_reopen_log_files.header.error = res;
+ api->ipc_response_send(conn,
+ &res_lib_cfg_reopen_log_files,
+ sizeof(res_lib_cfg_reopen_log_files));
+
+ LEAVE();
+}
diff --git a/exec/cmap.c b/exec/cmap.c
new file mode 100644
index 0000000..1d1b69e
--- /dev/null
+++ b/exec/cmap.c
@@ -0,0 +1,1155 @@
+/*
+ * Copyright (c) 2011-2017 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Author: Jan Friesse (jfriesse@redhat.com)
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of the Red Hat, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <poll.h>
+#include <assert.h>
+
+#include <qb/qbloop.h>
+#include <qb/qblist.h>
+#include <qb/qbipcs.h>
+#include <qb/qbipc_common.h>
+
+#include <corosync/corotypes.h>
+#include <corosync/corodefs.h>
+#include <corosync/mar_gen.h>
+#include <corosync/ipc_cmap.h>
+#include <corosync/logsys.h>
+#include <corosync/coroapi.h>
+#include <corosync/icmap.h>
+
+#include "service.h"
+#include "ipcs_stats.h"
+#include "stats.h"
+
+LOGSYS_DECLARE_SUBSYS ("CMAP");
+
+#define MAX_REQ_EXEC_CMAP_MCAST_ITEMS 32
+#define ICMAP_VALUETYPE_NOT_EXIST 0
+
+struct cmap_map {
+ cs_error_t (*map_get)(const char *key_name,
+ void *value,
+ size_t *value_len,
+ icmap_value_types_t *type);
+
+ cs_error_t (*map_set)(const char *key_name,
+ const void *value,
+ size_t value_len,
+ icmap_value_types_t type);
+
+ cs_error_t (*map_adjust_int)(const char *key_name, int32_t step);
+
+ cs_error_t (*map_delete)(const char *key_name);
+
+ int (*map_is_key_ro)(const char *key_name);
+
+ icmap_iter_t (*map_iter_init)(const char *prefix);
+ const char * (*map_iter_next)(icmap_iter_t iter, size_t *value_len, icmap_value_types_t *type);
+ void (*map_iter_finalize)(icmap_iter_t iter);
+
+ cs_error_t (*map_track_add)(const char *key_name,
+ int32_t track_type,
+ icmap_notify_fn_t notify_fn,
+ void *user_data,
+ icmap_track_t *icmap_track);
+
+ cs_error_t (*map_track_delete)(icmap_track_t icmap_track);
+ void * (*map_track_get_user_data)(icmap_track_t icmap_track);
+};
+
+struct cmap_map icmap_map = {
+ .map_get = icmap_get,
+ .map_set = icmap_set,
+ .map_adjust_int = icmap_adjust_int,
+ .map_delete = icmap_delete,
+ .map_is_key_ro = icmap_is_key_ro,
+ .map_iter_init = icmap_iter_init,
+ .map_iter_next = icmap_iter_next,
+ .map_iter_finalize = icmap_iter_finalize,
+ .map_track_add = icmap_track_add,
+ .map_track_delete = icmap_track_delete,
+ .map_track_get_user_data = icmap_track_get_user_data,
+};
+
+struct cmap_map stats_map = {
+ .map_get = stats_map_get,
+ .map_set = stats_map_set,
+ .map_adjust_int = stats_map_adjust_int,
+ .map_delete = stats_map_delete,
+ .map_is_key_ro = stats_map_is_key_ro,
+ .map_iter_init = stats_map_iter_init,
+ .map_iter_next = stats_map_iter_next,
+ .map_iter_finalize = stats_map_iter_finalize,
+ .map_track_add = stats_map_track_add,
+ .map_track_delete = stats_map_track_delete,
+ .map_track_get_user_data = stats_map_track_get_user_data,
+};
+
+struct cmap_conn_info {
+ struct hdb_handle_database iter_db;
+ struct hdb_handle_database track_db;
+ struct cmap_map map_fns;
+};
+
+typedef uint64_t cmap_iter_handle_t;
+typedef uint64_t cmap_track_handle_t;
+
+struct cmap_track_user_data {
+ void *conn;
+ cmap_track_handle_t track_handle;
+ uint64_t track_inst_handle;
+};
+
+enum cmap_message_req_types {
+ MESSAGE_REQ_EXEC_CMAP_MCAST = 0,
+};
+
+enum cmap_mcast_reason {
+ CMAP_MCAST_REASON_SYNC = 0,
+ CMAP_MCAST_REASON_NEW_CONFIG_VERSION = 1,
+};
+
+static struct corosync_api_v1 *api;
+
+static char *cmap_exec_init_fn (struct corosync_api_v1 *corosync_api);
+static int cmap_exec_exit_fn(void);
+
+static int cmap_lib_init_fn (void *conn);
+static int cmap_lib_exit_fn (void *conn);
+
+static void message_handler_req_lib_cmap_set(void *conn, const void *message);
+static void message_handler_req_lib_cmap_delete(void *conn, const void *message);
+static void message_handler_req_lib_cmap_get(void *conn, const void *message);
+static void message_handler_req_lib_cmap_adjust_int(void *conn, const void *message);
+static void message_handler_req_lib_cmap_iter_init(void *conn, const void *message);
+static void message_handler_req_lib_cmap_iter_next(void *conn, const void *message);
+static void message_handler_req_lib_cmap_iter_finalize(void *conn, const void *message);
+static void message_handler_req_lib_cmap_track_add(void *conn, const void *message);
+static void message_handler_req_lib_cmap_track_delete(void *conn, const void *message);
+static void message_handler_req_lib_cmap_set_current_map(void *conn, const void *message);
+
+static void cmap_notify_fn(int32_t event,
+ const char *key_name,
+ struct icmap_notify_value new_val,
+ struct icmap_notify_value old_val,
+ void *user_data);
+
+static void message_handler_req_exec_cmap_mcast(
+ const void *message,
+ unsigned int nodeid);
+
+static void exec_cmap_mcast_endian_convert(void *message);
+
+/*
+ * Reson is subtype of message. argc is number of items in argv array. Argv is array
+ * of strings (key names) which will be send to wire. There can be maximum
+ * MAX_REQ_EXEC_CMAP_MCAST_ITEMS items (for more items, CS_ERR_TOO_MANY_GROUPS
+ * error is returned). If key is not found, item has type ICMAP_VALUETYPE_NOT_EXIST
+ * and length zero.
+ */
+static cs_error_t cmap_mcast_send(enum cmap_mcast_reason reason, int argc, char *argv[]);
+
+static void cmap_sync_init (
+ const unsigned int *trans_list,
+ size_t trans_list_entries,
+ const unsigned int *member_list,
+ size_t member_list_entries,
+ const struct memb_ring_id *ring_id);
+
+static int cmap_sync_process (void);
+static void cmap_sync_activate (void);
+static void cmap_sync_abort (void);
+
+static void cmap_config_version_track_cb(
+ int32_t event,
+ const char *key_name,
+ struct icmap_notify_value new_value,
+ struct icmap_notify_value old_value,
+ void *user_data);
+
+/*
+ * Library Handler Definition
+ */
+static struct corosync_lib_handler cmap_lib_engine[] =
+{
+ { /* 0 */
+ .lib_handler_fn = message_handler_req_lib_cmap_set,
+ .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED
+ },
+ { /* 1 */
+ .lib_handler_fn = message_handler_req_lib_cmap_delete,
+ .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED
+ },
+ { /* 2 */
+ .lib_handler_fn = message_handler_req_lib_cmap_get,
+ .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED
+ },
+ { /* 3 */
+ .lib_handler_fn = message_handler_req_lib_cmap_adjust_int,
+ .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED
+ },
+ { /* 4 */
+ .lib_handler_fn = message_handler_req_lib_cmap_iter_init,
+ .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED
+ },
+ { /* 5 */
+ .lib_handler_fn = message_handler_req_lib_cmap_iter_next,
+ .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED
+ },
+ { /* 6 */
+ .lib_handler_fn = message_handler_req_lib_cmap_iter_finalize,
+ .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED
+ },
+ { /* 7 */
+ .lib_handler_fn = message_handler_req_lib_cmap_track_add,
+ .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED
+ },
+ { /* 8 */
+ .lib_handler_fn = message_handler_req_lib_cmap_track_delete,
+ .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED
+ },
+ { /* 9 */
+ .lib_handler_fn = message_handler_req_lib_cmap_set_current_map,
+ .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED
+ },
+};
+
+static struct corosync_exec_handler cmap_exec_engine[] =
+{
+ { /* 0 - MESSAGE_REQ_EXEC_CMAP_MCAST */
+ .exec_handler_fn = message_handler_req_exec_cmap_mcast,
+ .exec_endian_convert_fn = exec_cmap_mcast_endian_convert
+ },
+};
+
+struct corosync_service_engine cmap_service_engine = {
+ .name = "corosync configuration map access",
+ .id = CMAP_SERVICE,
+ .priority = 1,
+ .private_data_size = sizeof(struct cmap_conn_info),
+ .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED,
+ .allow_inquorate = CS_LIB_ALLOW_INQUORATE,
+ .lib_init_fn = cmap_lib_init_fn,
+ .lib_exit_fn = cmap_lib_exit_fn,
+ .lib_engine = cmap_lib_engine,
+ .lib_engine_count = sizeof (cmap_lib_engine) / sizeof (struct corosync_lib_handler),
+ .exec_init_fn = cmap_exec_init_fn,
+ .exec_exit_fn = cmap_exec_exit_fn,
+ .exec_engine = cmap_exec_engine,
+ .exec_engine_count = sizeof (cmap_exec_engine) / sizeof (struct corosync_exec_handler),
+ .sync_init = cmap_sync_init,
+ .sync_process = cmap_sync_process,
+ .sync_activate = cmap_sync_activate,
+ .sync_abort = cmap_sync_abort
+};
+
+struct corosync_service_engine *cmap_get_service_engine_ver0 (void)
+{
+ return (&cmap_service_engine);
+}
+
+struct req_exec_cmap_mcast_item {
+ mar_name_t key_name __attribute__((aligned(8)));
+ mar_uint8_t value_type __attribute__((aligned(8)));
+ mar_size_t value_len __attribute__((aligned(8)));
+ uint8_t value[] __attribute__((aligned(8)));
+};
+
+struct req_exec_cmap_mcast {
+ struct qb_ipc_request_header header __attribute__((aligned(8)));
+ mar_uint8_t reason __attribute__((aligned(8)));
+ mar_uint8_t no_items __attribute__((aligned(8)));
+ mar_uint8_t reserved1 __attribute__((aligned(8)));
+ mar_uint8_t reserver2 __attribute__((aligned(8)));
+ /*
+ * Following are array of req_exec_cmap_mcast_item alligned to 8 bytes
+ */
+};
+
+static size_t cmap_sync_trans_list_entries = 0;
+static size_t cmap_sync_member_list_entries = 0;
+static uint64_t cmap_highest_config_version_received = 0;
+static uint64_t cmap_my_config_version = 0;
+static int cmap_first_sync = 1;
+static icmap_track_t cmap_config_version_track;
+
+static void cmap_config_version_track_cb(
+ int32_t event,
+ const char *key_name,
+ struct icmap_notify_value new_value,
+ struct icmap_notify_value old_value,
+ void *user_data)
+{
+ const char *key = "totem.config_version";
+ cs_error_t ret;
+
+ ENTER();
+
+ if (icmap_get_uint64("totem.config_version", &cmap_my_config_version) != CS_OK) {
+ cmap_my_config_version = 0;
+ }
+
+
+ ret = cmap_mcast_send(CMAP_MCAST_REASON_NEW_CONFIG_VERSION, 1, (char **)&key);
+ if (ret != CS_OK) {
+ log_printf(LOGSYS_LEVEL_ERROR, "Can't inform other nodes about new config version");
+ }
+
+ LEAVE();
+}
+
+static int cmap_exec_exit_fn(void)
+{
+
+ if (icmap_track_delete(cmap_config_version_track) != CS_OK) {
+ log_printf(LOGSYS_LEVEL_ERROR, "Can't delete config_version icmap tracker");
+ }
+
+ return 0;
+}
+
+static char *cmap_exec_init_fn (
+ struct corosync_api_v1 *corosync_api)
+{
+ cs_error_t ret;
+
+ api = corosync_api;
+
+ ret = icmap_track_add("totem.config_version",
+ ICMAP_TRACK_ADD | ICMAP_TRACK_DELETE | ICMAP_TRACK_MODIFY,
+ cmap_config_version_track_cb,
+ NULL,
+ &cmap_config_version_track);
+
+ if (ret != CS_OK) {
+ return ((char *)"Can't add config_version icmap tracker");
+ }
+
+ return (NULL);
+}
+
+static int cmap_lib_init_fn (void *conn)
+{
+ struct cmap_conn_info *conn_info = (struct cmap_conn_info *)api->ipc_private_data_get (conn);
+
+ log_printf(LOGSYS_LEVEL_DEBUG, "lib_init_fn: conn=%p", conn);
+
+ api->ipc_refcnt_inc(conn);
+
+ memset(conn_info, 0, sizeof(*conn_info));
+ conn_info->map_fns = icmap_map;
+ hdb_create(&conn_info->iter_db);
+ hdb_create(&conn_info->track_db);
+
+ return (0);
+}
+
+static int cmap_lib_exit_fn (void *conn)
+{
+ struct cmap_conn_info *conn_info = (struct cmap_conn_info *)api->ipc_private_data_get (conn);
+ hdb_handle_t iter_handle = 0;
+ icmap_iter_t *iter;
+ hdb_handle_t track_handle = 0;
+ icmap_track_t *track;
+
+ log_printf(LOGSYS_LEVEL_DEBUG, "exit_fn for conn=%p", conn);
+
+ hdb_iterator_reset(&conn_info->iter_db);
+ while (hdb_iterator_next(&conn_info->iter_db,
+ (void*)&iter, &iter_handle) == 0) {
+
+ conn_info->map_fns.map_iter_finalize(*iter);
+
+ (void)hdb_handle_put (&conn_info->iter_db, iter_handle);
+ }
+
+ hdb_destroy(&conn_info->iter_db);
+
+ hdb_iterator_reset(&conn_info->track_db);
+ while (hdb_iterator_next(&conn_info->track_db,
+ (void*)&track, &track_handle) == 0) {
+
+ free(conn_info->map_fns.map_track_get_user_data(*track));
+
+ conn_info->map_fns.map_track_delete(*track);
+
+ (void)hdb_handle_put (&conn_info->track_db, track_handle);
+ }
+ hdb_destroy(&conn_info->track_db);
+
+ api->ipc_refcnt_dec(conn);
+
+ return (0);
+}
+
+static void cmap_sync_init (
+ const unsigned int *trans_list,
+ size_t trans_list_entries,
+ const unsigned int *member_list,
+ size_t member_list_entries,
+ const struct memb_ring_id *ring_id)
+{
+
+ cmap_sync_trans_list_entries = trans_list_entries;
+ cmap_sync_member_list_entries = member_list_entries;
+
+ if (icmap_get_uint64("totem.config_version", &cmap_my_config_version) != CS_OK) {
+ cmap_my_config_version = 0;
+ }
+
+ cmap_highest_config_version_received = cmap_my_config_version;
+}
+
+static int cmap_sync_process (void)
+{
+ const char *key = "totem.config_version";
+ cs_error_t ret;
+
+ ret = cmap_mcast_send(CMAP_MCAST_REASON_SYNC, 1, (char **)&key);
+
+ return (ret == CS_OK ? 0 : -1);
+}
+
+static void cmap_sync_activate (void)
+{
+
+ if (cmap_sync_trans_list_entries == 0) {
+ log_printf(LOGSYS_LEVEL_DEBUG, "Single node sync -> no action");
+
+ return ;
+ }
+
+ if (cmap_first_sync == 1) {
+ cmap_first_sync = 0;
+ } else {
+ log_printf(LOGSYS_LEVEL_DEBUG, "Not first sync -> no action");
+
+ return ;
+ }
+
+ if (cmap_my_config_version == 0) {
+ log_printf(LOGSYS_LEVEL_DEBUG, "My config version is 0 -> no action");
+
+ return ;
+ }
+
+ if (cmap_highest_config_version_received != cmap_my_config_version) {
+ log_printf(LOGSYS_LEVEL_ERROR,
+ "Received config version (%"PRIu64") is different than my config version (%"PRIu64")! Exiting",
+ cmap_highest_config_version_received, cmap_my_config_version);
+ api->shutdown_request();
+ return ;
+ }
+}
+
+static void cmap_sync_abort (void)
+{
+
+
+}
+
+static void message_handler_req_lib_cmap_set(void *conn, const void *message)
+{
+ const struct req_lib_cmap_set *req_lib_cmap_set = message;
+ struct cmap_conn_info *conn_info = (struct cmap_conn_info *)api->ipc_private_data_get (conn);
+ struct res_lib_cmap_set res_lib_cmap_set;
+ cs_error_t ret;
+
+ if (conn_info->map_fns.map_is_key_ro((char *)req_lib_cmap_set->key_name.value)) {
+ ret = CS_ERR_ACCESS;
+ } else {
+ ret = conn_info->map_fns.map_set((char *)req_lib_cmap_set->key_name.value, &req_lib_cmap_set->value,
+ req_lib_cmap_set->value_len, req_lib_cmap_set->type);
+ }
+
+ memset(&res_lib_cmap_set, 0, sizeof(res_lib_cmap_set));
+ res_lib_cmap_set.header.size = sizeof(res_lib_cmap_set);
+ res_lib_cmap_set.header.id = MESSAGE_RES_CMAP_SET;
+ res_lib_cmap_set.header.error = ret;
+
+ api->ipc_response_send(conn, &res_lib_cmap_set, sizeof(res_lib_cmap_set));
+}
+
+static void message_handler_req_lib_cmap_delete(void *conn, const void *message)
+{
+ const struct req_lib_cmap_set *req_lib_cmap_set = message;
+ struct cmap_conn_info *conn_info = (struct cmap_conn_info *)api->ipc_private_data_get (conn);
+ struct res_lib_cmap_delete res_lib_cmap_delete;
+ cs_error_t ret;
+
+ if (conn_info->map_fns.map_is_key_ro((char *)req_lib_cmap_set->key_name.value)) {
+ ret = CS_ERR_ACCESS;
+ } else {
+ ret = conn_info->map_fns.map_delete((char *)req_lib_cmap_set->key_name.value);
+ }
+
+ memset(&res_lib_cmap_delete, 0, sizeof(res_lib_cmap_delete));
+ res_lib_cmap_delete.header.size = sizeof(res_lib_cmap_delete);
+ res_lib_cmap_delete.header.id = MESSAGE_RES_CMAP_DELETE;
+ res_lib_cmap_delete.header.error = ret;
+
+ api->ipc_response_send(conn, &res_lib_cmap_delete, sizeof(res_lib_cmap_delete));
+}
+
+static void message_handler_req_lib_cmap_get(void *conn, const void *message)
+{
+ const struct req_lib_cmap_get *req_lib_cmap_get = message;
+ struct cmap_conn_info *conn_info = (struct cmap_conn_info *)api->ipc_private_data_get (conn);
+ struct res_lib_cmap_get *res_lib_cmap_get;
+ struct res_lib_cmap_get error_res_lib_cmap_get;
+ cs_error_t ret;
+ size_t value_len;
+ size_t res_lib_cmap_get_size;
+ icmap_value_types_t type;
+ void *value;
+
+ value_len = req_lib_cmap_get->value_len;
+
+ res_lib_cmap_get_size = sizeof(*res_lib_cmap_get) + value_len;
+ res_lib_cmap_get = malloc(res_lib_cmap_get_size);
+ if (res_lib_cmap_get == NULL) {
+ ret = CS_ERR_NO_MEMORY;
+ goto error_exit;
+ }
+
+ memset(res_lib_cmap_get, 0, res_lib_cmap_get_size);
+
+ if (value_len > 0) {
+ value = res_lib_cmap_get->value;
+ } else {
+ value = NULL;
+ }
+
+ ret = conn_info->map_fns.map_get((char *)req_lib_cmap_get->key_name.value,
+ value,
+ &value_len,
+ &type);
+
+ if (ret != CS_OK) {
+ free(res_lib_cmap_get);
+ goto error_exit;
+ }
+
+ res_lib_cmap_get->header.size = res_lib_cmap_get_size;
+ res_lib_cmap_get->header.id = MESSAGE_RES_CMAP_GET;
+ res_lib_cmap_get->header.error = ret;
+ res_lib_cmap_get->type = type;
+ res_lib_cmap_get->value_len = value_len;
+
+ api->ipc_response_send(conn, res_lib_cmap_get, res_lib_cmap_get_size);
+ free(res_lib_cmap_get);
+
+ return ;
+
+error_exit:
+ memset(&error_res_lib_cmap_get, 0, sizeof(error_res_lib_cmap_get));
+ error_res_lib_cmap_get.header.size = sizeof(error_res_lib_cmap_get);
+ error_res_lib_cmap_get.header.id = MESSAGE_RES_CMAP_GET;
+ error_res_lib_cmap_get.header.error = ret;
+
+ api->ipc_response_send(conn, &error_res_lib_cmap_get, sizeof(error_res_lib_cmap_get));
+}
+
+static void message_handler_req_lib_cmap_adjust_int(void *conn, const void *message)
+{
+ const struct req_lib_cmap_adjust_int *req_lib_cmap_adjust_int = message;
+ struct cmap_conn_info *conn_info = (struct cmap_conn_info *)api->ipc_private_data_get (conn);
+ struct res_lib_cmap_adjust_int res_lib_cmap_adjust_int;
+ cs_error_t ret;
+
+ if (conn_info->map_fns.map_is_key_ro((char *)req_lib_cmap_adjust_int->key_name.value)) {
+ ret = CS_ERR_ACCESS;
+ } else {
+ ret = conn_info->map_fns.map_adjust_int((char *)req_lib_cmap_adjust_int->key_name.value,
+ req_lib_cmap_adjust_int->step);
+
+ }
+
+ memset(&res_lib_cmap_adjust_int, 0, sizeof(res_lib_cmap_adjust_int));
+ res_lib_cmap_adjust_int.header.size = sizeof(res_lib_cmap_adjust_int);
+ res_lib_cmap_adjust_int.header.id = MESSAGE_RES_CMAP_ADJUST_INT;
+ res_lib_cmap_adjust_int.header.error = ret;
+
+ api->ipc_response_send(conn, &res_lib_cmap_adjust_int, sizeof(res_lib_cmap_adjust_int));
+}
+
+static void message_handler_req_lib_cmap_iter_init(void *conn, const void *message)
+{
+ const struct req_lib_cmap_iter_init *req_lib_cmap_iter_init = message;
+ struct res_lib_cmap_iter_init res_lib_cmap_iter_init;
+ cs_error_t ret;
+ icmap_iter_t iter;
+ icmap_iter_t *hdb_iter;
+ cmap_iter_handle_t handle = 0ULL;
+ const char *prefix;
+ struct cmap_conn_info *conn_info = (struct cmap_conn_info *)api->ipc_private_data_get (conn);
+
+ if (req_lib_cmap_iter_init->prefix.length > 0) {
+ prefix = (char *)req_lib_cmap_iter_init->prefix.value;
+ } else {
+ prefix = NULL;
+ }
+
+ iter = conn_info->map_fns.map_iter_init(prefix);
+ if (iter == NULL) {
+ ret = CS_ERR_NO_SECTIONS;
+ goto reply_send;
+ }
+
+ ret = hdb_error_to_cs(hdb_handle_create(&conn_info->iter_db, sizeof(iter), &handle));
+ if (ret != CS_OK) {
+ goto reply_send;
+ }
+
+ ret = hdb_error_to_cs(hdb_handle_get(&conn_info->iter_db, handle, (void *)&hdb_iter));
+ if (ret != CS_OK) {
+ goto reply_send;
+ }
+
+ *hdb_iter = iter;
+
+ (void)hdb_handle_put (&conn_info->iter_db, handle);
+
+reply_send:
+ memset(&res_lib_cmap_iter_init, 0, sizeof(res_lib_cmap_iter_init));
+ res_lib_cmap_iter_init.header.size = sizeof(res_lib_cmap_iter_init);
+ res_lib_cmap_iter_init.header.id = MESSAGE_RES_CMAP_ITER_INIT;
+ res_lib_cmap_iter_init.header.error = ret;
+ res_lib_cmap_iter_init.iter_handle = handle;
+
+ api->ipc_response_send(conn, &res_lib_cmap_iter_init, sizeof(res_lib_cmap_iter_init));
+}
+
+static void message_handler_req_lib_cmap_iter_next(void *conn, const void *message)
+{
+ const struct req_lib_cmap_iter_next *req_lib_cmap_iter_next = message;
+ struct res_lib_cmap_iter_next res_lib_cmap_iter_next;
+ cs_error_t ret;
+ icmap_iter_t *iter;
+ size_t value_len = 0;
+ icmap_value_types_t type = 0;
+ const char *res = NULL;
+ struct cmap_conn_info *conn_info = (struct cmap_conn_info *)api->ipc_private_data_get (conn);
+
+ ret = hdb_error_to_cs(hdb_handle_get(&conn_info->iter_db,
+ req_lib_cmap_iter_next->iter_handle, (void *)&iter));
+ if (ret != CS_OK) {
+ goto reply_send;
+ }
+
+ res = conn_info->map_fns.map_iter_next(*iter, &value_len, &type);
+ if (res == NULL) {
+ ret = CS_ERR_NO_SECTIONS;
+ }
+
+ (void)hdb_handle_put (&conn_info->iter_db, req_lib_cmap_iter_next->iter_handle);
+
+reply_send:
+ memset(&res_lib_cmap_iter_next, 0, sizeof(res_lib_cmap_iter_next));
+ res_lib_cmap_iter_next.header.size = sizeof(res_lib_cmap_iter_next);
+ res_lib_cmap_iter_next.header.id = MESSAGE_RES_CMAP_ITER_NEXT;
+ res_lib_cmap_iter_next.header.error = ret;
+
+ if (res != NULL) {
+ res_lib_cmap_iter_next.value_len = value_len;
+ res_lib_cmap_iter_next.type = type;
+
+ assert(strlen(res) <= sizeof(res_lib_cmap_iter_next.key_name.value));
+
+ memcpy(res_lib_cmap_iter_next.key_name.value, res, strlen(res));
+ res_lib_cmap_iter_next.key_name.length = strlen(res);
+ }
+
+ api->ipc_response_send(conn, &res_lib_cmap_iter_next, sizeof(res_lib_cmap_iter_next));
+}
+
+static void message_handler_req_lib_cmap_iter_finalize(void *conn, const void *message)
+{
+ const struct req_lib_cmap_iter_finalize *req_lib_cmap_iter_finalize = message;
+ struct res_lib_cmap_iter_finalize res_lib_cmap_iter_finalize;
+ cs_error_t ret;
+ icmap_iter_t *iter;
+ struct cmap_conn_info *conn_info = (struct cmap_conn_info *)api->ipc_private_data_get (conn);
+
+ ret = hdb_error_to_cs(hdb_handle_get(&conn_info->iter_db,
+ req_lib_cmap_iter_finalize->iter_handle, (void *)&iter));
+ if (ret != CS_OK) {
+ goto reply_send;
+ }
+
+ conn_info->map_fns.map_iter_finalize(*iter);
+
+ (void)hdb_handle_destroy(&conn_info->iter_db, req_lib_cmap_iter_finalize->iter_handle);
+
+ (void)hdb_handle_put (&conn_info->iter_db, req_lib_cmap_iter_finalize->iter_handle);
+
+reply_send:
+ memset(&res_lib_cmap_iter_finalize, 0, sizeof(res_lib_cmap_iter_finalize));
+ res_lib_cmap_iter_finalize.header.size = sizeof(res_lib_cmap_iter_finalize);
+ res_lib_cmap_iter_finalize.header.id = MESSAGE_RES_CMAP_ITER_FINALIZE;
+ res_lib_cmap_iter_finalize.header.error = ret;
+
+ api->ipc_response_send(conn, &res_lib_cmap_iter_finalize, sizeof(res_lib_cmap_iter_finalize));
+}
+
+static void cmap_notify_fn(int32_t event,
+ const char *key_name,
+ struct icmap_notify_value new_val,
+ struct icmap_notify_value old_val,
+ void *user_data)
+{
+ struct cmap_track_user_data *cmap_track_user_data = (struct cmap_track_user_data *)user_data;
+ struct res_lib_cmap_notify_callback res_lib_cmap_notify_callback;
+ struct iovec iov[3];
+
+ memset(&res_lib_cmap_notify_callback, 0, sizeof(res_lib_cmap_notify_callback));
+
+ res_lib_cmap_notify_callback.header.size = sizeof(res_lib_cmap_notify_callback) + new_val.len + old_val.len;
+ res_lib_cmap_notify_callback.header.id = MESSAGE_RES_CMAP_NOTIFY_CALLBACK;
+ res_lib_cmap_notify_callback.header.error = CS_OK;
+
+ res_lib_cmap_notify_callback.new_value_type = new_val.type;
+ res_lib_cmap_notify_callback.old_value_type = old_val.type;
+ res_lib_cmap_notify_callback.new_value_len = new_val.len;
+ res_lib_cmap_notify_callback.old_value_len = old_val.len;
+ res_lib_cmap_notify_callback.event = event;
+ res_lib_cmap_notify_callback.key_name.length = strlen(key_name);
+ res_lib_cmap_notify_callback.track_inst_handle = cmap_track_user_data->track_inst_handle;
+
+ assert(strlen(key_name) <= sizeof(res_lib_cmap_notify_callback.key_name.value));
+
+ memcpy(res_lib_cmap_notify_callback.key_name.value, key_name, strlen(key_name));
+
+ iov[0].iov_base = (char *)&res_lib_cmap_notify_callback;
+ iov[0].iov_len = sizeof(res_lib_cmap_notify_callback);
+ iov[1].iov_base = (char *)new_val.data;
+ iov[1].iov_len = new_val.len;
+ iov[2].iov_base = (char *)old_val.data;
+ iov[2].iov_len = old_val.len;
+
+ api->ipc_dispatch_iov_send(cmap_track_user_data->conn, iov, 3);
+}
+
+static void message_handler_req_lib_cmap_track_add(void *conn, const void *message)
+{
+ const struct req_lib_cmap_track_add *req_lib_cmap_track_add = message;
+ struct res_lib_cmap_track_add res_lib_cmap_track_add;
+ cs_error_t ret;
+ cmap_track_handle_t handle = 0;
+ icmap_track_t track = NULL;
+ icmap_track_t *hdb_track;
+ struct cmap_track_user_data *cmap_track_user_data;
+ const char *key_name;
+
+ struct cmap_conn_info *conn_info = (struct cmap_conn_info *)api->ipc_private_data_get (conn);
+
+ cmap_track_user_data = malloc(sizeof(*cmap_track_user_data));
+ if (cmap_track_user_data == NULL) {
+ ret = CS_ERR_NO_MEMORY;
+
+ goto reply_send;
+ }
+ memset(cmap_track_user_data, 0, sizeof(*cmap_track_user_data));
+
+ if (req_lib_cmap_track_add->key_name.length > 0) {
+ key_name = (char *)req_lib_cmap_track_add->key_name.value;
+ } else {
+ key_name = NULL;
+ }
+
+ ret = conn_info->map_fns.map_track_add(key_name,
+ req_lib_cmap_track_add->track_type,
+ cmap_notify_fn,
+ cmap_track_user_data,
+ &track);
+ if (ret != CS_OK) {
+ free(cmap_track_user_data);
+
+ goto reply_send;
+ }
+
+ ret = hdb_error_to_cs(hdb_handle_create(&conn_info->track_db, sizeof(track), &handle));
+ if (ret != CS_OK) {
+ free(cmap_track_user_data);
+
+ goto reply_send;
+ }
+
+ ret = hdb_error_to_cs(hdb_handle_get(&conn_info->track_db, handle, (void *)&hdb_track));
+ if (ret != CS_OK) {
+ free(cmap_track_user_data);
+
+ goto reply_send;
+ }
+
+ *hdb_track = track;
+ cmap_track_user_data->conn = conn;
+ cmap_track_user_data->track_handle = handle;
+ cmap_track_user_data->track_inst_handle = req_lib_cmap_track_add->track_inst_handle;
+
+ (void)hdb_handle_put (&conn_info->track_db, handle);
+
+reply_send:
+ memset(&res_lib_cmap_track_add, 0, sizeof(res_lib_cmap_track_add));
+ res_lib_cmap_track_add.header.size = sizeof(res_lib_cmap_track_add);
+ res_lib_cmap_track_add.header.id = MESSAGE_RES_CMAP_TRACK_ADD;
+ res_lib_cmap_track_add.header.error = ret;
+ res_lib_cmap_track_add.track_handle = handle;
+
+ api->ipc_response_send(conn, &res_lib_cmap_track_add, sizeof(res_lib_cmap_track_add));
+}
+
+static void message_handler_req_lib_cmap_track_delete(void *conn, const void *message)
+{
+ const struct req_lib_cmap_track_delete *req_lib_cmap_track_delete = message;
+ struct res_lib_cmap_track_delete res_lib_cmap_track_delete;
+ cs_error_t ret;
+ icmap_track_t *track;
+ struct cmap_conn_info *conn_info = (struct cmap_conn_info *)api->ipc_private_data_get (conn);
+ uint64_t track_inst_handle = 0;
+
+ ret = hdb_error_to_cs(hdb_handle_get(&conn_info->track_db,
+ req_lib_cmap_track_delete->track_handle, (void *)&track));
+ if (ret != CS_OK) {
+ goto reply_send;
+ }
+
+ track_inst_handle = ((struct cmap_track_user_data *)
+ conn_info->map_fns.map_track_get_user_data(*track))->track_inst_handle;
+
+ free(conn_info->map_fns.map_track_get_user_data(*track));
+
+ ret = conn_info->map_fns.map_track_delete(*track);
+
+ (void)hdb_handle_put (&conn_info->track_db, req_lib_cmap_track_delete->track_handle);
+ (void)hdb_handle_destroy(&conn_info->track_db, req_lib_cmap_track_delete->track_handle);
+
+reply_send:
+ memset(&res_lib_cmap_track_delete, 0, sizeof(res_lib_cmap_track_delete));
+ res_lib_cmap_track_delete.header.size = sizeof(res_lib_cmap_track_delete);
+ res_lib_cmap_track_delete.header.id = MESSAGE_RES_CMAP_TRACK_DELETE;
+ res_lib_cmap_track_delete.header.error = ret;
+ res_lib_cmap_track_delete.track_inst_handle = track_inst_handle;
+
+ api->ipc_response_send(conn, &res_lib_cmap_track_delete, sizeof(res_lib_cmap_track_delete));
+}
+
+
+static void message_handler_req_lib_cmap_set_current_map(void *conn, const void *message)
+{
+ const struct req_lib_cmap_set_current_map *req_lib_cmap_set_current_map = message;
+ struct qb_ipc_response_header res;
+ cs_error_t ret = CS_OK;
+ struct cmap_conn_info *conn_info = (struct cmap_conn_info *)api->ipc_private_data_get (conn);
+ int handles_open = 0;
+ hdb_handle_t iter_handle = 0;
+ icmap_iter_t *iter;
+ hdb_handle_t track_handle = 0;
+ icmap_track_t *track;
+
+ /* Cannot switch maps while there are tracks or iterators active */
+ hdb_iterator_reset(&conn_info->iter_db);
+ while (hdb_iterator_next(&conn_info->iter_db,
+ (void*)&iter, &iter_handle) == 0) {
+ handles_open++;
+ }
+
+ hdb_iterator_reset(&conn_info->track_db);
+ while (hdb_iterator_next(&conn_info->track_db,
+ (void*)&track, &track_handle) == 0) {
+ handles_open++;
+ }
+
+ if (handles_open) {
+ ret = CS_ERR_BUSY;
+ goto reply_send;
+ }
+
+ switch (req_lib_cmap_set_current_map->map) {
+ case CMAP_SETMAP_DEFAULT:
+ conn_info->map_fns = icmap_map;
+ break;
+ case CMAP_SETMAP_STATS:
+ conn_info->map_fns = stats_map;
+ break;
+ default:
+ ret = CS_ERR_NOT_EXIST;
+ break;
+ }
+
+reply_send:
+ res.size = sizeof(res);
+ res.id = MESSAGE_RES_CMAP_SET_CURRENT_MAP;
+ res.error = ret;
+
+ api->ipc_response_send(conn, &res, sizeof(res));
+}
+
+static cs_error_t cmap_mcast_send(enum cmap_mcast_reason reason, int argc, char *argv[])
+{
+ int i;
+ size_t value_len;
+ icmap_value_types_t value_type;
+ cs_error_t err;
+ size_t item_len;
+ size_t msg_len = 0;
+ struct req_exec_cmap_mcast req_exec_cmap_mcast;
+ struct req_exec_cmap_mcast_item *item = NULL;
+ struct iovec req_exec_cmap_iovec[MAX_REQ_EXEC_CMAP_MCAST_ITEMS + 1];
+
+ ENTER();
+
+ if (argc > MAX_REQ_EXEC_CMAP_MCAST_ITEMS) {
+ return (CS_ERR_TOO_MANY_GROUPS);
+ }
+
+ memset(req_exec_cmap_iovec, 0, sizeof(req_exec_cmap_iovec));
+
+ for (i = 0; i < argc; i++) {
+ err = icmap_get(argv[i], NULL, &value_len, &value_type);
+ if (err != CS_OK && err != CS_ERR_NOT_EXIST) {
+ goto free_mem;
+ }
+ if (err == CS_ERR_NOT_EXIST) {
+ value_type = ICMAP_VALUETYPE_NOT_EXIST;
+ value_len = 0;
+ }
+
+ item_len = MAR_ALIGN_UP(sizeof(*item) + value_len, 8);
+
+ item = malloc(item_len);
+ if (item == NULL) {
+ goto free_mem;
+ }
+ memset(item, 0, item_len);
+
+ item->value_type = value_type;
+ item->value_len = value_len;
+ item->key_name.length = strlen(argv[i]);
+
+ assert(strlen(argv[i]) < sizeof(item->key_name.value));
+
+ strcpy((char *)item->key_name.value, argv[i]);
+
+ if (value_type != ICMAP_VALUETYPE_NOT_EXIST) {
+ err = icmap_get(argv[i], item->value, &value_len, &value_type);
+ if (err != CS_OK) {
+ goto free_mem;
+ }
+ }
+
+ req_exec_cmap_iovec[i + 1].iov_base = item;
+ req_exec_cmap_iovec[i + 1].iov_len = item_len;
+ msg_len += item_len;
+
+ qb_log(LOG_TRACE, "Item %u - type %u, len %zu", i, item->value_type, item->value_len);
+
+ item = NULL;
+ }
+
+ memset(&req_exec_cmap_mcast, 0, sizeof(req_exec_cmap_mcast));
+ req_exec_cmap_mcast.header.size = sizeof(req_exec_cmap_mcast) + msg_len;
+ req_exec_cmap_mcast.reason = reason;
+ req_exec_cmap_mcast.no_items = argc;
+ req_exec_cmap_iovec[0].iov_base = &req_exec_cmap_mcast;
+ req_exec_cmap_iovec[0].iov_len = sizeof(req_exec_cmap_mcast);
+
+ qb_log(LOG_TRACE, "Sending %u items (%u iovec) for reason %u", argc, argc + 1, reason);
+ err = (api->totem_mcast(req_exec_cmap_iovec, argc + 1, TOTEM_AGREED) == 0 ? CS_OK : CS_ERR_MESSAGE_ERROR);
+
+free_mem:
+ for (i = 0; i < argc; i++) {
+ free(req_exec_cmap_iovec[i + 1].iov_base);
+ }
+
+ free(item);
+
+ LEAVE();
+ return (err);
+}
+
+static struct req_exec_cmap_mcast_item *cmap_mcast_item_find(
+ const void *message,
+ char *key)
+{
+ const struct req_exec_cmap_mcast *req_exec_cmap_mcast = message;
+ int i;
+ const char *p;
+ struct req_exec_cmap_mcast_item *item;
+ mar_uint16_t key_name_len;
+
+ p = (const char *)message + sizeof(*req_exec_cmap_mcast);
+
+ for (i = 0; i < req_exec_cmap_mcast->no_items; i++) {
+ item = (struct req_exec_cmap_mcast_item *)p;
+
+ key_name_len = item->key_name.length;
+ if (strlen(key) == key_name_len && strcmp((char *)item->key_name.value, key) == 0) {
+ return (item);
+ }
+
+ p += MAR_ALIGN_UP(sizeof(*item) + item->value_len, 8);
+ }
+
+ return (NULL);
+}
+
+static void message_handler_req_exec_cmap_mcast_reason_sync_nv(
+ enum cmap_mcast_reason reason,
+ const void *message,
+ unsigned int nodeid)
+{
+ char member_config_version[ICMAP_KEYNAME_MAXLEN];
+ uint64_t config_version = 0;
+ struct req_exec_cmap_mcast_item *item;
+ mar_size_t value_len;
+
+ ENTER();
+
+ item = cmap_mcast_item_find(message, (char *)"totem.config_version");
+ if (item != NULL) {
+ value_len = item->value_len;
+
+ if (item->value_type == ICMAP_VALUETYPE_NOT_EXIST) {
+ config_version = 0;
+ }
+
+ if (item->value_type == ICMAP_VALUETYPE_UINT64) {
+ memcpy(&config_version, item->value, value_len);
+ }
+ }
+
+ qb_log(LOG_TRACE, "Received config version %"PRIu64" from node " CS_PRI_NODE_ID, config_version, nodeid);
+
+ if (nodeid != api->totem_nodeid_get() &&
+ config_version > cmap_highest_config_version_received) {
+ cmap_highest_config_version_received = config_version;
+ }
+
+ snprintf(member_config_version, ICMAP_KEYNAME_MAXLEN,
+ "runtime.members.%u.config_version", nodeid);
+ icmap_set_uint64(member_config_version, config_version);
+
+ LEAVE();
+}
+
+static void message_handler_req_exec_cmap_mcast(
+ const void *message,
+ unsigned int nodeid)
+{
+ const struct req_exec_cmap_mcast *req_exec_cmap_mcast = message;
+
+ ENTER();
+
+ switch (req_exec_cmap_mcast->reason) {
+ case CMAP_MCAST_REASON_SYNC:
+ message_handler_req_exec_cmap_mcast_reason_sync_nv(req_exec_cmap_mcast->reason,
+ message, nodeid);
+
+ break;
+ case CMAP_MCAST_REASON_NEW_CONFIG_VERSION:
+ message_handler_req_exec_cmap_mcast_reason_sync_nv(req_exec_cmap_mcast->reason,
+ message, nodeid);
+
+ break;
+ default:
+ qb_log(LOG_TRACE, "Received mcast with unknown reason %u", req_exec_cmap_mcast->reason);
+ };
+
+ LEAVE();
+}
+
+static void exec_cmap_mcast_endian_convert(void *message)
+{
+ struct req_exec_cmap_mcast *req_exec_cmap_mcast = message;
+ const char *p;
+ int i;
+ struct req_exec_cmap_mcast_item *item;
+ uint16_t u16;
+ uint32_t u32;
+ uint64_t u64;
+ float flt;
+ double dbl;
+
+ swab_coroipc_request_header_t(&req_exec_cmap_mcast->header);
+
+ p = (const char *)message + sizeof(*req_exec_cmap_mcast);
+
+ for (i = 0; i < req_exec_cmap_mcast->no_items; i++) {
+ item = (struct req_exec_cmap_mcast_item *)p;
+
+ swab_mar_uint16_t(&item->key_name.length);
+ swab_mar_size_t(&item->value_len);
+
+ switch (item->value_type) {
+ case ICMAP_VALUETYPE_INT16:
+ case ICMAP_VALUETYPE_UINT16:
+ memcpy(&u16, item->value, sizeof(u16));
+ u16 = swab16(u16);
+ memcpy(item->value, &u16, sizeof(u16));
+ break;
+ case ICMAP_VALUETYPE_INT32:
+ case ICMAP_VALUETYPE_UINT32:
+ memcpy(&u32, item->value, sizeof(u32));
+ u32 = swab32(u32);
+ memcpy(item->value, &u32, sizeof(u32));
+ break;
+ case ICMAP_VALUETYPE_INT64:
+ case ICMAP_VALUETYPE_UINT64:
+ memcpy(&u64, item->value, sizeof(u64));
+ u64 = swab64(u64);
+ memcpy(item->value, &u64, sizeof(u64));
+ break;
+ case ICMAP_VALUETYPE_FLOAT:
+ memcpy(&flt, item->value, sizeof(flt));
+ swabflt(&flt);
+ memcpy(item->value, &flt, sizeof(flt));
+ break;
+ case ICMAP_VALUETYPE_DOUBLE:
+ memcpy(&dbl, item->value, sizeof(dbl));
+ swabdbl(&dbl);
+ memcpy(item->value, &dbl, sizeof(dbl));
+ break;
+ }
+
+ p += MAR_ALIGN_UP(sizeof(*item) + item->value_len, 8);
+ }
+}
diff --git a/exec/coroparse.c b/exec/coroparse.c
new file mode 100644
index 0000000..b614780
--- /dev/null
+++ b/exec/coroparse.c
@@ -0,0 +1,1697 @@
+/*
+ * Copyright (c) 2006-2022 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Author: Patrick Caulfield (pcaulfie@redhat.com)
+ * Jan Friesse (jfriesse@redhat.com)
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of the MontaVista Software, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <sys/uio.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/un.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+#include <dirent.h>
+#include <libgen.h>
+#include <limits.h>
+#include <stddef.h>
+#include <grp.h>
+#include <pwd.h>
+
+#include <qb/qblist.h>
+#include <qb/qbutil.h>
+#define LOGSYS_UTILS_ONLY 1
+#include <corosync/logsys.h>
+#include <corosync/icmap.h>
+
+#include "main.h"
+#include "util.h"
+
+enum parser_cb_type {
+ PARSER_CB_START,
+ PARSER_CB_END,
+ PARSER_CB_SECTION_START,
+ PARSER_CB_SECTION_END,
+ PARSER_CB_ITEM,
+};
+
+enum main_cp_cb_data_state {
+ MAIN_CP_CB_DATA_STATE_NORMAL,
+ MAIN_CP_CB_DATA_STATE_TOTEM,
+ MAIN_CP_CB_DATA_STATE_INTERFACE,
+ MAIN_CP_CB_DATA_STATE_LOGGER_SUBSYS,
+ MAIN_CP_CB_DATA_STATE_UIDGID,
+ MAIN_CP_CB_DATA_STATE_LOGGING_DAEMON,
+ MAIN_CP_CB_DATA_STATE_MEMBER,
+ MAIN_CP_CB_DATA_STATE_QUORUM,
+ MAIN_CP_CB_DATA_STATE_QDEVICE,
+ MAIN_CP_CB_DATA_STATE_NODELIST,
+ MAIN_CP_CB_DATA_STATE_NODELIST_NODE,
+ MAIN_CP_CB_DATA_STATE_PLOAD,
+ MAIN_CP_CB_DATA_STATE_SYSTEM,
+ MAIN_CP_CB_DATA_STATE_RESOURCES,
+ MAIN_CP_CB_DATA_STATE_RESOURCES_SYSTEM,
+ MAIN_CP_CB_DATA_STATE_RESOURCES_PROCESS,
+ MAIN_CP_CB_DATA_STATE_RESOURCES_SYSTEM_MEMUSED,
+ MAIN_CP_CB_DATA_STATE_RESOURCES_PROCESS_MEMUSED
+};
+
+typedef int (*parser_cb_f)(const char *path,
+ char *key,
+ char *value,
+ enum main_cp_cb_data_state *state,
+ enum parser_cb_type type,
+ const char **error_string,
+ icmap_map_t config_map,
+ void *user_data);
+
+struct key_value_list_item {
+ char *key;
+ char *value;
+ struct qb_list_head list;
+};
+
+struct main_cp_cb_data {
+ int linknumber;
+ char *bindnetaddr;
+ char *mcastaddr;
+ char *broadcast;
+ int mcastport;
+ int ttl;
+ int knet_link_priority;
+ int knet_ping_interval;
+ int knet_ping_timeout;
+ int knet_ping_precision;
+ int knet_pong_count;
+ int knet_pmtud_interval;
+ unsigned int knet_mtu;
+ char *knet_transport;
+
+ struct qb_list_head logger_subsys_items_head;
+ char *subsys;
+ char *logging_daemon_name;
+ struct qb_list_head member_items_head;
+
+ int node_number;
+};
+
+static int read_config_file_into_icmap(
+ const char **error_string, icmap_map_t config_map);
+static char error_string_response[512];
+
+static int uid_determine (const char *req_user)
+{
+ int pw_uid = 0;
+ struct passwd passwd;
+ struct passwd* pwdptr = &passwd;
+ struct passwd* temp_pwd_pt;
+ char *pwdbuffer;
+ int pwdlinelen, rc;
+ long int id;
+ char *ep;
+
+ id = strtol(req_user, &ep, 10);
+ if (*req_user != '\0' && *ep == '\0' && id >= 0 && id <= UINT_MAX) {
+ return (id);
+ }
+
+ pwdlinelen = sysconf (_SC_GETPW_R_SIZE_MAX);
+
+ if (pwdlinelen == -1) {
+ pwdlinelen = 256;
+ }
+
+ pwdbuffer = malloc (pwdlinelen);
+
+ while ((rc = getpwnam_r (req_user, pwdptr, pwdbuffer, pwdlinelen, &temp_pwd_pt)) == ERANGE) {
+ char *n;
+
+ pwdlinelen *= 2;
+ if (pwdlinelen <= 32678) {
+ n = realloc (pwdbuffer, pwdlinelen);
+ if (n != NULL) {
+ pwdbuffer = n;
+ continue;
+ }
+ }
+ }
+ if (rc != 0) {
+ free (pwdbuffer);
+ sprintf (error_string_response, "getpwnam_r(): %s", strerror(rc));
+ return (-1);
+ }
+ if (temp_pwd_pt == NULL) {
+ free (pwdbuffer);
+ sprintf (error_string_response,
+ "The '%s' user is not found in /etc/passwd, please read the documentation.",
+ req_user);
+ return (-1);
+ }
+ pw_uid = passwd.pw_uid;
+ free (pwdbuffer);
+
+ return pw_uid;
+}
+
+static int gid_determine (const char *req_group)
+{
+ int corosync_gid = 0;
+ struct group group;
+ struct group * grpptr = &group;
+ struct group * temp_grp_pt;
+ char *grpbuffer;
+ int grplinelen, rc;
+ long int id;
+ char *ep;
+
+ id = strtol(req_group, &ep, 10);
+ if (*req_group != '\0' && *ep == '\0' && id >= 0 && id <= UINT_MAX) {
+ return (id);
+ }
+
+ grplinelen = sysconf (_SC_GETGR_R_SIZE_MAX);
+
+ if (grplinelen == -1) {
+ grplinelen = 256;
+ }
+
+ grpbuffer = malloc (grplinelen);
+
+ while ((rc = getgrnam_r (req_group, grpptr, grpbuffer, grplinelen, &temp_grp_pt)) == ERANGE) {
+ char *n;
+
+ grplinelen *= 2;
+ if (grplinelen <= 32678) {
+ n = realloc (grpbuffer, grplinelen);
+ if (n != NULL) {
+ grpbuffer = n;
+ continue;
+ }
+ }
+ }
+ if (rc != 0) {
+ free (grpbuffer);
+ sprintf (error_string_response, "getgrnam_r(): %s", strerror(rc));
+ return (-1);
+ }
+ if (temp_grp_pt == NULL) {
+ free (grpbuffer);
+ sprintf (error_string_response,
+ "The '%s' group is not found in /etc/group, please read the documentation.",
+ req_group);
+ return (-1);
+ }
+ corosync_gid = group.gr_gid;
+ free (grpbuffer);
+
+ return corosync_gid;
+}
+static char *strchr_rs (const char *haystack, int byte)
+{
+ const char *end_address = strchr (haystack, byte);
+ if (end_address) {
+ end_address += 1; /* skip past { or = */
+
+ while (*end_address == ' ' || *end_address == '\t' || (unsigned char)*end_address == 0xA0)
+ end_address++;
+ }
+
+ return ((char *) end_address);
+}
+
+int coroparse_configparse (icmap_map_t config_map, const char **error_string)
+{
+ if (read_config_file_into_icmap(error_string, config_map)) {
+ return -1;
+ }
+
+ return 0;
+}
+
+static char *remove_whitespace(char *string, int remove_colon_and_brace)
+{
+ char *start;
+ char *end;
+
+ start = string;
+ while (*start == ' ' || *start == '\t' || (unsigned char)*start == 0xA0)
+ start++;
+
+ end = start+(strlen(start))-1;
+ while ((*end == ' ' || *end == '\t' || (unsigned char)*end == 0xA0 || (remove_colon_and_brace && (*end == ':' || *end == '{'))) && end > start)
+ end--;
+ if (*end != '\0')
+ *(end + 1) = '\0';
+
+ return start;
+}
+
+
+
+static int parse_section(FILE *fp,
+ const char *fname,
+ int *line_no,
+ char *path,
+ const char **error_string,
+ int depth,
+ enum main_cp_cb_data_state state,
+ parser_cb_f parser_cb,
+ icmap_map_t config_map,
+ void *user_data)
+{
+ char line[512];
+ int i;
+ char *loc;
+ int ignore_line;
+ char new_keyname[ICMAP_KEYNAME_MAXLEN];
+ static char formated_err[384];
+ const char *tmp_error_string;
+
+ if (strcmp(path, "") == 0) {
+ parser_cb("", NULL, NULL, &state, PARSER_CB_START, error_string, config_map, user_data);
+ }
+
+ tmp_error_string = NULL;
+
+ while (fgets (line, sizeof (line), fp)) {
+ (*line_no)++;
+
+ if (strlen(line) > 0) {
+ /*
+ * Check if complete line was read. Use feof to handle files
+ * without ending \n at the end of the file
+ */
+ if ((line[strlen(line) - 1] != '\n') && !feof(fp)) {
+ tmp_error_string = "Line too long";
+ goto parse_error;
+ }
+
+ if (line[strlen(line) - 1] == '\n')
+ line[strlen(line) - 1] = '\0';
+ if (strlen (line) > 0 && line[strlen(line) - 1] == '\r')
+ line[strlen(line) - 1] = '\0';
+ }
+ /*
+ * Clear out white space and tabs
+ */
+ for (i = strlen (line) - 1; i > -1; i--) {
+ if (line[i] == '\t' || line[i] == ' ' || (unsigned char)line[i] == 0xA0) {
+ line[i] = '\0';
+ } else {
+ break;
+ }
+ }
+
+ ignore_line = 1;
+ for (i = 0; i < strlen (line); i++) {
+ if (line[i] != '\t' && line[i] != ' ' && (unsigned char)line[i] != 0xA0) {
+ if (line[i] != '#')
+ ignore_line = 0;
+
+ break;
+ }
+ }
+ /*
+ * Clear out comments and empty lines
+ */
+ if (ignore_line) {
+ continue;
+ }
+
+ /* New section ? */
+ if ((loc = strchr_rs (line, '{'))) {
+ char *section;
+ char *after_section;
+ enum main_cp_cb_data_state newstate;
+
+ *(loc-1) = '\0';
+ section = remove_whitespace(line, 1);
+ after_section = remove_whitespace(loc, 0);
+
+ if (strcmp(section, "") == 0) {
+ tmp_error_string = "Missing section name before opening bracket '{'";
+ goto parse_error;
+ }
+
+ if (strcmp(after_section, "") != 0) {
+ tmp_error_string = "Extra characters after opening bracket '{'";
+ goto parse_error;
+ }
+
+ if (strlen(path) + strlen(section) + 1 >= ICMAP_KEYNAME_MAXLEN) {
+ tmp_error_string = "Start of section makes total cmap path too long";
+ goto parse_error;
+ }
+ strcpy(new_keyname, path);
+ if (strcmp(path, "") != 0) {
+ strcat(new_keyname, ".");
+ }
+ strcat(new_keyname, section);
+
+ /* Only use the new state for items further down the stack */
+ newstate = state;
+ if (!parser_cb(new_keyname, NULL, NULL, &newstate, PARSER_CB_SECTION_START,
+ &tmp_error_string, config_map, user_data)) {
+ goto parse_error;
+ }
+
+ if (parse_section(fp, fname, line_no, new_keyname, error_string, depth + 1, newstate,
+ parser_cb, config_map, user_data))
+ return -1;
+
+ continue ;
+ }
+
+ /* New key/value */
+ if ((loc = strchr_rs (line, ':'))) {
+ char *key;
+ char *value;
+
+ *(loc-1) = '\0';
+ key = remove_whitespace(line, 1);
+ value = remove_whitespace(loc, 0);
+
+ if (strlen(path) + strlen(key) + 1 >= ICMAP_KEYNAME_MAXLEN) {
+ tmp_error_string = "New key makes total cmap path too long";
+ goto parse_error;
+ }
+ strcpy(new_keyname, path);
+ if (strcmp(path, "") != 0) {
+ strcat(new_keyname, ".");
+ }
+ strcat(new_keyname, key);
+
+ if (!parser_cb(new_keyname, key, value, &state, PARSER_CB_ITEM, &tmp_error_string,
+ config_map, user_data)) {
+ goto parse_error;
+ }
+
+ continue ;
+ }
+
+ if (strchr_rs (line, '}')) {
+ char *trimmed_line;
+ trimmed_line = remove_whitespace(line, 0);
+
+ if (strcmp(trimmed_line, "}") != 0) {
+ tmp_error_string = "Extra characters before or after closing bracket '}'";
+ goto parse_error;
+ }
+
+ if (depth == 0) {
+ tmp_error_string = "Unexpected closing brace";
+
+ goto parse_error;
+ }
+
+ if (!parser_cb(path, NULL, NULL, &state, PARSER_CB_SECTION_END, &tmp_error_string,
+ config_map, user_data)) {
+ goto parse_error;
+ }
+
+ return 0;
+ }
+
+ /*
+ * Line is not opening section, ending section or value -> error
+ */
+ tmp_error_string = "Line is not opening or closing section or key value";
+ goto parse_error;
+ }
+
+ if (strcmp(path, "") != 0) {
+ tmp_error_string = "Missing closing brace";
+ goto parse_error;
+ }
+
+ if (strcmp(path, "") == 0) {
+ parser_cb("", NULL, NULL, &state, PARSER_CB_END, error_string, config_map, user_data);
+ }
+
+ return 0;
+
+parse_error:
+ if (snprintf(formated_err, sizeof(formated_err), "parser error: %s:%u: %s", fname, *line_no,
+ tmp_error_string) >= sizeof(formated_err)) {
+ *error_string = "Can't format parser error message";
+ } else {
+ *error_string = formated_err;
+ }
+
+ return -1;
+}
+
+static int safe_atoq_range(icmap_value_types_t value_type, long long int *min_val, long long int *max_val)
+{
+ switch (value_type) {
+ case ICMAP_VALUETYPE_INT8: *min_val = INT8_MIN; *max_val = INT8_MAX; break;
+ case ICMAP_VALUETYPE_UINT8: *min_val = 0; *max_val = UINT8_MAX; break;
+ case ICMAP_VALUETYPE_INT16: *min_val = INT16_MIN; *max_val = INT16_MAX; break;
+ case ICMAP_VALUETYPE_UINT16: *min_val = 0; *max_val = UINT16_MAX; break;
+ case ICMAP_VALUETYPE_INT32: *min_val = INT32_MIN; *max_val = INT32_MAX; break;
+ case ICMAP_VALUETYPE_UINT32: *min_val = 0; *max_val = UINT32_MAX; break;
+ default:
+ return (-1);
+ }
+
+ return (0);
+}
+
+/*
+ * Convert string str to long long int res. Type of result is target_type and currently only
+ * ICMAP_VALUETYPE_[U]INT[8|16|32] is supported.
+ * Return 0 on success, -1 on failure.
+ */
+static int safe_atoq(const char *str, long long int *res, icmap_value_types_t target_type)
+{
+ long long int val;
+ long long int min_val, max_val;
+ char *endptr;
+
+ errno = 0;
+
+ val = strtoll(str, &endptr, 10);
+ if (errno == ERANGE) {
+ return (-1);
+ }
+
+ if (endptr == str) {
+ return (-1);
+ }
+
+ if (*endptr != '\0') {
+ return (-1);
+ }
+
+ if (safe_atoq_range(target_type, &min_val, &max_val) != 0) {
+ return (-1);
+ }
+
+ if (val < min_val || val > max_val) {
+ return (-1);
+ }
+
+ *res = val;
+ return (0);
+}
+
+static int str_to_ull(const char *str, unsigned long long int *res)
+{
+ unsigned long long int val;
+ char *endptr;
+
+ errno = 0;
+
+ val = strtoull(str, &endptr, 10);
+ if (errno == ERANGE) {
+ return (-1);
+ }
+
+ if (endptr == str) {
+ return (-1);
+ }
+
+ if (*endptr != '\0') {
+ return (-1);
+ }
+
+ *res = val;
+ return (0);
+}
+
+static int handle_crypto_model(const char *val, const char **error_string)
+{
+
+ if (util_is_valid_knet_crypto_model(val, NULL, 0,
+ "Invalid crypto model. Should be ", error_string) == 1) {
+ return (0);
+ } else {
+ return (-1);
+ }
+}
+
+static int handle_compress_model(const char *val, const char **error_string)
+{
+
+ if (util_is_valid_knet_compress_model(val, NULL, 0,
+ "Invalid compression model. Should be ", error_string) == 1) {
+ return (0);
+ } else {
+ return (-1);
+ }
+}
+
+static int main_config_parser_cb(const char *path,
+ char *key,
+ char *value,
+ enum main_cp_cb_data_state *state,
+ enum parser_cb_type type,
+ const char **error_string,
+ icmap_map_t config_map,
+ void *user_data)
+{
+ int ii;
+ long long int val;
+ long long int min_val, max_val;
+ icmap_value_types_t val_type = ICMAP_VALUETYPE_BINARY;
+ unsigned long long int ull;
+ int add_as_string;
+ char key_name[ICMAP_KEYNAME_MAXLEN + 1];
+ static char formated_err[256];
+ struct main_cp_cb_data *data = (struct main_cp_cb_data *)user_data;
+ struct key_value_list_item *kv_item;
+ struct qb_list_head *iter, *tmp_iter;
+ int uid, gid;
+ cs_error_t cs_err;
+
+ cs_err = CS_OK;
+
+ /*
+ * Formally this check is not needed because length is checked by parse_section
+ */
+ if (strlen(path) >= sizeof(key_name)) {
+ if (snprintf(formated_err, sizeof(formated_err),
+ "Can't store path \"%s\" into key_name", path) >= sizeof(formated_err)) {
+ *error_string = "Can't format path into key_name error message";
+ } else {
+ *error_string = formated_err;
+ }
+ return (0);
+ }
+ /*
+ * Key_name is used in atoi_error/icmap_set_error, but many of icmap_set*
+ * are using path, so initialize key_name to valid value
+ */
+ strncpy(key_name, path, sizeof(key_name) - 1);
+
+ switch (type) {
+ case PARSER_CB_START:
+ memset(data, 0, sizeof(struct main_cp_cb_data));
+ *state = MAIN_CP_CB_DATA_STATE_NORMAL;
+ break;
+ case PARSER_CB_END:
+ break;
+ case PARSER_CB_ITEM:
+ add_as_string = 1;
+
+ switch (*state) {
+ case MAIN_CP_CB_DATA_STATE_NORMAL:
+ break;
+ case MAIN_CP_CB_DATA_STATE_PLOAD:
+ if ((strcmp(path, "pload.count") == 0) ||
+ (strcmp(path, "pload.size") == 0)) {
+ val_type = ICMAP_VALUETYPE_UINT32;
+ if (safe_atoq(value, &val, val_type) != 0) {
+ goto atoi_error;
+ }
+ if ((cs_err = icmap_set_uint32_r(config_map, path, val)) != CS_OK) {
+ goto icmap_set_error;
+ }
+ add_as_string = 0;
+ }
+ break;
+ case MAIN_CP_CB_DATA_STATE_QUORUM:
+ if ((strcmp(path, "quorum.expected_votes") == 0) ||
+ (strcmp(path, "quorum.votes") == 0) ||
+ (strcmp(path, "quorum.last_man_standing_window") == 0) ||
+ (strcmp(path, "quorum.leaving_timeout") == 0)) {
+ val_type = ICMAP_VALUETYPE_UINT32;
+ if (safe_atoq(value, &val, val_type) != 0) {
+ goto atoi_error;
+ }
+ if ((cs_err = icmap_set_uint32_r(config_map, path, val)) != CS_OK) {
+ goto icmap_set_error;
+ }
+ add_as_string = 0;
+ }
+
+ if ((strcmp(path, "quorum.two_node") == 0) ||
+ (strcmp(path, "quorum.expected_votes_tracking") == 0) ||
+ (strcmp(path, "quorum.allow_downscale") == 0) ||
+ (strcmp(path, "quorum.wait_for_all") == 0) ||
+ (strcmp(path, "quorum.auto_tie_breaker") == 0) ||
+ (strcmp(path, "quorum.last_man_standing") == 0)) {
+ val_type = ICMAP_VALUETYPE_UINT8;
+ if (safe_atoq(value, &val, val_type) != 0) {
+ goto atoi_error;
+ }
+ if ((cs_err = icmap_set_uint8_r(config_map, path, val)) != CS_OK) {
+ goto icmap_set_error;
+ }
+ add_as_string = 0;
+ }
+ break;
+ case MAIN_CP_CB_DATA_STATE_QDEVICE:
+ if ((strcmp(path, "quorum.device.timeout") == 0) ||
+ (strcmp(path, "quorum.device.sync_timeout") == 0) ||
+ (strcmp(path, "quorum.device.votes") == 0)) {
+ val_type = ICMAP_VALUETYPE_UINT32;
+ if (safe_atoq(value, &val, val_type) != 0) {
+ goto atoi_error;
+ }
+ if ((cs_err = icmap_set_uint32_r(config_map, path, val)) != CS_OK) {
+ goto icmap_set_error;
+ }
+ add_as_string = 0;
+ }
+ if ((strcmp(path, "quorum.device.master_wins") == 0)) {
+ val_type = ICMAP_VALUETYPE_UINT8;
+ if (safe_atoq(value, &val, val_type) != 0) {
+ goto atoi_error;
+ }
+ if ((cs_err = icmap_set_uint8_r(config_map, path, val)) != CS_OK) {
+ goto icmap_set_error;
+ }
+ add_as_string = 0;
+ }
+ break;
+ case MAIN_CP_CB_DATA_STATE_TOTEM:
+ if ((strcmp(path, "totem.version") == 0) ||
+ (strcmp(path, "totem.nodeid") == 0) ||
+ (strcmp(path, "totem.threads") == 0) ||
+ (strcmp(path, "totem.token") == 0) ||
+ (strcmp(path, "totem.token_coefficient") == 0) ||
+ (strcmp(path, "totem.token_retransmit") == 0) ||
+ (strcmp(path, "totem.token_warning") == 0) ||
+ (strcmp(path, "totem.hold") == 0) ||
+ (strcmp(path, "totem.token_retransmits_before_loss_const") == 0) ||
+ (strcmp(path, "totem.join") == 0) ||
+ (strcmp(path, "totem.send_join") == 0) ||
+ (strcmp(path, "totem.consensus") == 0) ||
+ (strcmp(path, "totem.merge") == 0) ||
+ (strcmp(path, "totem.downcheck") == 0) ||
+ (strcmp(path, "totem.fail_recv_const") == 0) ||
+ (strcmp(path, "totem.seqno_unchanged_const") == 0) ||
+ (strcmp(path, "totem.rrp_token_expired_timeout") == 0) ||
+ (strcmp(path, "totem.rrp_problem_count_timeout") == 0) ||
+ (strcmp(path, "totem.rrp_problem_count_threshold") == 0) ||
+ (strcmp(path, "totem.rrp_problem_count_mcast_threshold") == 0) ||
+ (strcmp(path, "totem.rrp_autorecovery_check_timeout") == 0) ||
+ (strcmp(path, "totem.heartbeat_failures_allowed") == 0) ||
+ (strcmp(path, "totem.max_network_delay") == 0) ||
+ (strcmp(path, "totem.window_size") == 0) ||
+ (strcmp(path, "totem.max_messages") == 0) ||
+ (strcmp(path, "totem.miss_count_const") == 0) ||
+ (strcmp(path, "totem.knet_pmtud_interval") == 0) ||
+ (strcmp(path, "totem.knet_mtu") == 0) ||
+ (strcmp(path, "totem.knet_compression_threshold") == 0) ||
+ (strcmp(path, "totem.netmtu") == 0)) {
+ val_type = ICMAP_VALUETYPE_UINT32;
+ if (safe_atoq(value, &val, val_type) != 0) {
+ goto atoi_error;
+ }
+ if ((cs_err = icmap_set_uint32_r(config_map,path, val)) != CS_OK) {
+ goto icmap_set_error;
+ }
+ add_as_string = 0;
+ }
+ if (strcmp(path, "totem.knet_compression_level") == 0) {
+ val_type = ICMAP_VALUETYPE_INT32;
+ if (safe_atoq(value, &val, val_type) != 0) {
+ goto atoi_error;
+ }
+ if ((cs_err = icmap_set_int32_r(config_map, path, val)) != CS_OK) {
+ goto icmap_set_error;
+ }
+ add_as_string = 0;
+ }
+ if (strcmp(path, "totem.config_version") == 0) {
+ if (str_to_ull(value, &ull) != 0) {
+ goto atoi_error;
+ }
+ if ((cs_err = icmap_set_uint64_r(config_map, path, ull)) != CS_OK) {
+ goto icmap_set_error;
+ }
+ add_as_string = 0;
+ }
+ if (strcmp(path, "totem.ip_version") == 0) {
+ if ((strcmp(value, "ipv4") != 0) &&
+ (strcmp(value, "ipv6") != 0) &&
+ (strcmp(value, "ipv6-4") != 0) &&
+ (strcmp(value, "ipv4-6") != 0)) {
+ *error_string = "Invalid ip_version type";
+
+ return (0);
+ }
+ }
+ if (strcmp(path, "totem.crypto_model") == 0) {
+ if (handle_crypto_model(value, error_string) != 0) {
+ return (0);
+ }
+ }
+
+ if (strcmp(path, "totem.crypto_cipher") == 0) {
+ if ((strcmp(value, "none") != 0) &&
+ (strcmp(value, "aes256") != 0) &&
+ (strcmp(value, "aes192") != 0) &&
+ (strcmp(value, "aes128") != 0)) {
+ *error_string = "Invalid cipher type. "
+ "Should be none, aes256, aes192 or aes128";
+
+ return (0);
+ }
+ }
+ if (strcmp(path, "totem.crypto_hash") == 0) {
+ if ((strcmp(value, "none") != 0) &&
+ (strcmp(value, "md5") != 0) &&
+ (strcmp(value, "sha1") != 0) &&
+ (strcmp(value, "sha256") != 0) &&
+ (strcmp(value, "sha384") != 0) &&
+ (strcmp(value, "sha512") != 0)) {
+ *error_string = "Invalid hash type. "
+ "Should be none, md5, sha1, sha256, sha384 or sha512";
+
+ return (0);
+ }
+ }
+
+ if (strcmp(path, "totem.knet_compression_model") == 0) {
+ if (handle_compress_model(value, error_string) != 0) {
+ return (0);
+ }
+ }
+
+ break;
+
+ case MAIN_CP_CB_DATA_STATE_SYSTEM:
+ if (strcmp(path, "system.qb_ipc_type") == 0) {
+ if ((strcmp(value, "native") != 0) &&
+ (strcmp(value, "shm") != 0) &&
+ (strcmp(value, "socket") != 0)) {
+ *error_string = "Invalid system.qb_ipc_type";
+
+ return (0);
+ }
+ }
+ if (strcmp(path, "system.sched_rr") == 0) {
+ if ((strcmp(value, "yes") != 0) &&
+ (strcmp(value, "no") != 0)) {
+ *error_string = "Invalid system.sched_rr value";
+
+ return (0);
+ }
+ }
+ if (strcmp(path, "system.move_to_root_cgroup") == 0) {
+ if ((strcmp(value, "yes") != 0) &&
+ (strcmp(value, "no") != 0) &&
+ (strcmp(value, "auto") != 0)) {
+ *error_string = "Invalid system.move_to_root_cgroup";
+
+ return (0);
+ }
+ }
+ if (strcmp(path, "system.allow_knet_handle_fallback") == 0) {
+ if ((strcmp(value, "yes") != 0) &&
+ (strcmp(value, "no") != 0)) {
+ *error_string = "Invalid system.allow_knet_handle_fallback";
+
+ return (0);
+ }
+ }
+ break;
+
+ case MAIN_CP_CB_DATA_STATE_INTERFACE:
+ if (strcmp(path, "totem.interface.linknumber") == 0) {
+ val_type = ICMAP_VALUETYPE_UINT8;
+ if (safe_atoq(value, &val, val_type) != 0) {
+ goto atoi_error;
+ }
+
+ data->linknumber = val;
+ add_as_string = 0;
+ }
+ if (strcmp(path, "totem.interface.bindnetaddr") == 0) {
+ data->bindnetaddr = strdup(value);
+ add_as_string = 0;
+ }
+ if (strcmp(path, "totem.interface.mcastaddr") == 0) {
+ data->mcastaddr = strdup(value);
+ add_as_string = 0;
+ }
+ if (strcmp(path, "totem.interface.broadcast") == 0) {
+ data->broadcast = strdup(value);
+ add_as_string = 0;
+ }
+ if (strcmp(path, "totem.interface.mcastport") == 0) {
+ val_type = ICMAP_VALUETYPE_UINT16;
+ if (safe_atoq(value, &val, val_type) != 0) {
+ goto atoi_error;
+ }
+ data->mcastport = val;
+ add_as_string = 0;
+ }
+ if (strcmp(path, "totem.interface.ttl") == 0) {
+ val_type = ICMAP_VALUETYPE_UINT8;
+ if (safe_atoq(value, &val, val_type) != 0) {
+ goto atoi_error;
+ }
+ data->ttl = val;
+ add_as_string = 0;
+ }
+ if (strcmp(path, "totem.interface.knet_link_priority") == 0) {
+ val_type = ICMAP_VALUETYPE_UINT8;
+ if (safe_atoq(value, &val, val_type) != 0) {
+ goto atoi_error;
+ }
+ data->knet_link_priority = val;
+ add_as_string = 0;
+ }
+ if (strcmp(path, "totem.interface.knet_ping_interval") == 0) {
+ val_type = ICMAP_VALUETYPE_UINT32;
+ if (safe_atoq(value, &val, val_type) != 0) {
+ goto atoi_error;
+ }
+ data->knet_ping_interval = val;
+ add_as_string = 0;
+ }
+ if (strcmp(path, "totem.interface.knet_ping_timeout") == 0) {
+ val_type = ICMAP_VALUETYPE_UINT32;
+ if (safe_atoq(value, &val, val_type) != 0) {
+ goto atoi_error;
+ }
+ data->knet_ping_timeout = val;
+ add_as_string = 0;
+ }
+ if (strcmp(path, "totem.interface.knet_ping_precision") == 0) {
+ val_type = ICMAP_VALUETYPE_UINT32;
+ if (safe_atoq(value, &val, val_type) != 0) {
+ goto atoi_error;
+ }
+ data->knet_ping_precision = val;
+ add_as_string = 0;
+ }
+ if (strcmp(path, "totem.interface.knet_pong_count") == 0) {
+ val_type = ICMAP_VALUETYPE_UINT32;
+ if (safe_atoq(value, &val, val_type) != 0) {
+ goto atoi_error;
+ }
+ data->knet_pong_count = val;
+ add_as_string = 0;
+ }
+ if (strcmp(path, "totem.interface.knet_transport") == 0) {
+ val_type = ICMAP_VALUETYPE_STRING;
+ data->knet_transport = strdup(value);
+ add_as_string = 0;
+ }
+ break;
+ case MAIN_CP_CB_DATA_STATE_LOGGER_SUBSYS:
+ if (strcmp(key, "subsys") == 0) {
+ data->subsys = strdup(value);
+ if (data->subsys == NULL) {
+ *error_string = "Can't alloc memory";
+
+ return (0);
+ }
+ } else {
+ kv_item = malloc(sizeof(*kv_item));
+ if (kv_item == NULL) {
+ *error_string = "Can't alloc memory";
+
+ return (0);
+ }
+ memset(kv_item, 0, sizeof(*kv_item));
+
+ kv_item->key = strdup(key);
+ kv_item->value = strdup(value);
+ if (kv_item->key == NULL || kv_item->value == NULL) {
+ free(kv_item);
+ *error_string = "Can't alloc memory";
+
+ return (0);
+ }
+ qb_list_init(&kv_item->list);
+ qb_list_add(&kv_item->list, &data->logger_subsys_items_head);
+ }
+ add_as_string = 0;
+ break;
+ case MAIN_CP_CB_DATA_STATE_LOGGING_DAEMON:
+ if (strcmp(key, "subsys") == 0) {
+ data->subsys = strdup(value);
+ if (data->subsys == NULL) {
+ *error_string = "Can't alloc memory";
+
+ return (0);
+ }
+ } else if (strcmp(key, "name") == 0) {
+ data->logging_daemon_name = strdup(value);
+ if (data->logging_daemon_name == NULL) {
+ *error_string = "Can't alloc memory";
+
+ return (0);
+ }
+ } else {
+ kv_item = malloc(sizeof(*kv_item));
+ if (kv_item == NULL) {
+ *error_string = "Can't alloc memory";
+
+ return (0);
+ }
+ memset(kv_item, 0, sizeof(*kv_item));
+
+ kv_item->key = strdup(key);
+ kv_item->value = strdup(value);
+ if (kv_item->key == NULL || kv_item->value == NULL) {
+ free(kv_item);
+ *error_string = "Can't alloc memory";
+
+ return (0);
+ }
+ qb_list_init(&kv_item->list);
+ qb_list_add(&kv_item->list, &data->logger_subsys_items_head);
+ }
+ add_as_string = 0;
+ break;
+ case MAIN_CP_CB_DATA_STATE_UIDGID:
+ if (strcmp(key, "uid") == 0) {
+ uid = uid_determine(value);
+ if (uid == -1) {
+ *error_string = error_string_response;
+ return (0);
+ }
+ snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "uidgid.config.uid.%u",
+ uid);
+ if ((cs_err = icmap_set_uint8_r(config_map, key_name, 1)) != CS_OK) {
+ goto icmap_set_error;
+ }
+ add_as_string = 0;
+ } else if (strcmp(key, "gid") == 0) {
+ gid = gid_determine(value);
+ if (gid == -1) {
+ *error_string = error_string_response;
+ return (0);
+ }
+ snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "uidgid.config.gid.%u",
+ gid);
+ if ((cs_err = icmap_set_uint8_r(config_map, key_name, 1)) != CS_OK) {
+ goto icmap_set_error;
+ }
+ add_as_string = 0;
+ } else {
+ *error_string = "uidgid: Only uid and gid are allowed items";
+ return (0);
+ }
+ break;
+ case MAIN_CP_CB_DATA_STATE_MEMBER:
+ if (strcmp(key, "memberaddr") != 0) {
+ *error_string = "Only memberaddr is allowed in member section";
+
+ return (0);
+ }
+
+ kv_item = malloc(sizeof(*kv_item));
+ if (kv_item == NULL) {
+ *error_string = "Can't alloc memory";
+
+ return (0);
+ }
+ memset(kv_item, 0, sizeof(*kv_item));
+
+ kv_item->key = strdup(key);
+ kv_item->value = strdup(value);
+ if (kv_item->key == NULL || kv_item->value == NULL) {
+ free(kv_item);
+ *error_string = "Can't alloc memory";
+
+ return (0);
+ }
+ qb_list_init(&kv_item->list);
+ qb_list_add(&kv_item->list, &data->member_items_head);
+ add_as_string = 0;
+ break;
+ case MAIN_CP_CB_DATA_STATE_NODELIST:
+ break;
+ case MAIN_CP_CB_DATA_STATE_NODELIST_NODE:
+ snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "nodelist.node.%u.%s", data->node_number, key);
+ if ((strcmp(key, "nodeid") == 0) ||
+ (strcmp(key, "quorum_votes") == 0)) {
+ val_type = ICMAP_VALUETYPE_UINT32;
+ if (safe_atoq(value, &val, val_type) != 0) {
+ goto atoi_error;
+ }
+
+ if ((cs_err = icmap_set_uint32_r(config_map, key_name, val)) != CS_OK) {
+ goto icmap_set_error;
+ }
+ add_as_string = 0;
+ }
+
+ if (add_as_string) {
+ if ((cs_err = icmap_set_string_r(config_map, key_name, value)) != CS_OK) {
+ goto icmap_set_error;
+ };
+ add_as_string = 0;
+ }
+ break;
+ case MAIN_CP_CB_DATA_STATE_RESOURCES:
+ if (strcmp(key, "watchdog_timeout") == 0) {
+ val_type = ICMAP_VALUETYPE_UINT32;
+ if (safe_atoq(value, &val, val_type) != 0) {
+ goto atoi_error;
+ }
+ if ((cs_err = icmap_set_uint32_r(config_map,path, val)) != CS_OK) {
+ goto icmap_set_error;
+ }
+ add_as_string = 0;
+ }
+ break;
+ case MAIN_CP_CB_DATA_STATE_RESOURCES_SYSTEM:
+ case MAIN_CP_CB_DATA_STATE_RESOURCES_SYSTEM_MEMUSED:
+ if (strcmp(key, "poll_period") == 0) {
+ if (str_to_ull(value, &ull) != 0) {
+ goto atoi_error;
+ }
+ if ((cs_err = icmap_set_uint64_r(config_map,path, ull)) != CS_OK) {
+ goto icmap_set_error;
+ }
+ add_as_string = 0;
+ }
+ break;
+ case MAIN_CP_CB_DATA_STATE_RESOURCES_PROCESS:
+ case MAIN_CP_CB_DATA_STATE_RESOURCES_PROCESS_MEMUSED:
+ if (strcmp(key, "poll_period") == 0) {
+ if (str_to_ull(value, &ull) != 0) {
+ goto atoi_error;
+ }
+ if ((cs_err = icmap_set_uint64_r(config_map,path, ull)) != CS_OK) {
+ goto icmap_set_error;
+ }
+ add_as_string = 0;
+ }
+ break;
+ }
+
+ if (add_as_string) {
+ if ((cs_err = icmap_set_string_r(config_map, path, value)) != CS_OK) {
+ goto icmap_set_error;
+ }
+ }
+ break;
+ case PARSER_CB_SECTION_START:
+ if (strcmp(path, "totem.interface") == 0) {
+ *state = MAIN_CP_CB_DATA_STATE_INTERFACE;
+ data->linknumber = 0;
+ data->mcastport = -1;
+ data->ttl = -1;
+ data->knet_link_priority = -1;
+ data->knet_ping_interval = -1;
+ data->knet_ping_timeout = -1;
+ data->knet_ping_precision = -1;
+ data->knet_pong_count = -1;
+ data->knet_transport = NULL;
+ qb_list_init(&data->member_items_head);
+ };
+ if (strcmp(path, "totem") == 0) {
+ *state = MAIN_CP_CB_DATA_STATE_TOTEM;
+ };
+ if (strcmp(path, "system") == 0) {
+ *state = MAIN_CP_CB_DATA_STATE_SYSTEM;
+ }
+ if (strcmp(path, "logging.logger_subsys") == 0) {
+ *state = MAIN_CP_CB_DATA_STATE_LOGGER_SUBSYS;
+ qb_list_init(&data->logger_subsys_items_head);
+ data->subsys = NULL;
+ }
+ if (strcmp(path, "logging.logging_daemon") == 0) {
+ *state = MAIN_CP_CB_DATA_STATE_LOGGING_DAEMON;
+ qb_list_init(&data->logger_subsys_items_head);
+ data->subsys = NULL;
+ data->logging_daemon_name = NULL;
+ }
+ if (strcmp(path, "uidgid") == 0) {
+ *state = MAIN_CP_CB_DATA_STATE_UIDGID;
+ }
+ if (strcmp(path, "totem.interface.member") == 0) {
+ *state = MAIN_CP_CB_DATA_STATE_MEMBER;
+ }
+ if (strcmp(path, "quorum") == 0) {
+ *state = MAIN_CP_CB_DATA_STATE_QUORUM;
+ }
+ if (strcmp(path, "quorum.device") == 0) {
+ *state = MAIN_CP_CB_DATA_STATE_QDEVICE;
+ }
+ if (strcmp(path, "nodelist") == 0) {
+ *state = MAIN_CP_CB_DATA_STATE_NODELIST;
+ data->node_number = 0;
+ }
+ if (strcmp(path, "nodelist.node") == 0) {
+ *state = MAIN_CP_CB_DATA_STATE_NODELIST_NODE;
+ }
+ if (strcmp(path, "resources") == 0) {
+ *state = MAIN_CP_CB_DATA_STATE_RESOURCES;
+ }
+ if (strcmp(path, "resources.system") == 0) {
+ *state = MAIN_CP_CB_DATA_STATE_RESOURCES_SYSTEM;
+ }
+ if (strcmp(path, "resources.system.memory_used") == 0) {
+ *state = MAIN_CP_CB_DATA_STATE_RESOURCES_SYSTEM_MEMUSED;
+ }
+ if (strcmp(path, "resources.process") == 0) {
+ *state = MAIN_CP_CB_DATA_STATE_RESOURCES_PROCESS;
+ }
+ if (strcmp(path, "resources.process.memory_used") == 0) {
+ *state = MAIN_CP_CB_DATA_STATE_RESOURCES_PROCESS_MEMUSED;
+ }
+ break;
+ case PARSER_CB_SECTION_END:
+ switch (*state) {
+ case MAIN_CP_CB_DATA_STATE_INTERFACE:
+ /*
+ * Create new interface section
+ */
+ if (data->bindnetaddr != NULL) {
+ snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "totem.interface.%u.bindnetaddr",
+ data->linknumber);
+ cs_err = icmap_set_string_r(config_map, key_name, data->bindnetaddr);
+
+ free(data->bindnetaddr);
+ data->bindnetaddr = NULL;
+
+ if (cs_err != CS_OK) {
+ goto icmap_set_error;
+ }
+ }
+
+ if (data->mcastaddr != NULL) {
+ snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "totem.interface.%u.mcastaddr",
+ data->linknumber);
+ cs_err = icmap_set_string_r(config_map, key_name, data->mcastaddr);
+
+ free(data->mcastaddr);
+ data->mcastaddr = NULL;
+
+ if (cs_err != CS_OK) {
+ goto icmap_set_error;
+ }
+ }
+
+ if (data->broadcast != NULL) {
+ snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "totem.interface.%u.broadcast",
+ data->linknumber);
+ cs_err = icmap_set_string_r(config_map, key_name, data->broadcast);
+
+ free(data->broadcast);
+ data->broadcast = NULL;
+
+ if (cs_err != CS_OK) {
+ goto icmap_set_error;
+ }
+ }
+
+ if (data->mcastport > -1) {
+ snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "totem.interface.%u.mcastport",
+ data->linknumber);
+ if ((cs_err = icmap_set_uint16_r(config_map, key_name,
+ data->mcastport)) != CS_OK) {
+ goto icmap_set_error;
+ }
+ }
+
+ if (data->ttl > -1) {
+ snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "totem.interface.%u.ttl",
+ data->linknumber);
+ if ((cs_err = icmap_set_uint8_r(config_map, key_name, data->ttl)) != CS_OK) {
+ goto icmap_set_error;
+ }
+ }
+ if (data->knet_link_priority > -1) {
+ snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "totem.interface.%u.knet_link_priority",
+ data->linknumber);
+ if ((cs_err = icmap_set_uint8_r(config_map, key_name,
+ data->knet_link_priority)) != CS_OK) {
+ goto icmap_set_error;
+ }
+ }
+ if (data->knet_ping_interval > -1) {
+ snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "totem.interface.%u.knet_ping_interval",
+ data->linknumber);
+ if ((cs_err = icmap_set_uint32_r(config_map, key_name,
+ data->knet_ping_interval)) != CS_OK) {
+ goto icmap_set_error;
+ }
+ }
+ if (data->knet_ping_timeout > -1) {
+ snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "totem.interface.%u.knet_ping_timeout",
+ data->linknumber);
+ if ((cs_err = icmap_set_uint32_r(config_map, key_name,
+ data->knet_ping_timeout)) != CS_OK) {
+ goto icmap_set_error;
+ }
+ }
+ if (data->knet_ping_precision > -1) {
+ snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "totem.interface.%u.knet_ping_precision",
+ data->linknumber);
+ if ((cs_err = icmap_set_uint32_r(config_map, key_name,
+ data->knet_ping_precision)) != CS_OK) {
+ goto icmap_set_error;
+ }
+ }
+ if (data->knet_pong_count > -1) {
+ snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "totem.interface.%u.knet_pong_count",
+ data->linknumber);
+ if ((cs_err = icmap_set_uint32_r(config_map, key_name,
+ data->knet_pong_count)) != CS_OK) {
+ goto icmap_set_error;
+ }
+ }
+ if (data->knet_transport) {
+ snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "totem.interface.%u.knet_transport",
+ data->linknumber);
+ cs_err = icmap_set_string_r(config_map, key_name, data->knet_transport);
+ free(data->knet_transport);
+
+ if (cs_err != CS_OK) {
+ goto icmap_set_error;
+ }
+ }
+
+ ii = 0;
+
+ qb_list_for_each_safe(iter, tmp_iter, &(data->member_items_head)) {
+ kv_item = qb_list_entry(iter, struct key_value_list_item, list);
+
+ snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "totem.interface.%u.member.%u",
+ data->linknumber, ii);
+ cs_err = icmap_set_string_r(config_map, key_name, kv_item->value);
+
+ free(kv_item->value);
+ free(kv_item->key);
+ free(kv_item);
+ ii++;
+
+ if (cs_err != CS_OK) {
+ goto icmap_set_error;
+ }
+ }
+
+ break;
+ case MAIN_CP_CB_DATA_STATE_LOGGER_SUBSYS:
+ if (data->subsys == NULL) {
+ *error_string = "No subsys key in logger_subsys directive";
+
+ return (0);
+ }
+
+ qb_list_for_each_safe(iter, tmp_iter, &(data->logger_subsys_items_head)) {
+ kv_item = qb_list_entry(iter, struct key_value_list_item, list);
+
+ snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "logging.logger_subsys.%s.%s",
+ data->subsys, kv_item->key);
+ cs_err = icmap_set_string_r(config_map, key_name, kv_item->value);
+
+ free(kv_item->value);
+ free(kv_item->key);
+ free(kv_item);
+
+ if (cs_err != CS_OK) {
+ goto icmap_set_error;
+ }
+ }
+
+ snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "logging.logger_subsys.%s.subsys",
+ data->subsys);
+ cs_err = icmap_set_string_r(config_map, key_name, data->subsys);
+
+ free(data->subsys);
+
+ if (cs_err != CS_OK) {
+ goto icmap_set_error;
+ }
+ break;
+ case MAIN_CP_CB_DATA_STATE_LOGGING_DAEMON:
+ if (data->logging_daemon_name == NULL) {
+ *error_string = "No name key in logging_daemon directive";
+
+ return (0);
+ }
+
+ qb_list_for_each_safe(iter, tmp_iter, &(data->logger_subsys_items_head)) {
+ kv_item = qb_list_entry(iter, struct key_value_list_item, list);
+
+ if (data->subsys == NULL) {
+ if (strcmp(data->logging_daemon_name, "corosync") == 0) {
+ snprintf(key_name, ICMAP_KEYNAME_MAXLEN,
+ "logging.%s",
+ kv_item->key);
+ } else {
+ snprintf(key_name, ICMAP_KEYNAME_MAXLEN,
+ "logging.logging_daemon.%s.%s",
+ data->logging_daemon_name, kv_item->key);
+ }
+ } else {
+ if (strcmp(data->logging_daemon_name, "corosync") == 0) {
+ snprintf(key_name, ICMAP_KEYNAME_MAXLEN,
+ "logging.logger_subsys.%s.%s",
+ data->subsys,
+ kv_item->key);
+ } else {
+ snprintf(key_name, ICMAP_KEYNAME_MAXLEN,
+ "logging.logging_daemon.%s.%s.%s",
+ data->logging_daemon_name, data->subsys,
+ kv_item->key);
+ }
+ }
+ cs_err = icmap_set_string_r(config_map, key_name, kv_item->value);
+
+ free(kv_item->value);
+ free(kv_item->key);
+ free(kv_item);
+
+ if (cs_err != CS_OK) {
+ goto icmap_set_error;
+ }
+ }
+
+ if (data->subsys == NULL) {
+ if (strcmp(data->logging_daemon_name, "corosync") != 0) {
+ snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "logging.logging_daemon.%s.name",
+ data->logging_daemon_name);
+ cs_err = icmap_set_string_r(config_map, key_name, data->logging_daemon_name);
+ }
+ } else {
+ if (strcmp(data->logging_daemon_name, "corosync") == 0) {
+ snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "logging.logger_subsys.%s.subsys",
+ data->subsys);
+ cs_err = icmap_set_string_r(config_map, key_name, data->subsys);
+
+ } else {
+ snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "logging.logging_daemon.%s.%s.subsys",
+ data->logging_daemon_name, data->subsys);
+ cs_err = icmap_set_string_r(config_map, key_name, data->subsys);
+
+ if (cs_err != CS_OK) {
+ free(data->subsys);
+ free(data->logging_daemon_name);
+
+ goto icmap_set_error;
+ }
+ snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "logging.logging_daemon.%s.%s.name",
+ data->logging_daemon_name, data->subsys);
+ cs_err = icmap_set_string_r(config_map, key_name, data->logging_daemon_name);
+ }
+ }
+
+ free(data->subsys);
+ free(data->logging_daemon_name);
+
+ if (cs_err != CS_OK) {
+ goto icmap_set_error;
+ }
+ break;
+ case MAIN_CP_CB_DATA_STATE_NODELIST_NODE:
+ data->node_number++;
+ break;
+ case MAIN_CP_CB_DATA_STATE_NORMAL:
+ case MAIN_CP_CB_DATA_STATE_PLOAD:
+ case MAIN_CP_CB_DATA_STATE_UIDGID:
+ case MAIN_CP_CB_DATA_STATE_MEMBER:
+ case MAIN_CP_CB_DATA_STATE_QUORUM:
+ case MAIN_CP_CB_DATA_STATE_QDEVICE:
+ case MAIN_CP_CB_DATA_STATE_NODELIST:
+ case MAIN_CP_CB_DATA_STATE_TOTEM:
+ case MAIN_CP_CB_DATA_STATE_SYSTEM:
+ break;
+ case MAIN_CP_CB_DATA_STATE_RESOURCES:
+ *state = MAIN_CP_CB_DATA_STATE_NORMAL;
+ break;
+ case MAIN_CP_CB_DATA_STATE_RESOURCES_SYSTEM:
+ *state = MAIN_CP_CB_DATA_STATE_RESOURCES;
+ break;
+ case MAIN_CP_CB_DATA_STATE_RESOURCES_SYSTEM_MEMUSED:
+ *state = MAIN_CP_CB_DATA_STATE_RESOURCES_SYSTEM;
+ break;
+ case MAIN_CP_CB_DATA_STATE_RESOURCES_PROCESS:
+ *state = MAIN_CP_CB_DATA_STATE_RESOURCES;
+ break;
+ case MAIN_CP_CB_DATA_STATE_RESOURCES_PROCESS_MEMUSED:
+ *state = MAIN_CP_CB_DATA_STATE_RESOURCES_PROCESS;
+ break;
+ }
+ break;
+ }
+
+ return (1);
+
+atoi_error:
+ min_val = max_val = 0;
+ /*
+ * This is really assert, because developer ether doesn't set val_type correctly or
+ * we've got here after some nasty memory overwrite
+ */
+ assert(safe_atoq_range(val_type, &min_val, &max_val) == 0);
+
+ if (snprintf(formated_err, sizeof(formated_err),
+ "Value of key \"%s\" is expected to be integer in range (%lld..%lld), but \"%s\" was given",
+ key_name, min_val, max_val, value) >= sizeof(formated_err)) {
+ *error_string = "Can't format parser error message";
+ } else {
+ *error_string = formated_err;
+ }
+
+ return (0);
+
+icmap_set_error:
+ if (snprintf(formated_err, sizeof(formated_err),
+ "Can't store key \"%s\" into icmap, returned error is %s",
+ key_name, cs_strerror(cs_err)) >= sizeof(formated_err)) {
+ *error_string = "Can't format parser error message";
+ } else {
+ *error_string = formated_err;
+ }
+
+ return (0);
+}
+
+static int uidgid_config_parser_cb(const char *path,
+ char *key,
+ char *value,
+ enum main_cp_cb_data_state *state,
+ enum parser_cb_type type,
+ const char **error_string,
+ icmap_map_t config_map,
+ void *user_data)
+{
+ char key_name[ICMAP_KEYNAME_MAXLEN];
+ int uid, gid;
+ static char formated_err[256];
+ cs_error_t cs_err;
+
+ switch (type) {
+ case PARSER_CB_START:
+ break;
+ case PARSER_CB_END:
+ break;
+ case PARSER_CB_ITEM:
+ if (strcmp(path, "uidgid.uid") == 0) {
+ uid = uid_determine(value);
+ if (uid == -1) {
+ *error_string = error_string_response;
+ return (0);
+ }
+ snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "uidgid.config.uid.%u",
+ uid);
+ if ((cs_err = icmap_set_uint8_r(config_map, key_name, 1)) != CS_OK) {
+ goto icmap_set_error;
+ }
+ } else if (strcmp(path, "uidgid.gid") == 0) {
+ gid = gid_determine(value);
+ if (gid == -1) {
+ *error_string = error_string_response;
+ return (0);
+ }
+ snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "uidgid.config.gid.%u",
+ gid);
+ if ((cs_err = icmap_set_uint8_r(config_map, key_name, 1)) != CS_OK) {
+ goto icmap_set_error;
+ }
+ } else {
+ *error_string = "uidgid: Only uid and gid are allowed items";
+ return (0);
+ }
+ break;
+ case PARSER_CB_SECTION_START:
+ if (strcmp(path, "uidgid") != 0) {
+ *error_string = "uidgid: Can't add subsection different than uidgid";
+ return (0);
+ };
+ break;
+ case PARSER_CB_SECTION_END:
+ break;
+ }
+
+ return (1);
+
+icmap_set_error:
+ if (snprintf(formated_err, sizeof(formated_err),
+ "Can't store key \"%s\" into icmap, returned error is %s",
+ key_name, cs_strerror(cs_err)) >= sizeof(formated_err)) {
+ *error_string = "Can't format parser error message";
+ } else {
+ *error_string = formated_err;
+ }
+
+ return (0);
+}
+
+static int read_uidgid_files_into_icmap(
+ const char **error_string,
+ icmap_map_t config_map)
+{
+ FILE *fp;
+ char *dirname_res;
+ DIR *dp;
+ struct dirent *dirent;
+ char filename[PATH_MAX + FILENAME_MAX + 1];
+ char uidgid_dirname[PATH_MAX + FILENAME_MAX + 1];
+ int res = 0;
+ struct stat stat_buf;
+ enum main_cp_cb_data_state state = MAIN_CP_CB_DATA_STATE_NORMAL;
+ char key_name[ICMAP_KEYNAME_MAXLEN];
+ int line_no;
+
+ /*
+ * Build uidgid directory based on corosync.conf file location
+ */
+ res = snprintf(filename, sizeof(filename), "%s",
+ corosync_get_config_file());
+ if (res >= sizeof(filename)) {
+ *error_string = "uidgid.d path too long";
+
+ return (-1);
+ }
+
+ dirname_res = dirname(filename);
+
+ res = snprintf(uidgid_dirname, sizeof(uidgid_dirname), "%s/%s",
+ dirname_res, "uidgid.d");
+ if (res >= sizeof(uidgid_dirname)) {
+ *error_string = "uidgid.d path too long";
+
+ return (-1);
+ }
+
+ dp = opendir (uidgid_dirname);
+
+ if (dp == NULL)
+ return 0;
+
+ for (dirent = readdir(dp);
+ dirent != NULL;
+ dirent = readdir(dp)) {
+
+ res = snprintf(filename, sizeof (filename), "%s/%s", uidgid_dirname, dirent->d_name);
+ if (res >= sizeof(filename)) {
+ res = -1;
+ *error_string = "uidgid.d dirname path too long";
+
+ goto error_exit;
+ }
+ res = stat (filename, &stat_buf);
+ if (res == 0 && S_ISREG(stat_buf.st_mode)) {
+
+ fp = fopen (filename, "r");
+ if (fp == NULL) continue;
+
+ key_name[0] = 0;
+
+ line_no = 0;
+ res = parse_section(fp, filename, &line_no, key_name, error_string, 0, state,
+ uidgid_config_parser_cb, config_map, NULL);
+
+ fclose (fp);
+
+ if (res != 0) {
+ goto error_exit;
+ }
+ }
+ }
+
+error_exit:
+ closedir(dp);
+
+ return res;
+}
+
+/* Read config file and load into icmap */
+static int read_config_file_into_icmap(
+ const char **error_string,
+ icmap_map_t config_map)
+{
+ FILE *fp;
+ const char *filename;
+ char *error_reason = error_string_response;
+ int res;
+ char key_name[ICMAP_KEYNAME_MAXLEN];
+ struct main_cp_cb_data data;
+ enum main_cp_cb_data_state state = MAIN_CP_CB_DATA_STATE_NORMAL;
+ int line_no;
+
+ filename = corosync_get_config_file();
+
+ fp = fopen (filename, "r");
+ if (fp == NULL) {
+ char error_str[100];
+ const char *error_ptr = qb_strerror_r(errno, error_str, sizeof(error_str));
+ snprintf (error_reason, sizeof(error_string_response),
+ "Can't read file %s: %s",
+ filename, error_ptr);
+ *error_string = error_reason;
+ return -1;
+ }
+
+ key_name[0] = 0;
+
+ line_no = 0;
+ res = parse_section(fp, filename, &line_no, key_name, error_string, 0, state,
+ main_config_parser_cb, config_map, &data);
+
+ fclose(fp);
+
+ if (res == 0) {
+ res = read_uidgid_files_into_icmap(error_string, config_map);
+ }
+
+ if (res == 0) {
+ snprintf (error_reason, sizeof(error_string_response),
+ "Successfully read main configuration file '%s'.", filename);
+ *error_string = error_reason;
+ }
+
+ return res;
+}
diff --git a/exec/cpg.c b/exec/cpg.c
new file mode 100644
index 0000000..0439d14
--- /dev/null
+++ b/exec/cpg.c
@@ -0,0 +1,2344 @@
+/*
+ * Copyright (c) 2006-2019 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Author: Christine Caulfield (ccaulfie@redhat.com)
+ * Author: Jan Friesse (jfriesse@redhat.com)
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of the MontaVista Software, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#ifdef HAVE_ALLOCA_H
+#include <alloca.h>
+#endif
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.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 <time.h>
+#include <assert.h>
+#include <arpa/inet.h>
+#include <sys/mman.h>
+
+#include <qb/qblist.h>
+#include <qb/qbmap.h>
+
+#include <corosync/corotypes.h>
+#include <qb/qbipc_common.h>
+#include <corosync/corodefs.h>
+#include <corosync/logsys.h>
+#include <corosync/coroapi.h>
+
+#include <corosync/cpg.h>
+#include <corosync/ipc_cpg.h>
+
+#ifndef MAP_ANONYMOUS
+#define MAP_ANONYMOUS MAP_ANON
+#endif
+
+#include "service.h"
+
+LOGSYS_DECLARE_SUBSYS ("CPG");
+
+#define GROUP_HASH_SIZE 32
+
+enum cpg_message_req_types {
+ MESSAGE_REQ_EXEC_CPG_PROCJOIN = 0,
+ MESSAGE_REQ_EXEC_CPG_PROCLEAVE = 1,
+ MESSAGE_REQ_EXEC_CPG_JOINLIST = 2,
+ MESSAGE_REQ_EXEC_CPG_MCAST = 3,
+ MESSAGE_REQ_EXEC_CPG_DOWNLIST_OLD = 4,
+ MESSAGE_REQ_EXEC_CPG_DOWNLIST = 5,
+ MESSAGE_REQ_EXEC_CPG_PARTIAL_MCAST = 6,
+};
+
+struct zcb_mapped {
+ struct qb_list_head list;
+ void *addr;
+ size_t size;
+};
+/*
+ * state` exec deliver
+ * match group name, pid -> if matched deliver for YES:
+ * XXX indicates impossible state
+ *
+ * join leave mcast
+ * UNJOINED XXX XXX NO
+ * LEAVE_STARTED XXX YES(unjoined_enter) YES
+ * JOIN_STARTED YES(join_started_enter) XXX NO
+ * JOIN_COMPLETED XXX NO YES
+ *
+ * join_started_enter
+ * set JOIN_COMPLETED
+ * add entry to process_info list
+ * unjoined_enter
+ * set UNJOINED
+ * delete entry from process_info list
+ *
+ *
+ * library accept join error codes
+ * UNJOINED YES(CS_OK) set JOIN_STARTED
+ * LEAVE_STARTED NO(CS_ERR_BUSY)
+ * JOIN_STARTED NO(CS_ERR_EXIST)
+ * JOIN_COMPlETED NO(CS_ERR_EXIST)
+ *
+ * library accept leave error codes
+ * UNJOINED NO(CS_ERR_NOT_EXIST)
+ * LEAVE_STARTED NO(CS_ERR_NOT_EXIST)
+ * JOIN_STARTED NO(CS_ERR_BUSY)
+ * JOIN_COMPLETED YES(CS_OK) set LEAVE_STARTED
+ *
+ * library accept mcast
+ * UNJOINED NO(CS_ERR_NOT_EXIST)
+ * LEAVE_STARTED NO(CS_ERR_NOT_EXIST)
+ * JOIN_STARTED YES(CS_OK)
+ * JOIN_COMPLETED YES(CS_OK)
+ */
+enum cpd_state {
+ CPD_STATE_UNJOINED,
+ CPD_STATE_LEAVE_STARTED,
+ CPD_STATE_JOIN_STARTED,
+ CPD_STATE_JOIN_COMPLETED
+};
+
+enum cpg_sync_state {
+ CPGSYNC_DOWNLIST,
+ CPGSYNC_JOINLIST
+};
+
+static struct qb_list_head joinlist_messages_head;
+
+struct cpg_pd {
+ void *conn;
+ mar_cpg_name_t group_name;
+ uint32_t pid;
+ enum cpd_state cpd_state;
+ unsigned int flags;
+ int initial_totem_conf_sent;
+ uint64_t transition_counter; /* These two are used when sending fragmented messages */
+ uint64_t initial_transition_counter;
+ struct qb_list_head list;
+ struct qb_list_head iteration_instance_list_head;
+ struct qb_list_head zcb_mapped_list_head;
+};
+
+struct cpg_iteration_instance {
+ hdb_handle_t handle;
+ struct qb_list_head list;
+ struct qb_list_head items_list_head; /* List of process_info */
+ struct qb_list_head *current_pointer;
+};
+
+DECLARE_HDB_DATABASE(cpg_iteration_handle_t_db,NULL);
+
+QB_LIST_DECLARE (cpg_pd_list_head);
+
+static unsigned int my_member_list[PROCESSOR_COUNT_MAX];
+
+static unsigned int my_member_list_entries;
+
+static unsigned int my_old_member_list[PROCESSOR_COUNT_MAX];
+
+static unsigned int my_old_member_list_entries = 0;
+
+static struct corosync_api_v1 *api = NULL;
+
+static enum cpg_sync_state my_sync_state = CPGSYNC_DOWNLIST;
+
+static mar_cpg_ring_id_t last_sync_ring_id;
+
+struct process_info {
+ unsigned int nodeid;
+ uint32_t pid;
+ mar_cpg_name_t group;
+ struct qb_list_head list; /* on the group_info members list */
+};
+QB_LIST_DECLARE (process_info_list_head);
+
+struct join_list_entry {
+ uint32_t pid;
+ mar_cpg_name_t group_name;
+};
+
+struct join_list_confchg_data {
+ mar_cpg_name_t cpg_group;
+ mar_cpg_address_t join_list[CPG_MEMBERS_MAX];
+ int join_list_entries;
+};
+
+/*
+ * Service Interfaces required by service_message_handler struct
+ */
+static char *cpg_exec_init_fn (struct corosync_api_v1 *);
+
+static int cpg_lib_init_fn (void *conn);
+
+static int cpg_lib_exit_fn (void *conn);
+
+static void message_handler_req_exec_cpg_procjoin (
+ const void *message,
+ unsigned int nodeid);
+
+static void message_handler_req_exec_cpg_procleave (
+ const void *message,
+ unsigned int nodeid);
+
+static void message_handler_req_exec_cpg_joinlist (
+ const void *message,
+ unsigned int nodeid);
+
+static void message_handler_req_exec_cpg_mcast (
+ const void *message,
+ unsigned int nodeid);
+
+static void message_handler_req_exec_cpg_partial_mcast (
+ const void *message,
+ unsigned int nodeid);
+
+static void message_handler_req_exec_cpg_downlist_old (
+ const void *message,
+ unsigned int nodeid);
+
+static void message_handler_req_exec_cpg_downlist (
+ const void *message,
+ unsigned int nodeid);
+
+static void exec_cpg_procjoin_endian_convert (void *msg);
+
+static void exec_cpg_joinlist_endian_convert (void *msg);
+
+static void exec_cpg_mcast_endian_convert (void *msg);
+
+static void exec_cpg_partial_mcast_endian_convert (void *msg);
+
+static void exec_cpg_downlist_endian_convert_old (void *msg);
+
+static void exec_cpg_downlist_endian_convert (void *msg);
+
+static void message_handler_req_lib_cpg_join (void *conn, const void *message);
+
+static void message_handler_req_lib_cpg_leave (void *conn, const void *message);
+
+static void message_handler_req_lib_cpg_finalize (void *conn, const void *message);
+
+static void message_handler_req_lib_cpg_mcast (void *conn, const void *message);
+
+static void message_handler_req_lib_cpg_partial_mcast (void *conn, const void *message);
+
+static void message_handler_req_lib_cpg_membership (void *conn,
+ const void *message);
+
+static void message_handler_req_lib_cpg_local_get (void *conn,
+ const void *message);
+
+static void message_handler_req_lib_cpg_iteration_initialize (
+ void *conn,
+ const void *message);
+
+static void message_handler_req_lib_cpg_iteration_next (
+ void *conn,
+ const void *message);
+
+static void message_handler_req_lib_cpg_iteration_finalize (
+ void *conn,
+ const void *message);
+
+static void message_handler_req_lib_cpg_zc_alloc (
+ void *conn,
+ const void *message);
+
+static void message_handler_req_lib_cpg_zc_free (
+ void *conn,
+ const void *message);
+
+static void message_handler_req_lib_cpg_zc_execute (
+ void *conn,
+ const void *message);
+
+static int cpg_node_joinleave_send (unsigned int pid, const mar_cpg_name_t *group_name, int fn, int reason);
+
+static int cpg_exec_send_downlist(void);
+
+static int cpg_exec_send_joinlist(void);
+
+static void downlist_inform_clients (void);
+
+static void joinlist_inform_clients (void);
+
+static void joinlist_messages_delete (void);
+
+static void cpg_sync_init (
+ const unsigned int *trans_list,
+ size_t trans_list_entries,
+ const unsigned int *member_list,
+ size_t member_list_entries,
+ const struct memb_ring_id *ring_id);
+
+static int cpg_sync_process (void);
+
+static void cpg_sync_activate (void);
+
+static void cpg_sync_abort (void);
+
+static void do_proc_join(
+ const mar_cpg_name_t *name,
+ uint32_t pid,
+ unsigned int nodeid,
+ int reason,
+ qb_map_t *group_notify_map);
+
+static void do_proc_leave(
+ const mar_cpg_name_t *name,
+ uint32_t pid,
+ unsigned int nodeid,
+ int reason);
+
+static int notify_lib_totem_membership (
+ void *conn,
+ int member_list_entries,
+ const unsigned int *member_list);
+
+static inline int zcb_all_free (
+ struct cpg_pd *cpd);
+
+static char *cpg_print_group_name (
+ const mar_cpg_name_t *group);
+
+/*
+ * Library Handler Definition
+ */
+static struct corosync_lib_handler cpg_lib_engine[] =
+{
+ { /* 0 - MESSAGE_REQ_CPG_JOIN */
+ .lib_handler_fn = message_handler_req_lib_cpg_join,
+ .flow_control = CS_LIB_FLOW_CONTROL_REQUIRED
+ },
+ { /* 1 - MESSAGE_REQ_CPG_LEAVE */
+ .lib_handler_fn = message_handler_req_lib_cpg_leave,
+ .flow_control = CS_LIB_FLOW_CONTROL_REQUIRED
+ },
+ { /* 2 - MESSAGE_REQ_CPG_MCAST */
+ .lib_handler_fn = message_handler_req_lib_cpg_mcast,
+ .flow_control = CS_LIB_FLOW_CONTROL_REQUIRED
+ },
+ { /* 3 - MESSAGE_REQ_CPG_MEMBERSHIP */
+ .lib_handler_fn = message_handler_req_lib_cpg_membership,
+ .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED
+ },
+ { /* 4 - MESSAGE_REQ_CPG_LOCAL_GET */
+ .lib_handler_fn = message_handler_req_lib_cpg_local_get,
+ .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED
+ },
+ { /* 5 - MESSAGE_REQ_CPG_ITERATIONINITIALIZE */
+ .lib_handler_fn = message_handler_req_lib_cpg_iteration_initialize,
+ .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED
+ },
+ { /* 6 - MESSAGE_REQ_CPG_ITERATIONNEXT */
+ .lib_handler_fn = message_handler_req_lib_cpg_iteration_next,
+ .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED
+ },
+ { /* 7 - MESSAGE_REQ_CPG_ITERATIONFINALIZE */
+ .lib_handler_fn = message_handler_req_lib_cpg_iteration_finalize,
+ .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED
+ },
+ { /* 8 - MESSAGE_REQ_CPG_FINALIZE */
+ .lib_handler_fn = message_handler_req_lib_cpg_finalize,
+ .flow_control = CS_LIB_FLOW_CONTROL_REQUIRED
+ },
+ { /* 9 */
+ .lib_handler_fn = message_handler_req_lib_cpg_zc_alloc,
+ .flow_control = CS_LIB_FLOW_CONTROL_REQUIRED
+ },
+ { /* 10 */
+ .lib_handler_fn = message_handler_req_lib_cpg_zc_free,
+ .flow_control = CS_LIB_FLOW_CONTROL_REQUIRED
+ },
+ { /* 11 */
+ .lib_handler_fn = message_handler_req_lib_cpg_zc_execute,
+ .flow_control = CS_LIB_FLOW_CONTROL_REQUIRED
+ },
+ { /* 12 */
+ .lib_handler_fn = message_handler_req_lib_cpg_partial_mcast,
+ .flow_control = CS_LIB_FLOW_CONTROL_REQUIRED
+ },
+
+};
+
+static struct corosync_exec_handler cpg_exec_engine[] =
+{
+ { /* 0 - MESSAGE_REQ_EXEC_CPG_PROCJOIN */
+ .exec_handler_fn = message_handler_req_exec_cpg_procjoin,
+ .exec_endian_convert_fn = exec_cpg_procjoin_endian_convert
+ },
+ { /* 1 - MESSAGE_REQ_EXEC_CPG_PROCLEAVE */
+ .exec_handler_fn = message_handler_req_exec_cpg_procleave,
+ .exec_endian_convert_fn = exec_cpg_procjoin_endian_convert
+ },
+ { /* 2 - MESSAGE_REQ_EXEC_CPG_JOINLIST */
+ .exec_handler_fn = message_handler_req_exec_cpg_joinlist,
+ .exec_endian_convert_fn = exec_cpg_joinlist_endian_convert
+ },
+ { /* 3 - MESSAGE_REQ_EXEC_CPG_MCAST */
+ .exec_handler_fn = message_handler_req_exec_cpg_mcast,
+ .exec_endian_convert_fn = exec_cpg_mcast_endian_convert
+ },
+ { /* 4 - MESSAGE_REQ_EXEC_CPG_DOWNLIST_OLD */
+ .exec_handler_fn = message_handler_req_exec_cpg_downlist_old,
+ .exec_endian_convert_fn = exec_cpg_downlist_endian_convert_old
+ },
+ { /* 5 - MESSAGE_REQ_EXEC_CPG_DOWNLIST */
+ .exec_handler_fn = message_handler_req_exec_cpg_downlist,
+ .exec_endian_convert_fn = exec_cpg_downlist_endian_convert
+ },
+ { /* 6 - MESSAGE_REQ_EXEC_CPG_PARTIAL_MCAST */
+ .exec_handler_fn = message_handler_req_exec_cpg_partial_mcast,
+ .exec_endian_convert_fn = exec_cpg_partial_mcast_endian_convert
+ },
+};
+
+struct corosync_service_engine cpg_service_engine = {
+ .name = "corosync cluster closed process group service v1.01",
+ .id = CPG_SERVICE,
+ .priority = 1,
+ .private_data_size = sizeof (struct cpg_pd),
+ .flow_control = CS_LIB_FLOW_CONTROL_REQUIRED,
+ .allow_inquorate = CS_LIB_ALLOW_INQUORATE,
+ .lib_init_fn = cpg_lib_init_fn,
+ .lib_exit_fn = cpg_lib_exit_fn,
+ .lib_engine = cpg_lib_engine,
+ .lib_engine_count = sizeof (cpg_lib_engine) / sizeof (struct corosync_lib_handler),
+ .exec_init_fn = cpg_exec_init_fn,
+ .exec_dump_fn = NULL,
+ .exec_engine = cpg_exec_engine,
+ .exec_engine_count = sizeof (cpg_exec_engine) / sizeof (struct corosync_exec_handler),
+ .sync_init = cpg_sync_init,
+ .sync_process = cpg_sync_process,
+ .sync_activate = cpg_sync_activate,
+ .sync_abort = cpg_sync_abort
+};
+
+struct corosync_service_engine *cpg_get_service_engine_ver0 (void)
+{
+ return (&cpg_service_engine);
+}
+
+struct req_exec_cpg_procjoin {
+ struct qb_ipc_request_header header __attribute__((aligned(8)));
+ mar_cpg_name_t group_name __attribute__((aligned(8)));
+ mar_uint32_t pid __attribute__((aligned(8)));
+ mar_uint32_t reason __attribute__((aligned(8)));
+};
+
+struct req_exec_cpg_mcast {
+ struct qb_ipc_request_header header __attribute__((aligned(8)));
+ mar_cpg_name_t group_name __attribute__((aligned(8)));
+ mar_uint32_t msglen __attribute__((aligned(8)));
+ mar_uint32_t pid __attribute__((aligned(8)));
+ mar_message_source_t source __attribute__((aligned(8)));
+ mar_uint8_t message[] __attribute__((aligned(8)));
+};
+
+struct req_exec_cpg_partial_mcast {
+ struct qb_ipc_request_header header __attribute__((aligned(8)));
+ mar_cpg_name_t group_name __attribute__((aligned(8)));
+ mar_uint32_t msglen __attribute__((aligned(8)));
+ mar_uint32_t fraglen __attribute__((aligned(8)));
+ mar_uint32_t pid __attribute__((aligned(8)));
+ mar_uint32_t type __attribute__((aligned(8)));
+ mar_message_source_t source __attribute__((aligned(8)));
+ mar_uint8_t message[] __attribute__((aligned(8)));
+};
+
+struct req_exec_cpg_downlist_old {
+ struct qb_ipc_request_header header __attribute__((aligned(8)));
+ mar_uint32_t left_nodes __attribute__((aligned(8)));
+ mar_uint32_t nodeids[PROCESSOR_COUNT_MAX] __attribute__((aligned(8)));
+};
+
+struct req_exec_cpg_downlist {
+ struct qb_ipc_request_header header __attribute__((aligned(8)));
+ /* merge decisions */
+ mar_uint32_t old_members __attribute__((aligned(8)));
+ /* downlist below */
+ mar_uint32_t left_nodes __attribute__((aligned(8)));
+ mar_uint32_t nodeids[PROCESSOR_COUNT_MAX] __attribute__((aligned(8)));
+};
+
+struct joinlist_msg {
+ mar_uint32_t sender_nodeid;
+ uint32_t pid;
+ mar_cpg_name_t group_name;
+ struct qb_list_head list;
+};
+
+static struct req_exec_cpg_downlist g_req_exec_cpg_downlist;
+
+/*
+ * Function print group name. It's not reentrant
+ */
+static char *cpg_print_group_name(const mar_cpg_name_t *group)
+{
+ static char res[CPG_MAX_NAME_LENGTH * 4 + 1];
+ int dest_pos = 0;
+ char c;
+ int i;
+
+ for (i = 0; i < group->length; i++) {
+ c = group->value[i];
+
+ if (c >= ' ' && c < 0x7f && c != '\\') {
+ res[dest_pos++] = c;
+ } else {
+ if (c == '\\') {
+ res[dest_pos++] = '\\';
+ res[dest_pos++] = '\\';
+ } else {
+ snprintf(res + dest_pos, sizeof(res) - dest_pos, "\\x%02X", c);
+ dest_pos += 4;
+ }
+ }
+ }
+ res[dest_pos] = 0;
+
+ return (res);
+}
+
+static void cpg_sync_init (
+ const unsigned int *trans_list,
+ size_t trans_list_entries,
+ const unsigned int *member_list,
+ size_t member_list_entries,
+ const struct memb_ring_id *ring_id)
+{
+ int entries;
+ int i, j;
+ int found;
+
+ my_sync_state = CPGSYNC_DOWNLIST;
+
+ memcpy (my_member_list, member_list, member_list_entries *
+ sizeof (unsigned int));
+ my_member_list_entries = member_list_entries;
+
+ last_sync_ring_id.nodeid = ring_id->nodeid;
+ last_sync_ring_id.seq = ring_id->seq;
+
+ entries = 0;
+ /*
+ * Determine list of nodeids for downlist message
+ */
+ for (i = 0; i < my_old_member_list_entries; i++) {
+ found = 0;
+ for (j = 0; j < trans_list_entries; j++) {
+ if (my_old_member_list[i] == trans_list[j]) {
+ found = 1;
+ break;
+ }
+ }
+ if (found == 0) {
+ g_req_exec_cpg_downlist.nodeids[entries++] =
+ my_old_member_list[i];
+ }
+ }
+ g_req_exec_cpg_downlist.left_nodes = entries;
+}
+
+static int cpg_sync_process (void)
+{
+ int res = -1;
+
+ if (my_sync_state == CPGSYNC_DOWNLIST) {
+ res = cpg_exec_send_downlist();
+ if (res == -1) {
+ return (-1);
+ }
+ my_sync_state = CPGSYNC_JOINLIST;
+ }
+ if (my_sync_state == CPGSYNC_JOINLIST) {
+ res = cpg_exec_send_joinlist();
+ }
+ return (res);
+}
+
+static void cpg_sync_activate (void)
+{
+ memcpy (my_old_member_list, my_member_list,
+ my_member_list_entries * sizeof (unsigned int));
+ my_old_member_list_entries = my_member_list_entries;
+
+ downlist_inform_clients ();
+
+ joinlist_inform_clients ();
+
+ joinlist_messages_delete ();
+
+ notify_lib_totem_membership (NULL, my_member_list_entries, my_member_list);
+}
+
+static void cpg_sync_abort (void)
+{
+
+ joinlist_messages_delete ();
+}
+
+static int notify_lib_totem_membership (
+ void *conn,
+ int member_list_entries,
+ const unsigned int *member_list)
+{
+ struct qb_list_head *iter;
+ char *buf;
+ int size;
+ struct res_lib_cpg_totem_confchg_callback *res;
+
+ size = sizeof(struct res_lib_cpg_totem_confchg_callback) +
+ sizeof(mar_uint32_t) * (member_list_entries);
+ buf = alloca(size);
+ if (!buf)
+ return CS_ERR_LIBRARY;
+
+ res = (struct res_lib_cpg_totem_confchg_callback *)buf;
+ res->member_list_entries = member_list_entries;
+ res->header.size = size;
+ res->header.id = MESSAGE_RES_CPG_TOTEM_CONFCHG_CALLBACK;
+ res->header.error = CS_OK;
+
+ memcpy (&res->ring_id, &last_sync_ring_id, sizeof (mar_cpg_ring_id_t));
+ memcpy (res->member_list, member_list, res->member_list_entries * sizeof (mar_uint32_t));
+
+ if (conn == NULL) {
+ qb_list_for_each(iter, &cpg_pd_list_head) {
+ struct cpg_pd *cpg_pd = qb_list_entry (iter, struct cpg_pd, list);
+ api->ipc_dispatch_send (cpg_pd->conn, buf, size);
+ }
+ } else {
+ api->ipc_dispatch_send (conn, buf, size);
+ }
+
+ return CS_OK;
+}
+
+/*
+ * Helper function for notify_lib_joinlist which prepares member_list using
+ * process_info_list with removed left_list items.
+ * member_list_entries - When not NULL it contains number of member_list entries
+ * member_list - When not NULL it is used as pointer to start of preallocated
+ * array of members. Pointer is adjusted to the end of array on
+ * exit.
+ */
+static void notify_lib_joinlist_fill_member_list(
+ const mar_cpg_name_t *group_name,
+ int left_list_entries,
+ const mar_cpg_address_t *left_list,
+ int *member_list_entries,
+ mar_cpg_address_t **member_list)
+{
+ struct qb_list_head *iter;
+ int i;
+
+ if (member_list_entries != NULL) {
+ *member_list_entries = 0;
+ }
+
+ qb_list_for_each(iter, &process_info_list_head) {
+ struct process_info *pi = qb_list_entry (iter, struct process_info, list);
+
+ if (mar_name_compare (&pi->group, group_name) == 0) {
+ int in_left_list = 0;
+
+ for (i = 0; i < left_list_entries; i++) {
+ if (left_list[i].nodeid == pi->nodeid && left_list[i].pid == pi->pid) {
+ in_left_list = 1;
+ break ;
+ }
+ }
+
+ if (!in_left_list) {
+ if (member_list_entries != NULL) {
+ (*member_list_entries)++;
+ }
+
+ if (member_list != NULL) {
+ (*member_list)->nodeid = pi->nodeid;
+ (*member_list)->pid = pi->pid;
+ (*member_list)->reason = CPG_REASON_UNDEFINED;
+ (*member_list)++;
+ }
+ }
+ }
+ }
+}
+
+static int notify_lib_joinlist(
+ const mar_cpg_name_t *group_name,
+ int joined_list_entries,
+ mar_cpg_address_t *joined_list,
+ int left_list_entries,
+ mar_cpg_address_t *left_list,
+ int id)
+{
+ int size;
+ char *buf;
+ struct qb_list_head *iter;
+ int member_list_entries;
+ struct res_lib_cpg_confchg_callback *res;
+ mar_cpg_address_t *retgi;
+ int i;
+
+ /*
+ * Find size of member_list (use process_info_list but remove items in left_list)
+ */
+ notify_lib_joinlist_fill_member_list(group_name, left_list_entries, left_list,
+ &member_list_entries, NULL);
+
+ size = sizeof(struct res_lib_cpg_confchg_callback) +
+ sizeof(mar_cpg_address_t) * (member_list_entries + left_list_entries + joined_list_entries);
+ buf = alloca(size);
+ if (!buf)
+ return CS_ERR_LIBRARY;
+
+ res = (struct res_lib_cpg_confchg_callback *)buf;
+ res->joined_list_entries = joined_list_entries;
+ res->left_list_entries = left_list_entries;
+ res->member_list_entries = member_list_entries;
+ retgi = res->member_list;
+ res->header.size = size;
+ res->header.id = id;
+ res->header.error = CS_OK;
+ memcpy(&res->group_name, group_name, sizeof(mar_cpg_name_t));
+
+ /*
+ * Fill res->memberlist. Use process_info_list but remove items in left_list.
+ */
+ notify_lib_joinlist_fill_member_list(group_name, left_list_entries, left_list,
+ NULL, &retgi);
+
+ /*
+ * Fill res->left_list
+ */
+ if (left_list_entries) {
+ memcpy (retgi, left_list, left_list_entries * sizeof(mar_cpg_address_t));
+ retgi += left_list_entries;
+ }
+
+ if (joined_list_entries) {
+ /*
+ * Fill res->joined_list
+ */
+ memcpy (retgi, joined_list, joined_list_entries * sizeof(mar_cpg_address_t));
+ retgi += joined_list_entries;
+
+ /*
+ * Update cpd_state for all local joined processes in group
+ */
+ for (i = 0; i < joined_list_entries; i++) {
+ if (joined_list[i].nodeid == api->totem_nodeid_get()) {
+ qb_list_for_each(iter, &cpg_pd_list_head) {
+ struct cpg_pd *cpd = qb_list_entry (iter, struct cpg_pd, list);
+ if (joined_list[i].pid == cpd->pid &&
+ mar_name_compare (&cpd->group_name, group_name) == 0) {
+ cpd->cpd_state = CPD_STATE_JOIN_COMPLETED;
+ }
+ }
+ }
+ }
+ }
+
+ /*
+ * Send notification to all ipc clients joined in group_name
+ */
+ qb_list_for_each(iter, &cpg_pd_list_head) {
+ struct cpg_pd *cpd = qb_list_entry (iter, struct cpg_pd, list);
+ if (mar_name_compare (&cpd->group_name, group_name) == 0) {
+ if (cpd->cpd_state == CPD_STATE_JOIN_COMPLETED ||
+ cpd->cpd_state == CPD_STATE_LEAVE_STARTED) {
+
+ api->ipc_dispatch_send (cpd->conn, buf, size);
+ cpd->transition_counter++;
+ }
+ }
+ }
+
+ if (left_list_entries) {
+ /*
+ * Zero internal cpd state for all local processes leaving group
+ * (this loop is not strictly needed because left_list always either
+ * contains exactly one process running on local node or more items
+ * but none of them is running on local node)
+ */
+ for (i = 0; i < joined_list_entries; i++) {
+ if (left_list[i].nodeid == api->totem_nodeid_get() &&
+ left_list[i].reason == CONFCHG_CPG_REASON_LEAVE) {
+ qb_list_for_each(iter, &cpg_pd_list_head) {
+ struct cpg_pd *cpd = qb_list_entry (iter, struct cpg_pd, list);
+ if (left_list[i].pid == cpd->pid &&
+ mar_name_compare (&cpd->group_name, group_name) == 0) {
+ cpd->pid = 0;
+ memset (&cpd->group_name, 0, sizeof(cpd->group_name));
+ cpd->cpd_state = CPD_STATE_UNJOINED;
+ }
+ }
+ }
+ }
+ }
+
+ /*
+ * Traverse thru cpds and send totem membership for cpd, where it is not send yet
+ */
+ qb_list_for_each(iter, &cpg_pd_list_head) {
+ struct cpg_pd *cpd = qb_list_entry (iter, struct cpg_pd, list);
+
+ if ((cpd->flags & CPG_MODEL_V1_DELIVER_INITIAL_TOTEM_CONF) && (cpd->initial_totem_conf_sent == 0)) {
+ cpd->initial_totem_conf_sent = 1;
+
+ notify_lib_totem_membership (cpd->conn, my_old_member_list_entries, my_old_member_list);
+ }
+ }
+
+ return CS_OK;
+}
+
+static void downlist_log(const char *msg, struct req_exec_cpg_downlist *dl)
+{
+ log_printf (LOG_DEBUG,
+ "%s: members(old:%d left:%d)",
+ msg,
+ dl->old_members,
+ dl->left_nodes);
+}
+
+static void downlist_inform_clients (void)
+{
+ struct qb_list_head *iter, *tmp_iter;
+ struct process_info *left_pi;
+ qb_map_t *group_map;
+ struct cpg_name cpg_group;
+ mar_cpg_name_t group;
+ struct confchg_data{
+ struct cpg_name cpg_group;
+ mar_cpg_address_t left_list[CPG_MEMBERS_MAX];
+ int left_list_entries;
+ struct qb_list_head list;
+ } *pcd;
+ qb_map_iter_t *miter;
+ int i, size;
+
+ downlist_log("my downlist", &g_req_exec_cpg_downlist);
+
+ group_map = qb_skiplist_create();
+
+ /*
+ * only the cpg groups included in left nodes should receive
+ * confchg event, so we will collect these cpg groups and
+ * relative left_lists here.
+ */
+ qb_list_for_each_safe(iter, tmp_iter, &process_info_list_head) {
+ struct process_info *pi = qb_list_entry(iter, struct process_info, list);
+
+ left_pi = NULL;
+ for (i = 0; i < g_req_exec_cpg_downlist.left_nodes; i++) {
+
+ if (pi->nodeid == g_req_exec_cpg_downlist.nodeids[i]) {
+ left_pi = pi;
+ break;
+ }
+ }
+
+ if (left_pi) {
+ marshall_from_mar_cpg_name_t(&cpg_group, &left_pi->group);
+ cpg_group.value[cpg_group.length] = 0;
+
+ pcd = (struct confchg_data *)qb_map_get(group_map, cpg_group.value);
+ if (pcd == NULL) {
+ pcd = (struct confchg_data *)calloc(1, sizeof(struct confchg_data));
+ memcpy(&pcd->cpg_group, &cpg_group, sizeof(struct cpg_name));
+ qb_map_put(group_map, pcd->cpg_group.value, pcd);
+ }
+ size = pcd->left_list_entries;
+ pcd->left_list[size].nodeid = left_pi->nodeid;
+ pcd->left_list[size].pid = left_pi->pid;
+ pcd->left_list[size].reason = CONFCHG_CPG_REASON_NODEDOWN;
+ pcd->left_list_entries++;
+ qb_list_del (&left_pi->list);
+ free (left_pi);
+ }
+ }
+
+ /* send only one confchg event per cpg group */
+ miter = qb_map_iter_create(group_map);
+ while (qb_map_iter_next(miter, (void **)&pcd)) {
+ marshall_to_mar_cpg_name_t(&group, &pcd->cpg_group);
+
+ log_printf (LOG_DEBUG, "left_list_entries:%d", pcd->left_list_entries);
+ for (i=0; i<pcd->left_list_entries; i++) {
+ log_printf (LOG_DEBUG, "left_list[%d] group:%s, ip:%s, pid:%d",
+ i, cpg_print_group_name(&group),
+ (char*)api->totem_ifaces_print(pcd->left_list[i].nodeid),
+ pcd->left_list[i].pid);
+ }
+
+ /* send confchg event */
+ notify_lib_joinlist(&group,
+ 0, NULL,
+ pcd->left_list_entries,
+ pcd->left_list,
+ MESSAGE_RES_CPG_CONFCHG_CALLBACK);
+
+ free(pcd);
+ }
+ qb_map_iter_free(miter);
+ qb_map_destroy(group_map);
+}
+
+/*
+ * Remove processes that might have left the group while we were suspended.
+ */
+static void joinlist_remove_zombie_pi_entries (void)
+{
+ struct qb_list_head *pi_iter, *tmp_iter;
+ struct qb_list_head *jl_iter;
+ struct process_info *pi;
+ struct joinlist_msg *stored_msg;
+ int found;
+
+ qb_list_for_each_safe(pi_iter, tmp_iter, &process_info_list_head) {
+ pi = qb_list_entry (pi_iter, struct process_info, list);
+
+ /*
+ * Ignore local node
+ */
+ if (pi->nodeid == api->totem_nodeid_get()) {
+ continue ;
+ }
+
+ /*
+ * Try to find message in joinlist messages
+ */
+ found = 0;
+ qb_list_for_each(jl_iter, &joinlist_messages_head) {
+ stored_msg = qb_list_entry(jl_iter, struct joinlist_msg, list);
+
+ if (stored_msg->sender_nodeid == api->totem_nodeid_get()) {
+ continue ;
+ }
+
+ if (pi->nodeid == stored_msg->sender_nodeid &&
+ pi->pid == stored_msg->pid &&
+ mar_name_compare (&pi->group, &stored_msg->group_name) == 0) {
+ found = 1;
+ break ;
+ }
+ }
+
+ if (!found) {
+ do_proc_leave(&pi->group, pi->pid, pi->nodeid, CONFCHG_CPG_REASON_PROCDOWN);
+ }
+ }
+}
+
+static void joinlist_inform_clients (void)
+{
+ struct joinlist_msg *stored_msg;
+ struct qb_list_head *iter;
+ unsigned int i;
+ qb_map_t *group_notify_map;
+ qb_map_iter_t *miter;
+ struct join_list_confchg_data *jld;
+
+ group_notify_map = qb_skiplist_create();
+
+ i = 0;
+ qb_list_for_each(iter, &joinlist_messages_head) {
+ stored_msg = qb_list_entry(iter, struct joinlist_msg, list);
+
+ log_printf (LOG_DEBUG, "joinlist_messages[%u] group:%s, ip:%s, pid:%d",
+ i++, cpg_print_group_name(&stored_msg->group_name),
+ (char*)api->totem_ifaces_print(stored_msg->sender_nodeid),
+ stored_msg->pid);
+
+ /* Ignore our own messages */
+ if (stored_msg->sender_nodeid == api->totem_nodeid_get()) {
+ continue ;
+ }
+
+ do_proc_join (&stored_msg->group_name, stored_msg->pid, stored_msg->sender_nodeid,
+ CONFCHG_CPG_REASON_NODEUP, group_notify_map);
+ }
+
+ miter = qb_map_iter_create(group_notify_map);
+ while (qb_map_iter_next(miter, (void **)&jld)) {
+ notify_lib_joinlist(&jld->cpg_group,
+ jld->join_list_entries, jld->join_list,
+ 0, NULL,
+ MESSAGE_RES_CPG_CONFCHG_CALLBACK);
+ free(jld);
+ }
+ qb_map_iter_free(miter);
+ qb_map_destroy(group_notify_map);
+
+ joinlist_remove_zombie_pi_entries ();
+}
+
+static void joinlist_messages_delete (void)
+{
+ struct joinlist_msg *stored_msg;
+ struct qb_list_head *iter, *tmp_iter;
+
+ qb_list_for_each_safe(iter, tmp_iter, &joinlist_messages_head) {
+ stored_msg = qb_list_entry(iter, struct joinlist_msg, list);
+ qb_list_del (&stored_msg->list);
+ free (stored_msg);
+ }
+ qb_list_init (&joinlist_messages_head);
+}
+
+static char *cpg_exec_init_fn (struct corosync_api_v1 *corosync_api)
+{
+ qb_list_init (&joinlist_messages_head);
+ api = corosync_api;
+ return (NULL);
+}
+
+static void cpg_iteration_instance_finalize (struct cpg_iteration_instance *cpg_iteration_instance)
+{
+ struct qb_list_head *iter, *tmp_iter;
+ struct process_info *pi;
+
+ qb_list_for_each_safe(iter, tmp_iter, &(cpg_iteration_instance->items_list_head)) {
+ pi = qb_list_entry (iter, struct process_info, list);
+ qb_list_del (&pi->list);
+ free (pi);
+ }
+
+ qb_list_del (&cpg_iteration_instance->list);
+ hdb_handle_destroy (&cpg_iteration_handle_t_db, cpg_iteration_instance->handle);
+}
+
+static void cpg_pd_finalize (struct cpg_pd *cpd)
+{
+ struct qb_list_head *iter, *tmp_iter;
+ struct cpg_iteration_instance *cpii;
+
+ zcb_all_free(cpd);
+ qb_list_for_each_safe(iter, tmp_iter, &(cpd->iteration_instance_list_head)) {
+ cpii = qb_list_entry (iter, struct cpg_iteration_instance, list);
+
+ cpg_iteration_instance_finalize (cpii);
+ }
+
+ qb_list_del (&cpd->list);
+}
+
+static int cpg_lib_exit_fn (void *conn)
+{
+ struct cpg_pd *cpd = (struct cpg_pd *)api->ipc_private_data_get (conn);
+
+ log_printf(LOGSYS_LEVEL_DEBUG, "exit_fn for conn=%p", conn);
+
+ if (cpd->group_name.length > 0 && cpd->cpd_state != CPD_STATE_LEAVE_STARTED) {
+ cpg_node_joinleave_send (cpd->pid, &cpd->group_name,
+ MESSAGE_REQ_EXEC_CPG_PROCLEAVE, CONFCHG_CPG_REASON_PROCDOWN);
+ }
+
+ cpg_pd_finalize (cpd);
+
+ api->ipc_refcnt_dec (conn);
+ return (0);
+}
+
+static int cpg_node_joinleave_send (unsigned int pid, const mar_cpg_name_t *group_name, int fn, int reason)
+{
+ struct req_exec_cpg_procjoin req_exec_cpg_procjoin;
+ struct iovec req_exec_cpg_iovec;
+ int result;
+
+ memset(&req_exec_cpg_procjoin, 0, sizeof(req_exec_cpg_procjoin));
+
+ memcpy(&req_exec_cpg_procjoin.group_name, group_name, sizeof(mar_cpg_name_t));
+ req_exec_cpg_procjoin.pid = pid;
+ req_exec_cpg_procjoin.reason = reason;
+
+ req_exec_cpg_procjoin.header.size = sizeof(req_exec_cpg_procjoin);
+ req_exec_cpg_procjoin.header.id = SERVICE_ID_MAKE(CPG_SERVICE, fn);
+
+ req_exec_cpg_iovec.iov_base = (char *)&req_exec_cpg_procjoin;
+ req_exec_cpg_iovec.iov_len = sizeof(req_exec_cpg_procjoin);
+
+ result = api->totem_mcast (&req_exec_cpg_iovec, 1, TOTEM_AGREED);
+
+ return (result);
+}
+
+/* Can byteswap join & leave messages */
+static void exec_cpg_procjoin_endian_convert (void *msg)
+{
+ struct req_exec_cpg_procjoin *req_exec_cpg_procjoin = msg;
+
+ req_exec_cpg_procjoin->pid = swab32(req_exec_cpg_procjoin->pid);
+ swab_mar_cpg_name_t (&req_exec_cpg_procjoin->group_name);
+ req_exec_cpg_procjoin->reason = swab32(req_exec_cpg_procjoin->reason);
+}
+
+static void exec_cpg_joinlist_endian_convert (void *msg_v)
+{
+ char *msg = msg_v;
+ struct qb_ipc_response_header *res = (struct qb_ipc_response_header *)msg;
+ struct join_list_entry *jle = (struct join_list_entry *)(msg + sizeof(struct qb_ipc_response_header));
+
+ swab_mar_int32_t (&res->size);
+
+ while ((const char*)jle < msg + res->size) {
+ jle->pid = swab32(jle->pid);
+ swab_mar_cpg_name_t (&jle->group_name);
+ jle++;
+ }
+}
+
+static void exec_cpg_downlist_endian_convert_old (void *msg)
+{
+}
+
+static void exec_cpg_downlist_endian_convert (void *msg)
+{
+ struct req_exec_cpg_downlist *req_exec_cpg_downlist = msg;
+ unsigned int i;
+
+ req_exec_cpg_downlist->left_nodes = swab32(req_exec_cpg_downlist->left_nodes);
+ req_exec_cpg_downlist->old_members = swab32(req_exec_cpg_downlist->old_members);
+
+ for (i = 0; i < req_exec_cpg_downlist->left_nodes; i++) {
+ req_exec_cpg_downlist->nodeids[i] = swab32(req_exec_cpg_downlist->nodeids[i]);
+ }
+}
+
+
+static void exec_cpg_mcast_endian_convert (void *msg)
+{
+ struct req_exec_cpg_mcast *req_exec_cpg_mcast = msg;
+
+ swab_coroipc_request_header_t (&req_exec_cpg_mcast->header);
+ swab_mar_cpg_name_t (&req_exec_cpg_mcast->group_name);
+ req_exec_cpg_mcast->pid = swab32(req_exec_cpg_mcast->pid);
+ req_exec_cpg_mcast->msglen = swab32(req_exec_cpg_mcast->msglen);
+ swab_mar_message_source_t (&req_exec_cpg_mcast->source);
+}
+
+static void exec_cpg_partial_mcast_endian_convert (void *msg)
+{
+ struct req_exec_cpg_partial_mcast *req_exec_cpg_mcast = msg;
+
+ swab_coroipc_request_header_t (&req_exec_cpg_mcast->header);
+ swab_mar_cpg_name_t (&req_exec_cpg_mcast->group_name);
+ req_exec_cpg_mcast->pid = swab32(req_exec_cpg_mcast->pid);
+ req_exec_cpg_mcast->msglen = swab32(req_exec_cpg_mcast->msglen);
+ req_exec_cpg_mcast->fraglen = swab32(req_exec_cpg_mcast->fraglen);
+ req_exec_cpg_mcast->type = swab32(req_exec_cpg_mcast->type);
+ swab_mar_message_source_t (&req_exec_cpg_mcast->source);
+}
+
+static struct process_info *process_info_find(const mar_cpg_name_t *group_name, uint32_t pid, unsigned int nodeid) {
+ struct qb_list_head *iter;
+
+ qb_list_for_each(iter, &process_info_list_head) {
+ struct process_info *pi = qb_list_entry (iter, struct process_info, list);
+
+ if (pi->pid == pid && pi->nodeid == nodeid &&
+ mar_name_compare (&pi->group, group_name) == 0) {
+ return pi;
+ }
+ }
+
+ return NULL;
+}
+
+static void do_proc_join(
+ const mar_cpg_name_t *name,
+ uint32_t pid,
+ unsigned int nodeid,
+ int reason,
+ qb_map_t *group_notify_map)
+{
+ struct process_info *pi;
+ struct process_info *pi_entry;
+ mar_cpg_address_t notify_info;
+ struct qb_list_head *list;
+ struct qb_list_head *list_to_add = NULL;
+ int size;
+
+ if (process_info_find (name, pid, nodeid) != NULL) {
+ return ;
+ }
+ pi = malloc (sizeof (struct process_info));
+ if (!pi) {
+ log_printf(LOGSYS_LEVEL_WARNING, "Unable to allocate process_info struct");
+ return;
+ }
+ pi->nodeid = nodeid;
+ pi->pid = pid;
+ memcpy(&pi->group, name, sizeof(*name));
+ qb_list_init(&pi->list);
+
+ /*
+ * Insert new process in sorted order so synchronization works properly
+ */
+ list_to_add = &process_info_list_head;
+ qb_list_for_each(list, &process_info_list_head) {
+ pi_entry = qb_list_entry(list, struct process_info, list);
+ if (pi_entry->nodeid > pi->nodeid ||
+ (pi_entry->nodeid == pi->nodeid && pi_entry->pid > pi->pid)) {
+
+ break;
+ }
+ list_to_add = list;
+ }
+ qb_list_add (&pi->list, list_to_add);
+
+ notify_info.pid = pi->pid;
+ notify_info.nodeid = nodeid;
+ notify_info.reason = reason;
+
+ if (group_notify_map == NULL) {
+ notify_lib_joinlist(&pi->group,
+ 1, &notify_info,
+ 0, NULL,
+ MESSAGE_RES_CPG_CONFCHG_CALLBACK);
+ } else {
+ struct join_list_confchg_data *jld = qb_map_get(group_notify_map, pi->group.value);
+ if (jld == NULL) {
+ jld = (struct join_list_confchg_data *)calloc(1, sizeof(struct join_list_confchg_data));
+ memcpy(&jld->cpg_group, &pi->group, sizeof(mar_cpg_name_t));
+ qb_map_put(group_notify_map, jld->cpg_group.value, jld);
+ }
+ size = jld->join_list_entries;
+ jld->join_list[size].nodeid = notify_info.nodeid;
+ jld->join_list[size].pid = notify_info.pid;
+ jld->join_list[size].reason = notify_info.reason;
+ jld->join_list_entries++;
+ }
+}
+
+static void do_proc_leave(
+ const mar_cpg_name_t *name,
+ uint32_t pid,
+ unsigned int nodeid,
+ int reason)
+{
+ struct process_info *pi;
+ struct qb_list_head *iter, *tmp_iter;
+ mar_cpg_address_t notify_info;
+
+ notify_info.pid = pid;
+ notify_info.nodeid = nodeid;
+ notify_info.reason = reason;
+
+ notify_lib_joinlist(name,
+ 0, NULL,
+ 1, &notify_info,
+ MESSAGE_RES_CPG_CONFCHG_CALLBACK);
+
+ qb_list_for_each_safe(iter, tmp_iter, &process_info_list_head) {
+ pi = qb_list_entry(iter, struct process_info, list);
+
+ if (pi->pid == pid && pi->nodeid == nodeid &&
+ mar_name_compare (&pi->group, name)==0) {
+ qb_list_del (&pi->list);
+ free (pi);
+ }
+ }
+}
+
+static void message_handler_req_exec_cpg_downlist_old (
+ const void *message,
+ unsigned int nodeid)
+{
+ log_printf (LOGSYS_LEVEL_DEBUG, "downlist OLD from node " CS_PRI_NODE_ID,
+ nodeid);
+}
+
+static void message_handler_req_exec_cpg_downlist(
+ const void *message,
+ unsigned int nodeid)
+{
+ const struct req_exec_cpg_downlist *req_exec_cpg_downlist = message;
+
+ log_printf (LOGSYS_LEVEL_DEBUG, "downlist left_list: %d received",
+ req_exec_cpg_downlist->left_nodes);
+}
+
+
+static void message_handler_req_exec_cpg_procjoin (
+ const void *message,
+ unsigned int nodeid)
+{
+ const struct req_exec_cpg_procjoin *req_exec_cpg_procjoin = message;
+
+ log_printf(LOGSYS_LEVEL_DEBUG, "got procjoin message from cluster node " CS_PRI_NODE_ID " (%s) for pid %u",
+ nodeid,
+ api->totem_ifaces_print(nodeid),
+ (unsigned int)req_exec_cpg_procjoin->pid);
+
+ do_proc_join (&req_exec_cpg_procjoin->group_name,
+ req_exec_cpg_procjoin->pid, nodeid,
+ CONFCHG_CPG_REASON_JOIN, NULL);
+}
+
+static void message_handler_req_exec_cpg_procleave (
+ const void *message,
+ unsigned int nodeid)
+{
+ const struct req_exec_cpg_procjoin *req_exec_cpg_procjoin = message;
+
+ log_printf(LOGSYS_LEVEL_DEBUG, "got procleave message from cluster node " CS_PRI_NODE_ID " (%s) for pid %u",
+ nodeid,
+ api->totem_ifaces_print(nodeid),
+ (unsigned int)req_exec_cpg_procjoin->pid);
+
+ do_proc_leave (&req_exec_cpg_procjoin->group_name,
+ req_exec_cpg_procjoin->pid, nodeid,
+ req_exec_cpg_procjoin->reason);
+}
+
+
+/* Got a proclist from another node */
+static void message_handler_req_exec_cpg_joinlist (
+ const void *message_v,
+ unsigned int nodeid)
+{
+ const char *message = message_v;
+ const struct qb_ipc_response_header *res = (const struct qb_ipc_response_header *)message;
+ const struct join_list_entry *jle = (const struct join_list_entry *)(message + sizeof(struct qb_ipc_response_header));
+ struct joinlist_msg *stored_msg;
+
+ log_printf(LOGSYS_LEVEL_DEBUG, "got joinlist message from node " CS_PRI_NODE_ID,
+ nodeid);
+
+ while ((const char*)jle < message + res->size) {
+ stored_msg = malloc (sizeof (struct joinlist_msg));
+ memset(stored_msg, 0, sizeof (struct joinlist_msg));
+ stored_msg->sender_nodeid = nodeid;
+ stored_msg->pid = jle->pid;
+ memcpy(&stored_msg->group_name, &jle->group_name, sizeof(mar_cpg_name_t));
+ qb_list_init (&stored_msg->list);
+ qb_list_add (&stored_msg->list, &joinlist_messages_head);
+ jle++;
+ }
+}
+
+static void message_handler_req_exec_cpg_mcast (
+ const void *message,
+ unsigned int nodeid)
+{
+ const struct req_exec_cpg_mcast *req_exec_cpg_mcast = message;
+ struct res_lib_cpg_deliver_callback res_lib_cpg_mcast;
+ int msglen = req_exec_cpg_mcast->msglen;
+ struct qb_list_head *iter, *pi_iter, *tmp_iter;
+ struct cpg_pd *cpd;
+ struct iovec iovec[2];
+ int known_node = 0;
+
+ res_lib_cpg_mcast.header.id = MESSAGE_RES_CPG_DELIVER_CALLBACK;
+ res_lib_cpg_mcast.header.size = sizeof(res_lib_cpg_mcast) + msglen;
+ res_lib_cpg_mcast.msglen = msglen;
+ res_lib_cpg_mcast.pid = req_exec_cpg_mcast->pid;
+ res_lib_cpg_mcast.nodeid = nodeid;
+
+ memcpy(&res_lib_cpg_mcast.group_name, &req_exec_cpg_mcast->group_name,
+ sizeof(mar_cpg_name_t));
+ iovec[0].iov_base = (void *)&res_lib_cpg_mcast;
+ iovec[0].iov_len = sizeof (res_lib_cpg_mcast);
+
+ iovec[1].iov_base = (char*)message+sizeof(*req_exec_cpg_mcast);
+ iovec[1].iov_len = msglen;
+
+ qb_list_for_each_safe(iter, tmp_iter, &cpg_pd_list_head) {
+ cpd = qb_list_entry(iter, struct cpg_pd, list);
+ if ((cpd->cpd_state == CPD_STATE_LEAVE_STARTED || cpd->cpd_state == CPD_STATE_JOIN_COMPLETED)
+ && (mar_name_compare (&cpd->group_name, &req_exec_cpg_mcast->group_name) == 0)) {
+
+ if (!known_node) {
+ /* Try to find, if we know the node */
+ qb_list_for_each(pi_iter, &process_info_list_head) {
+ struct process_info *pi = qb_list_entry (pi_iter, struct process_info, list);
+
+ if (pi->nodeid == nodeid &&
+ mar_name_compare (&pi->group, &req_exec_cpg_mcast->group_name) == 0) {
+ known_node = 1;
+ break;
+ }
+ }
+ }
+
+ if (!known_node) {
+ log_printf(LOGSYS_LEVEL_WARNING, "Unknown node -> we will not deliver message");
+ return ;
+ }
+
+ api->ipc_dispatch_iov_send (cpd->conn, iovec, 2);
+ }
+ }
+}
+
+static void message_handler_req_exec_cpg_partial_mcast (
+ const void *message,
+ unsigned int nodeid)
+{
+ const struct req_exec_cpg_partial_mcast *req_exec_cpg_mcast = message;
+ struct res_lib_cpg_partial_deliver_callback res_lib_cpg_mcast;
+ int msglen = req_exec_cpg_mcast->fraglen;
+ struct qb_list_head *iter, *pi_iter, *tmp_iter;
+ struct cpg_pd *cpd;
+ struct iovec iovec[2];
+ int known_node = 0;
+
+ log_printf(LOGSYS_LEVEL_DEBUG, "Got fragmented message from node " CS_PRI_NODE_ID ", size = %d bytes\n", nodeid, msglen);
+
+ res_lib_cpg_mcast.header.id = MESSAGE_RES_CPG_PARTIAL_DELIVER_CALLBACK;
+ res_lib_cpg_mcast.header.size = sizeof(res_lib_cpg_mcast) + msglen;
+ res_lib_cpg_mcast.fraglen = msglen;
+ res_lib_cpg_mcast.msglen = req_exec_cpg_mcast->msglen;
+ res_lib_cpg_mcast.pid = req_exec_cpg_mcast->pid;
+ res_lib_cpg_mcast.type = req_exec_cpg_mcast->type;
+ res_lib_cpg_mcast.nodeid = nodeid;
+
+ memcpy(&res_lib_cpg_mcast.group_name, &req_exec_cpg_mcast->group_name,
+ sizeof(mar_cpg_name_t));
+ iovec[0].iov_base = (void *)&res_lib_cpg_mcast;
+ iovec[0].iov_len = sizeof (res_lib_cpg_mcast);
+
+ iovec[1].iov_base = (char*)message+sizeof(*req_exec_cpg_mcast);
+ iovec[1].iov_len = msglen;
+
+ qb_list_for_each_safe(iter, tmp_iter, &cpg_pd_list_head) {
+ cpd = qb_list_entry(iter, struct cpg_pd, list);
+
+ if ((cpd->cpd_state == CPD_STATE_LEAVE_STARTED || cpd->cpd_state == CPD_STATE_JOIN_COMPLETED)
+ && (mar_name_compare (&cpd->group_name, &req_exec_cpg_mcast->group_name) == 0)) {
+
+ if (!known_node) {
+ /* Try to find, if we know the node */
+ qb_list_for_each(pi_iter, &process_info_list_head) {
+ struct process_info *pi = qb_list_entry (pi_iter, struct process_info, list);
+
+ if (pi->nodeid == nodeid &&
+ mar_name_compare (&pi->group, &req_exec_cpg_mcast->group_name) == 0) {
+ known_node = 1;
+ break;
+ }
+ }
+ }
+
+ if (!known_node) {
+ log_printf(LOGSYS_LEVEL_WARNING, "Unknown node -> we will not deliver message");
+ return ;
+ }
+
+ api->ipc_dispatch_iov_send (cpd->conn, iovec, 2);
+ }
+ }
+}
+
+
+static int cpg_exec_send_downlist(void)
+{
+ struct iovec iov;
+
+ g_req_exec_cpg_downlist.header.id = SERVICE_ID_MAKE(CPG_SERVICE, MESSAGE_REQ_EXEC_CPG_DOWNLIST);
+ g_req_exec_cpg_downlist.header.size = sizeof(struct req_exec_cpg_downlist);
+
+ g_req_exec_cpg_downlist.old_members = my_old_member_list_entries;
+
+ iov.iov_base = (void *)&g_req_exec_cpg_downlist;
+ iov.iov_len = g_req_exec_cpg_downlist.header.size;
+
+ return (api->totem_mcast (&iov, 1, TOTEM_AGREED));
+}
+
+static int cpg_exec_send_joinlist(void)
+{
+ int count = 0;
+ struct qb_list_head *iter;
+ struct qb_ipc_response_header *res;
+ char *buf;
+ size_t buf_size;
+ struct join_list_entry *jle;
+ struct iovec req_exec_cpg_iovec;
+
+ qb_list_for_each(iter, &process_info_list_head) {
+ struct process_info *pi = qb_list_entry (iter, struct process_info, list);
+
+ if (pi->nodeid == api->totem_nodeid_get ()) {
+ count++;
+ }
+ }
+
+ /* Nothing to send */
+ if (!count)
+ return 0;
+
+ buf_size = sizeof(struct qb_ipc_response_header) + sizeof(struct join_list_entry) * count;
+ buf = alloca(buf_size);
+ if (!buf) {
+ log_printf(LOGSYS_LEVEL_WARNING, "Unable to allocate joinlist buffer");
+ return -1;
+ }
+ memset(buf, 0, buf_size);
+
+ jle = (struct join_list_entry *)(buf + sizeof(struct qb_ipc_response_header));
+ res = (struct qb_ipc_response_header *)buf;
+
+ qb_list_for_each(iter, &process_info_list_head) {
+ struct process_info *pi = qb_list_entry (iter, struct process_info, list);
+
+ if (pi->nodeid == api->totem_nodeid_get ()) {
+ memcpy (&jle->group_name, &pi->group, sizeof (mar_cpg_name_t));
+ jle->pid = pi->pid;
+ jle++;
+ }
+ }
+
+ res->id = SERVICE_ID_MAKE(CPG_SERVICE, MESSAGE_REQ_EXEC_CPG_JOINLIST);
+ res->size = sizeof(struct qb_ipc_response_header)+sizeof(struct join_list_entry) * count;
+
+ req_exec_cpg_iovec.iov_base = buf;
+ req_exec_cpg_iovec.iov_len = res->size;
+
+ return (api->totem_mcast (&req_exec_cpg_iovec, 1, TOTEM_AGREED));
+}
+
+static int cpg_lib_init_fn (void *conn)
+{
+ struct cpg_pd *cpd = (struct cpg_pd *)api->ipc_private_data_get (conn);
+ memset (cpd, 0, sizeof(struct cpg_pd));
+ cpd->conn = conn;
+ qb_list_add (&cpd->list, &cpg_pd_list_head);
+
+ qb_list_init (&cpd->iteration_instance_list_head);
+ qb_list_init (&cpd->zcb_mapped_list_head);
+
+ api->ipc_refcnt_inc (conn);
+ log_printf(LOGSYS_LEVEL_DEBUG, "lib_init_fn: conn=%p, cpd=%p", conn, cpd);
+ return (0);
+}
+
+/* Join message from the library */
+static void message_handler_req_lib_cpg_join (void *conn, const void *message)
+{
+ const struct req_lib_cpg_join *req_lib_cpg_join = message;
+ struct cpg_pd *cpd = (struct cpg_pd *)api->ipc_private_data_get (conn);
+ struct res_lib_cpg_join res_lib_cpg_join;
+ cs_error_t error = CS_OK;
+ struct qb_list_head *iter;
+
+ /* Test, if we don't have same pid and group name joined */
+ qb_list_for_each(iter, &cpg_pd_list_head) {
+ struct cpg_pd *cpd_item = qb_list_entry (iter, struct cpg_pd, list);
+
+ if (cpd_item->pid == req_lib_cpg_join->pid &&
+ mar_name_compare(&req_lib_cpg_join->group_name, &cpd_item->group_name) == 0) {
+
+ /* We have same pid and group name joined -> return error */
+ error = CS_ERR_EXIST;
+ goto response_send;
+ }
+ }
+
+ /*
+ * Same check must be done in process info list, because there may be not yet delivered
+ * leave of client.
+ */
+ qb_list_for_each(iter, &process_info_list_head) {
+ struct process_info *pi = qb_list_entry (iter, struct process_info, list);
+
+ if (pi->nodeid == api->totem_nodeid_get () && pi->pid == req_lib_cpg_join->pid &&
+ mar_name_compare(&req_lib_cpg_join->group_name, &pi->group) == 0) {
+ /* We have same pid and group name joined -> return error */
+ error = CS_ERR_TRY_AGAIN;
+ goto response_send;
+ }
+ }
+
+ if (req_lib_cpg_join->group_name.length > CPG_MAX_NAME_LENGTH) {
+ error = CS_ERR_NAME_TOO_LONG;
+ goto response_send;
+ }
+
+ switch (cpd->cpd_state) {
+ case CPD_STATE_UNJOINED:
+ error = CS_OK;
+ cpd->cpd_state = CPD_STATE_JOIN_STARTED;
+ cpd->pid = req_lib_cpg_join->pid;
+ cpd->flags = req_lib_cpg_join->flags;
+ memcpy (&cpd->group_name, &req_lib_cpg_join->group_name,
+ sizeof (cpd->group_name));
+
+ cpg_node_joinleave_send (req_lib_cpg_join->pid,
+ &req_lib_cpg_join->group_name,
+ MESSAGE_REQ_EXEC_CPG_PROCJOIN, CONFCHG_CPG_REASON_JOIN);
+ break;
+ case CPD_STATE_LEAVE_STARTED:
+ error = CS_ERR_BUSY;
+ break;
+ case CPD_STATE_JOIN_STARTED:
+ error = CS_ERR_EXIST;
+ break;
+ case CPD_STATE_JOIN_COMPLETED:
+ error = CS_ERR_EXIST;
+ break;
+ }
+
+response_send:
+ res_lib_cpg_join.header.size = sizeof(res_lib_cpg_join);
+ res_lib_cpg_join.header.id = MESSAGE_RES_CPG_JOIN;
+ res_lib_cpg_join.header.error = error;
+ api->ipc_response_send (conn, &res_lib_cpg_join, sizeof(res_lib_cpg_join));
+}
+
+/* Leave message from the library */
+static void message_handler_req_lib_cpg_leave (void *conn, const void *message)
+{
+ struct res_lib_cpg_leave res_lib_cpg_leave;
+ cs_error_t error = CS_OK;
+ struct req_lib_cpg_leave *req_lib_cpg_leave = (struct req_lib_cpg_leave *)message;
+ struct cpg_pd *cpd = (struct cpg_pd *)api->ipc_private_data_get (conn);
+
+ log_printf(LOGSYS_LEVEL_DEBUG, "got leave request on %p", conn);
+
+ switch (cpd->cpd_state) {
+ case CPD_STATE_UNJOINED:
+ error = CS_ERR_NOT_EXIST;
+ break;
+ case CPD_STATE_LEAVE_STARTED:
+ error = CS_ERR_NOT_EXIST;
+ break;
+ case CPD_STATE_JOIN_STARTED:
+ error = CS_ERR_BUSY;
+ break;
+ case CPD_STATE_JOIN_COMPLETED:
+ error = CS_OK;
+ cpd->cpd_state = CPD_STATE_LEAVE_STARTED;
+ cpg_node_joinleave_send (req_lib_cpg_leave->pid,
+ &req_lib_cpg_leave->group_name,
+ MESSAGE_REQ_EXEC_CPG_PROCLEAVE,
+ CONFCHG_CPG_REASON_LEAVE);
+ break;
+ }
+
+ /* send return */
+ res_lib_cpg_leave.header.size = sizeof(res_lib_cpg_leave);
+ res_lib_cpg_leave.header.id = MESSAGE_RES_CPG_LEAVE;
+ res_lib_cpg_leave.header.error = error;
+ api->ipc_response_send(conn, &res_lib_cpg_leave, sizeof(res_lib_cpg_leave));
+}
+
+/* Finalize message from library */
+static void message_handler_req_lib_cpg_finalize (
+ void *conn,
+ const void *message)
+{
+ struct cpg_pd *cpd = (struct cpg_pd *)api->ipc_private_data_get (conn);
+ struct res_lib_cpg_finalize res_lib_cpg_finalize;
+ cs_error_t error = CS_OK;
+
+ log_printf (LOGSYS_LEVEL_DEBUG, "cpg finalize for conn=%p", conn);
+
+ /*
+ * We will just remove cpd from list. After this call, connection will be
+ * closed on lib side, and cpg_lib_exit_fn will be called
+ */
+ qb_list_del (&cpd->list);
+ qb_list_init (&cpd->list);
+
+ res_lib_cpg_finalize.header.size = sizeof (res_lib_cpg_finalize);
+ res_lib_cpg_finalize.header.id = MESSAGE_RES_CPG_FINALIZE;
+ res_lib_cpg_finalize.header.error = error;
+
+ api->ipc_response_send (conn, &res_lib_cpg_finalize,
+ sizeof (res_lib_cpg_finalize));
+}
+
+static int
+memory_map (
+ const char *path,
+ size_t bytes,
+ void **buf)
+{
+ int32_t fd;
+ void *addr;
+ int32_t res;
+
+ fd = open (path, O_RDWR, 0600);
+
+ unlink (path);
+
+ if (fd == -1) {
+ return (-1);
+ }
+
+ res = ftruncate (fd, bytes);
+ if (res == -1) {
+ goto error_close_unlink;
+ }
+
+ addr = mmap (NULL, bytes, PROT_READ | PROT_WRITE,
+ MAP_SHARED, fd, 0);
+
+ if (addr == MAP_FAILED) {
+ goto error_close_unlink;
+ }
+#ifdef MADV_NOSYNC
+ madvise(addr, bytes, MADV_NOSYNC);
+#endif
+
+ res = close (fd);
+ if (res) {
+ munmap (addr, bytes);
+ return (-1);
+ }
+ *buf = addr;
+ return (0);
+
+error_close_unlink:
+ close (fd);
+ unlink(path);
+ return -1;
+}
+
+static inline int zcb_alloc (
+ struct cpg_pd *cpd,
+ const char *path_to_file,
+ size_t size,
+ void **addr)
+{
+ struct zcb_mapped *zcb_mapped;
+ unsigned int res;
+
+ zcb_mapped = malloc (sizeof (struct zcb_mapped));
+ if (zcb_mapped == NULL) {
+ return (-1);
+ }
+
+ res = memory_map (
+ path_to_file,
+ size,
+ addr);
+ if (res == -1) {
+ free (zcb_mapped);
+ return (-1);
+ }
+
+ qb_list_init (&zcb_mapped->list);
+ zcb_mapped->addr = *addr;
+ zcb_mapped->size = size;
+ qb_list_add_tail (&zcb_mapped->list, &cpd->zcb_mapped_list_head);
+ return (0);
+}
+
+
+static inline int zcb_free (struct zcb_mapped *zcb_mapped)
+{
+ unsigned int res;
+
+ res = munmap (zcb_mapped->addr, zcb_mapped->size);
+ qb_list_del (&zcb_mapped->list);
+ free (zcb_mapped);
+ return (res);
+}
+
+static inline int zcb_by_addr_free (struct cpg_pd *cpd, void *addr)
+{
+ struct qb_list_head *list, *tmp_iter;
+ struct zcb_mapped *zcb_mapped;
+ unsigned int res = 0;
+
+ qb_list_for_each_safe(list, tmp_iter, &(cpd->zcb_mapped_list_head)) {
+ zcb_mapped = qb_list_entry (list, struct zcb_mapped, list);
+
+ if (zcb_mapped->addr == addr) {
+ res = zcb_free (zcb_mapped);
+ break;
+ }
+
+ }
+ return (res);
+}
+
+static inline int zcb_all_free (
+ struct cpg_pd *cpd)
+{
+ struct qb_list_head *list, *tmp_iter;
+ struct zcb_mapped *zcb_mapped;
+
+ qb_list_for_each_safe(list, tmp_iter, &(cpd->zcb_mapped_list_head)) {
+ zcb_mapped = qb_list_entry (list, struct zcb_mapped, list);
+
+ zcb_free (zcb_mapped);
+ }
+ return (0);
+}
+
+union u {
+ uint64_t server_addr;
+ void *server_ptr;
+};
+
+static uint64_t void2serveraddr (void *server_ptr)
+{
+ union u u;
+
+ u.server_ptr = server_ptr;
+ return (u.server_addr);
+}
+
+static void *serveraddr2void (uint64_t server_addr)
+{
+ union u u;
+
+ u.server_addr = server_addr;
+ return (u.server_ptr);
+};
+
+static void message_handler_req_lib_cpg_zc_alloc (
+ void *conn,
+ const void *message)
+{
+ mar_req_coroipcc_zc_alloc_t *hdr = (mar_req_coroipcc_zc_alloc_t *)message;
+ struct qb_ipc_response_header res_header;
+ void *addr = NULL;
+ struct coroipcs_zc_header *zc_header;
+ unsigned int res;
+ struct cpg_pd *cpd = (struct cpg_pd *)api->ipc_private_data_get (conn);
+
+ log_printf(LOGSYS_LEVEL_DEBUG, "path: %s", hdr->path_to_file);
+
+ res = zcb_alloc (cpd, hdr->path_to_file, hdr->map_size,
+ &addr);
+ assert(res == 0);
+
+ zc_header = (struct coroipcs_zc_header *)addr;
+ zc_header->server_address = void2serveraddr(addr);
+
+ res_header.size = sizeof (struct qb_ipc_response_header);
+ res_header.id = 0;
+ api->ipc_response_send (conn,
+ &res_header,
+ res_header.size);
+}
+
+static void message_handler_req_lib_cpg_zc_free (
+ void *conn,
+ const void *message)
+{
+ mar_req_coroipcc_zc_free_t *hdr = (mar_req_coroipcc_zc_free_t *)message;
+ struct qb_ipc_response_header res_header;
+ void *addr = NULL;
+ struct cpg_pd *cpd = (struct cpg_pd *)api->ipc_private_data_get (conn);
+
+ log_printf(LOGSYS_LEVEL_DEBUG, " free'ing");
+
+ addr = serveraddr2void (hdr->server_address);
+
+ zcb_by_addr_free (cpd, addr);
+
+ res_header.size = sizeof (struct qb_ipc_response_header);
+ res_header.id = 0;
+ api->ipc_response_send (
+ conn, &res_header,
+ res_header.size);
+}
+
+/* Fragmented mcast message from the library */
+static void message_handler_req_lib_cpg_partial_mcast (void *conn, const void *message)
+{
+ const struct req_lib_cpg_partial_mcast *req_lib_cpg_mcast = message;
+ struct cpg_pd *cpd = (struct cpg_pd *)api->ipc_private_data_get (conn);
+ mar_cpg_name_t group_name = cpd->group_name;
+
+ struct iovec req_exec_cpg_iovec[2];
+ struct req_exec_cpg_partial_mcast req_exec_cpg_mcast;
+ struct res_lib_cpg_partial_send res_lib_cpg_partial_send;
+ int msglen = req_lib_cpg_mcast->fraglen;
+ int result;
+ cs_error_t error = CS_ERR_NOT_EXIST;
+
+ log_printf(LOGSYS_LEVEL_TRACE, "got fragmented mcast request on %p", conn);
+ log_printf(LOGSYS_LEVEL_DEBUG, "Sending fragmented message size = %d bytes\n", msglen);
+
+ switch (cpd->cpd_state) {
+ case CPD_STATE_UNJOINED:
+ error = CS_ERR_NOT_EXIST;
+ break;
+ case CPD_STATE_LEAVE_STARTED:
+ error = CS_ERR_NOT_EXIST;
+ break;
+ case CPD_STATE_JOIN_STARTED:
+ error = CS_OK;
+ break;
+ case CPD_STATE_JOIN_COMPLETED:
+ error = CS_OK;
+ break;
+ }
+
+ res_lib_cpg_partial_send.header.size = sizeof(res_lib_cpg_partial_send);
+ res_lib_cpg_partial_send.header.id = MESSAGE_RES_CPG_PARTIAL_SEND;
+
+ if (req_lib_cpg_mcast->type == LIBCPG_PARTIAL_FIRST) {
+ cpd->initial_transition_counter = cpd->transition_counter;
+ }
+ if (cpd->transition_counter != cpd->initial_transition_counter) {
+ error = CS_ERR_INTERRUPT;
+ }
+
+ if (error == CS_OK) {
+ req_exec_cpg_mcast.header.size = sizeof(req_exec_cpg_mcast) + msglen;
+ req_exec_cpg_mcast.header.id = SERVICE_ID_MAKE(CPG_SERVICE,
+ MESSAGE_REQ_EXEC_CPG_PARTIAL_MCAST);
+ req_exec_cpg_mcast.pid = cpd->pid;
+ req_exec_cpg_mcast.msglen = req_lib_cpg_mcast->msglen;
+ req_exec_cpg_mcast.type = req_lib_cpg_mcast->type;
+ req_exec_cpg_mcast.fraglen = req_lib_cpg_mcast->fraglen;
+ api->ipc_source_set (&req_exec_cpg_mcast.source, conn);
+ memcpy(&req_exec_cpg_mcast.group_name, &group_name,
+ sizeof(mar_cpg_name_t));
+
+ req_exec_cpg_iovec[0].iov_base = (char *)&req_exec_cpg_mcast;
+ req_exec_cpg_iovec[0].iov_len = sizeof(req_exec_cpg_mcast);
+ req_exec_cpg_iovec[1].iov_base = (char *)&req_lib_cpg_mcast->message;
+ req_exec_cpg_iovec[1].iov_len = msglen;
+
+ result = api->totem_mcast (req_exec_cpg_iovec, 2, TOTEM_AGREED);
+ assert(result == 0);
+ } else {
+ log_printf(LOGSYS_LEVEL_ERROR, "*** %p can't mcast to group %s state:%d, error:%d",
+ conn, group_name.value, cpd->cpd_state, error);
+ }
+
+ res_lib_cpg_partial_send.header.error = error;
+ api->ipc_response_send (conn, &res_lib_cpg_partial_send,
+ sizeof (res_lib_cpg_partial_send));
+}
+
+/* Mcast message from the library */
+static void message_handler_req_lib_cpg_mcast (void *conn, const void *message)
+{
+ const struct req_lib_cpg_mcast *req_lib_cpg_mcast = message;
+ struct cpg_pd *cpd = (struct cpg_pd *)api->ipc_private_data_get (conn);
+ mar_cpg_name_t group_name = cpd->group_name;
+
+ struct iovec req_exec_cpg_iovec[2];
+ struct req_exec_cpg_mcast req_exec_cpg_mcast;
+ int msglen = req_lib_cpg_mcast->msglen;
+ int result;
+ cs_error_t error = CS_ERR_NOT_EXIST;
+
+ log_printf(LOGSYS_LEVEL_TRACE, "got mcast request on %p", conn);
+
+ switch (cpd->cpd_state) {
+ case CPD_STATE_UNJOINED:
+ error = CS_ERR_NOT_EXIST;
+ break;
+ case CPD_STATE_LEAVE_STARTED:
+ error = CS_ERR_NOT_EXIST;
+ break;
+ case CPD_STATE_JOIN_STARTED:
+ error = CS_OK;
+ break;
+ case CPD_STATE_JOIN_COMPLETED:
+ error = CS_OK;
+ break;
+ }
+
+ if (error == CS_OK) {
+ memset(&req_exec_cpg_mcast, 0, sizeof(req_exec_cpg_mcast));
+
+ req_exec_cpg_mcast.header.size = sizeof(req_exec_cpg_mcast) + msglen;
+ req_exec_cpg_mcast.header.id = SERVICE_ID_MAKE(CPG_SERVICE,
+ MESSAGE_REQ_EXEC_CPG_MCAST);
+ req_exec_cpg_mcast.pid = cpd->pid;
+ req_exec_cpg_mcast.msglen = msglen;
+ api->ipc_source_set (&req_exec_cpg_mcast.source, conn);
+ memcpy(&req_exec_cpg_mcast.group_name, &group_name,
+ sizeof(mar_cpg_name_t));
+
+ req_exec_cpg_iovec[0].iov_base = (char *)&req_exec_cpg_mcast;
+ req_exec_cpg_iovec[0].iov_len = sizeof(req_exec_cpg_mcast);
+ req_exec_cpg_iovec[1].iov_base = (char *)&req_lib_cpg_mcast->message;
+ req_exec_cpg_iovec[1].iov_len = msglen;
+
+ result = api->totem_mcast (req_exec_cpg_iovec, 2, TOTEM_AGREED);
+ assert(result == 0);
+ } else {
+ log_printf(LOGSYS_LEVEL_ERROR, "*** %p can't mcast to group %s state:%d, error:%d",
+ conn, group_name.value, cpd->cpd_state, error);
+ }
+}
+
+static void message_handler_req_lib_cpg_zc_execute (
+ void *conn,
+ const void *message)
+{
+ mar_req_coroipcc_zc_execute_t *hdr = (mar_req_coroipcc_zc_execute_t *)message;
+ struct qb_ipc_request_header *header;
+ struct res_lib_cpg_mcast res_lib_cpg_mcast;
+ struct cpg_pd *cpd = (struct cpg_pd *)api->ipc_private_data_get (conn);
+ struct iovec req_exec_cpg_iovec[2];
+ struct req_exec_cpg_mcast req_exec_cpg_mcast;
+ struct req_lib_cpg_mcast *req_lib_cpg_mcast;
+ int result;
+ cs_error_t error = CS_ERR_NOT_EXIST;
+
+ log_printf(LOGSYS_LEVEL_TRACE, "got ZC mcast request on %p", conn);
+
+ header = (struct qb_ipc_request_header *)(((char *)serveraddr2void(hdr->server_address) + sizeof (struct coroipcs_zc_header)));
+ req_lib_cpg_mcast = (struct req_lib_cpg_mcast *)header;
+
+ switch (cpd->cpd_state) {
+ case CPD_STATE_UNJOINED:
+ error = CS_ERR_NOT_EXIST;
+ break;
+ case CPD_STATE_LEAVE_STARTED:
+ error = CS_ERR_NOT_EXIST;
+ break;
+ case CPD_STATE_JOIN_STARTED:
+ error = CS_OK;
+ break;
+ case CPD_STATE_JOIN_COMPLETED:
+ error = CS_OK;
+ break;
+ }
+
+ res_lib_cpg_mcast.header.size = sizeof(res_lib_cpg_mcast);
+ res_lib_cpg_mcast.header.id = MESSAGE_RES_CPG_MCAST;
+ if (error == CS_OK) {
+ req_exec_cpg_mcast.header.size = sizeof(req_exec_cpg_mcast) + req_lib_cpg_mcast->msglen;
+ req_exec_cpg_mcast.header.id = SERVICE_ID_MAKE(CPG_SERVICE,
+ MESSAGE_REQ_EXEC_CPG_MCAST);
+ req_exec_cpg_mcast.pid = cpd->pid;
+ req_exec_cpg_mcast.msglen = req_lib_cpg_mcast->msglen;
+ api->ipc_source_set (&req_exec_cpg_mcast.source, conn);
+ memcpy(&req_exec_cpg_mcast.group_name, &cpd->group_name,
+ sizeof(mar_cpg_name_t));
+
+ req_exec_cpg_iovec[0].iov_base = (char *)&req_exec_cpg_mcast;
+ req_exec_cpg_iovec[0].iov_len = sizeof(req_exec_cpg_mcast);
+ req_exec_cpg_iovec[1].iov_base = (char *)header + sizeof(struct req_lib_cpg_mcast);
+ req_exec_cpg_iovec[1].iov_len = req_exec_cpg_mcast.msglen;
+
+ result = api->totem_mcast (req_exec_cpg_iovec, 2, TOTEM_AGREED);
+ if (result == 0) {
+ res_lib_cpg_mcast.header.error = CS_OK;
+ } else {
+ res_lib_cpg_mcast.header.error = CS_ERR_TRY_AGAIN;
+ }
+ } else {
+ res_lib_cpg_mcast.header.error = error;
+ }
+
+ api->ipc_response_send (conn, &res_lib_cpg_mcast,
+ sizeof (res_lib_cpg_mcast));
+
+}
+
+static void message_handler_req_lib_cpg_membership (void *conn,
+ const void *message)
+{
+ struct req_lib_cpg_membership_get *req_lib_cpg_membership_get =
+ (struct req_lib_cpg_membership_get *)message;
+ struct res_lib_cpg_membership_get res_lib_cpg_membership_get;
+ struct qb_list_head *iter;
+ int member_count = 0;
+
+ res_lib_cpg_membership_get.header.id = MESSAGE_RES_CPG_MEMBERSHIP;
+ res_lib_cpg_membership_get.header.error = CS_OK;
+ res_lib_cpg_membership_get.header.size =
+ sizeof (struct res_lib_cpg_membership_get);
+
+ qb_list_for_each(iter, &process_info_list_head) {
+ struct process_info *pi = qb_list_entry (iter, struct process_info, list);
+ if (mar_name_compare (&pi->group, &req_lib_cpg_membership_get->group_name) == 0) {
+ res_lib_cpg_membership_get.member_list[member_count].nodeid = pi->nodeid;
+ res_lib_cpg_membership_get.member_list[member_count].pid = pi->pid;
+ member_count += 1;
+ }
+ }
+ res_lib_cpg_membership_get.member_count = member_count;
+
+ api->ipc_response_send (conn, &res_lib_cpg_membership_get,
+ sizeof (res_lib_cpg_membership_get));
+}
+
+static void message_handler_req_lib_cpg_local_get (void *conn,
+ const void *message)
+{
+ struct res_lib_cpg_local_get res_lib_cpg_local_get;
+
+ res_lib_cpg_local_get.header.size = sizeof (res_lib_cpg_local_get);
+ res_lib_cpg_local_get.header.id = MESSAGE_RES_CPG_LOCAL_GET;
+ res_lib_cpg_local_get.header.error = CS_OK;
+ res_lib_cpg_local_get.local_nodeid = api->totem_nodeid_get ();
+
+ api->ipc_response_send (conn, &res_lib_cpg_local_get,
+ sizeof (res_lib_cpg_local_get));
+}
+
+static void message_handler_req_lib_cpg_iteration_initialize (
+ void *conn,
+ const void *message)
+{
+ const struct req_lib_cpg_iterationinitialize *req_lib_cpg_iterationinitialize = message;
+ struct cpg_pd *cpd = (struct cpg_pd *)api->ipc_private_data_get (conn);
+ hdb_handle_t cpg_iteration_handle = 0;
+ struct res_lib_cpg_iterationinitialize res_lib_cpg_iterationinitialize;
+ struct qb_list_head *iter, *iter2;
+ struct cpg_iteration_instance *cpg_iteration_instance;
+ cs_error_t error = CS_OK;
+ int res;
+
+ log_printf (LOGSYS_LEVEL_DEBUG, "cpg iteration initialize");
+
+ /* Because between calling this function and *next can be some operations which will
+ * change list, we must do full copy.
+ */
+
+ /*
+ * Create new iteration instance
+ */
+ res = hdb_handle_create (&cpg_iteration_handle_t_db, sizeof (struct cpg_iteration_instance),
+ &cpg_iteration_handle);
+
+ if (res != 0) {
+ error = CS_ERR_NO_MEMORY;
+ goto response_send;
+ }
+
+ res = hdb_handle_get (&cpg_iteration_handle_t_db, cpg_iteration_handle, (void *)&cpg_iteration_instance);
+
+ if (res != 0) {
+ error = CS_ERR_BAD_HANDLE;
+ goto error_destroy;
+ }
+
+ qb_list_init (&cpg_iteration_instance->items_list_head);
+ cpg_iteration_instance->handle = cpg_iteration_handle;
+
+ /*
+ * Create copy of process_info list "grouped by" group name
+ */
+ qb_list_for_each(iter, &process_info_list_head) {
+ struct process_info *pi = qb_list_entry (iter, struct process_info, list);
+ struct process_info *new_pi;
+
+ if (req_lib_cpg_iterationinitialize->iteration_type == CPG_ITERATION_NAME_ONLY) {
+ /*
+ * Try to find processed group name in our list new list
+ */
+ int found = 0;
+
+ qb_list_for_each(iter2, &(cpg_iteration_instance->items_list_head)) {
+ struct process_info *pi2 = qb_list_entry (iter2, struct process_info, list);
+
+ if (mar_name_compare (&pi2->group, &pi->group) == 0) {
+ found = 1;
+ break;
+ }
+ }
+
+ if (found) {
+ /*
+ * We have this name in list -> don't add
+ */
+ continue ;
+ }
+ } else if (req_lib_cpg_iterationinitialize->iteration_type == CPG_ITERATION_ONE_GROUP) {
+ /*
+ * Test pi group name with request
+ */
+ if (mar_name_compare (&pi->group, &req_lib_cpg_iterationinitialize->group_name) != 0)
+ /*
+ * Not same -> don't add
+ */
+ continue ;
+ }
+
+ new_pi = malloc (sizeof (struct process_info));
+ if (!new_pi) {
+ log_printf(LOGSYS_LEVEL_WARNING, "Unable to allocate process_info struct");
+
+ error = CS_ERR_NO_MEMORY;
+
+ goto error_put_destroy;
+ }
+
+ memcpy (new_pi, pi, sizeof (struct process_info));
+ qb_list_init (&new_pi->list);
+
+ if (req_lib_cpg_iterationinitialize->iteration_type == CPG_ITERATION_NAME_ONLY) {
+ /*
+ * pid and nodeid -> undefined
+ */
+ new_pi->pid = new_pi->nodeid = 0;
+ }
+
+ /*
+ * We will return list "grouped" by "group name", so try to find right place to add
+ */
+ qb_list_for_each(iter2, &(cpg_iteration_instance->items_list_head)) {
+ struct process_info *pi2 = qb_list_entry (iter2, struct process_info, list);
+
+ if (mar_name_compare (&pi2->group, &pi->group) == 0) {
+ break;
+ }
+ }
+
+ qb_list_add (&new_pi->list, iter2);
+ }
+
+ /*
+ * Now we have a full "grouped by" copy of process_info list
+ */
+
+ /*
+ * Add instance to current cpd list
+ */
+ qb_list_init (&cpg_iteration_instance->list);
+ qb_list_add (&cpg_iteration_instance->list, &cpd->iteration_instance_list_head);
+
+ cpg_iteration_instance->current_pointer = &cpg_iteration_instance->items_list_head;
+
+error_put_destroy:
+ hdb_handle_put (&cpg_iteration_handle_t_db, cpg_iteration_handle);
+error_destroy:
+ if (error != CS_OK) {
+ hdb_handle_destroy (&cpg_iteration_handle_t_db, cpg_iteration_handle);
+ }
+
+response_send:
+ res_lib_cpg_iterationinitialize.header.size = sizeof (res_lib_cpg_iterationinitialize);
+ res_lib_cpg_iterationinitialize.header.id = MESSAGE_RES_CPG_ITERATIONINITIALIZE;
+ res_lib_cpg_iterationinitialize.header.error = error;
+ res_lib_cpg_iterationinitialize.iteration_handle = cpg_iteration_handle;
+
+ api->ipc_response_send (conn, &res_lib_cpg_iterationinitialize,
+ sizeof (res_lib_cpg_iterationinitialize));
+}
+
+static void message_handler_req_lib_cpg_iteration_next (
+ void *conn,
+ const void *message)
+{
+ const struct req_lib_cpg_iterationnext *req_lib_cpg_iterationnext = message;
+ struct res_lib_cpg_iterationnext res_lib_cpg_iterationnext;
+ struct cpg_iteration_instance *cpg_iteration_instance;
+ cs_error_t error = CS_OK;
+ int res;
+ struct process_info *pi;
+
+ log_printf (LOGSYS_LEVEL_DEBUG, "cpg iteration next");
+
+ res = hdb_handle_get (&cpg_iteration_handle_t_db,
+ req_lib_cpg_iterationnext->iteration_handle,
+ (void *)&cpg_iteration_instance);
+
+ if (res != 0) {
+ error = CS_ERR_LIBRARY;
+ goto error_exit;
+ }
+
+ assert (cpg_iteration_instance);
+
+ cpg_iteration_instance->current_pointer = cpg_iteration_instance->current_pointer->next;
+
+ if (cpg_iteration_instance->current_pointer == &cpg_iteration_instance->items_list_head) {
+ error = CS_ERR_NO_SECTIONS;
+ goto error_put;
+ }
+
+ pi = qb_list_entry (cpg_iteration_instance->current_pointer, struct process_info, list);
+
+ /*
+ * Copy iteration data
+ */
+ res_lib_cpg_iterationnext.description.nodeid = pi->nodeid;
+ res_lib_cpg_iterationnext.description.pid = pi->pid;
+ memcpy (&res_lib_cpg_iterationnext.description.group,
+ &pi->group,
+ sizeof (mar_cpg_name_t));
+
+error_put:
+ hdb_handle_put (&cpg_iteration_handle_t_db, req_lib_cpg_iterationnext->iteration_handle);
+error_exit:
+ res_lib_cpg_iterationnext.header.size = sizeof (res_lib_cpg_iterationnext);
+ res_lib_cpg_iterationnext.header.id = MESSAGE_RES_CPG_ITERATIONNEXT;
+ res_lib_cpg_iterationnext.header.error = error;
+
+ api->ipc_response_send (conn, &res_lib_cpg_iterationnext,
+ sizeof (res_lib_cpg_iterationnext));
+}
+
+static void message_handler_req_lib_cpg_iteration_finalize (
+ void *conn,
+ const void *message)
+{
+ const struct req_lib_cpg_iterationfinalize *req_lib_cpg_iterationfinalize = message;
+ struct res_lib_cpg_iterationfinalize res_lib_cpg_iterationfinalize;
+ struct cpg_iteration_instance *cpg_iteration_instance;
+ cs_error_t error = CS_OK;
+ int res;
+
+ log_printf (LOGSYS_LEVEL_DEBUG, "cpg iteration finalize");
+
+ res = hdb_handle_get (&cpg_iteration_handle_t_db,
+ req_lib_cpg_iterationfinalize->iteration_handle,
+ (void *)&cpg_iteration_instance);
+
+ if (res != 0) {
+ error = CS_ERR_LIBRARY;
+ goto error_exit;
+ }
+
+ assert (cpg_iteration_instance);
+
+ cpg_iteration_instance_finalize (cpg_iteration_instance);
+ hdb_handle_put (&cpg_iteration_handle_t_db, cpg_iteration_instance->handle);
+
+error_exit:
+ res_lib_cpg_iterationfinalize.header.size = sizeof (res_lib_cpg_iterationfinalize);
+ res_lib_cpg_iterationfinalize.header.id = MESSAGE_RES_CPG_ITERATIONFINALIZE;
+ res_lib_cpg_iterationfinalize.header.error = error;
+
+ api->ipc_response_send (conn, &res_lib_cpg_iterationfinalize,
+ sizeof (res_lib_cpg_iterationfinalize));
+}
diff --git a/exec/cs_queue.h b/exec/cs_queue.h
new file mode 100644
index 0000000..3dd7233
--- /dev/null
+++ b/exec/cs_queue.h
@@ -0,0 +1,292 @@
+/*
+ * Copyright (c) 2002-2004 MontaVista Software, Inc.
+ * Copyright (c) 2006-2011 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Author: Steven Dake (sdake@redhat.com)
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of the MontaVista Software, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef CS_QUEUE_H_DEFINED
+#define CS_QUEUE_H_DEFINED
+
+#include <string.h>
+#include <stdlib.h>
+#include <pthread.h>
+#include <errno.h>
+#include "assert.h"
+
+struct cs_queue {
+ int head;
+ int tail;
+ int used;
+ int usedhw;
+ size_t size;
+ void *items;
+ size_t size_per_item;
+ int iterator;
+ pthread_mutex_t mutex;
+ int threaded_mode_enabled;
+};
+
+static inline int cs_queue_init (struct cs_queue *cs_queue, size_t cs_queue_items, size_t size_per_item, int threaded_mode_enabled) {
+ cs_queue->head = 0;
+ cs_queue->tail = cs_queue_items - 1;
+ cs_queue->used = 0;
+ cs_queue->usedhw = 0;
+ cs_queue->size = cs_queue_items;
+ cs_queue->size_per_item = size_per_item;
+ cs_queue->threaded_mode_enabled = threaded_mode_enabled;
+
+ cs_queue->items = malloc (cs_queue_items * size_per_item);
+ if (cs_queue->items == 0) {
+ return (-ENOMEM);
+ }
+ memset (cs_queue->items, 0, cs_queue_items * size_per_item);
+ if (cs_queue->threaded_mode_enabled) {
+ pthread_mutex_init (&cs_queue->mutex, NULL);
+ }
+ return (0);
+}
+
+static inline int cs_queue_reinit (struct cs_queue *cs_queue)
+{
+ if (cs_queue->threaded_mode_enabled) {
+ pthread_mutex_lock (&cs_queue->mutex);
+ }
+ cs_queue->head = 0;
+ cs_queue->tail = cs_queue->size - 1;
+ cs_queue->used = 0;
+ cs_queue->usedhw = 0;
+
+ memset (cs_queue->items, 0, cs_queue->size * cs_queue->size_per_item);
+ if (cs_queue->threaded_mode_enabled) {
+ pthread_mutex_unlock (&cs_queue->mutex);
+ }
+ return (0);
+}
+
+static inline void cs_queue_free (struct cs_queue *cs_queue) {
+ if (cs_queue->threaded_mode_enabled) {
+ pthread_mutex_destroy (&cs_queue->mutex);
+ }
+ free (cs_queue->items);
+}
+
+static inline int cs_queue_is_full (struct cs_queue *cs_queue) {
+ int full;
+
+ if (cs_queue->threaded_mode_enabled) {
+ pthread_mutex_lock (&cs_queue->mutex);
+ }
+ full = ((cs_queue->size - 1) == cs_queue->used);
+ if (cs_queue->threaded_mode_enabled) {
+ pthread_mutex_unlock (&cs_queue->mutex);
+ }
+ return (full);
+}
+
+static inline int cs_queue_is_empty (struct cs_queue *cs_queue) {
+ int empty;
+
+ if (cs_queue->threaded_mode_enabled) {
+ pthread_mutex_lock (&cs_queue->mutex);
+ }
+ empty = (cs_queue->used == 0);
+ if (cs_queue->threaded_mode_enabled) {
+ pthread_mutex_unlock (&cs_queue->mutex);
+ }
+ return (empty);
+}
+
+static inline void cs_queue_item_add (struct cs_queue *cs_queue, void *item)
+{
+ char *cs_queue_item;
+ int cs_queue_position;
+
+ if (cs_queue->threaded_mode_enabled) {
+ pthread_mutex_lock (&cs_queue->mutex);
+ }
+ cs_queue_position = cs_queue->head;
+ cs_queue_item = cs_queue->items;
+ cs_queue_item += cs_queue_position * cs_queue->size_per_item;
+ memcpy (cs_queue_item, item, cs_queue->size_per_item);
+
+ assert (cs_queue->tail != cs_queue->head);
+
+ cs_queue->head = (cs_queue->head + 1) % cs_queue->size;
+ cs_queue->used++;
+ if (cs_queue->used > cs_queue->usedhw) {
+ cs_queue->usedhw = cs_queue->used;
+ }
+ if (cs_queue->threaded_mode_enabled) {
+ pthread_mutex_unlock (&cs_queue->mutex);
+ }
+}
+
+static inline void *cs_queue_item_get (struct cs_queue *cs_queue)
+{
+ char *cs_queue_item;
+ int cs_queue_position;
+
+ if (cs_queue->threaded_mode_enabled) {
+ pthread_mutex_lock (&cs_queue->mutex);
+ }
+ cs_queue_position = (cs_queue->tail + 1) % cs_queue->size;
+ cs_queue_item = cs_queue->items;
+ cs_queue_item += cs_queue_position * cs_queue->size_per_item;
+ if (cs_queue->threaded_mode_enabled) {
+ pthread_mutex_unlock (&cs_queue->mutex);
+ }
+ return ((void *)cs_queue_item);
+}
+
+static inline void cs_queue_item_remove (struct cs_queue *cs_queue) {
+ if (cs_queue->threaded_mode_enabled) {
+ pthread_mutex_lock (&cs_queue->mutex);
+ }
+ cs_queue->tail = (cs_queue->tail + 1) % cs_queue->size;
+
+ assert (cs_queue->tail != cs_queue->head);
+
+ cs_queue->used--;
+ assert (cs_queue->used >= 0);
+ if (cs_queue->threaded_mode_enabled) {
+ pthread_mutex_unlock (&cs_queue->mutex);
+ }
+}
+
+static inline void cs_queue_items_remove (struct cs_queue *cs_queue, int rel_count)
+{
+ if (cs_queue->threaded_mode_enabled) {
+ pthread_mutex_lock (&cs_queue->mutex);
+ }
+ cs_queue->tail = (cs_queue->tail + rel_count) % cs_queue->size;
+
+ assert (cs_queue->tail != cs_queue->head);
+
+ cs_queue->used -= rel_count;
+ if (cs_queue->threaded_mode_enabled) {
+ pthread_mutex_unlock (&cs_queue->mutex);
+ }
+}
+
+
+static inline void cs_queue_item_iterator_init (struct cs_queue *cs_queue)
+{
+ if (cs_queue->threaded_mode_enabled) {
+ pthread_mutex_lock (&cs_queue->mutex);
+ }
+ cs_queue->iterator = (cs_queue->tail + 1) % cs_queue->size;
+ if (cs_queue->threaded_mode_enabled) {
+ pthread_mutex_unlock (&cs_queue->mutex);
+ }
+}
+
+static inline void *cs_queue_item_iterator_get (struct cs_queue *cs_queue)
+{
+ char *cs_queue_item;
+ int cs_queue_position;
+
+ if (cs_queue->threaded_mode_enabled) {
+ pthread_mutex_lock (&cs_queue->mutex);
+ }
+ cs_queue_position = (cs_queue->iterator) % cs_queue->size;
+ if (cs_queue->iterator == cs_queue->head) {
+ if (cs_queue->threaded_mode_enabled) {
+ pthread_mutex_unlock (&cs_queue->mutex);
+ }
+ return (0);
+ }
+ cs_queue_item = cs_queue->items;
+ cs_queue_item += cs_queue_position * cs_queue->size_per_item;
+ if (cs_queue->threaded_mode_enabled) {
+ pthread_mutex_unlock (&cs_queue->mutex);
+ }
+ return ((void *)cs_queue_item);
+}
+
+static inline int cs_queue_item_iterator_next (struct cs_queue *cs_queue)
+{
+ int next_res;
+
+ if (cs_queue->threaded_mode_enabled) {
+ pthread_mutex_lock (&cs_queue->mutex);
+ }
+ cs_queue->iterator = (cs_queue->iterator + 1) % cs_queue->size;
+
+ next_res = cs_queue->iterator == cs_queue->head;
+ if (cs_queue->threaded_mode_enabled) {
+ pthread_mutex_unlock (&cs_queue->mutex);
+ }
+ return (next_res);
+}
+
+static inline void cs_queue_avail (struct cs_queue *cs_queue, int *avail)
+{
+ if (cs_queue->threaded_mode_enabled) {
+ pthread_mutex_lock (&cs_queue->mutex);
+ }
+ *avail = cs_queue->size - cs_queue->used - 2;
+ assert (*avail >= 0);
+ if (cs_queue->threaded_mode_enabled) {
+ pthread_mutex_unlock (&cs_queue->mutex);
+ }
+}
+
+static inline int cs_queue_used (struct cs_queue *cs_queue) {
+ int used;
+
+ if (cs_queue->threaded_mode_enabled) {
+ pthread_mutex_lock (&cs_queue->mutex);
+ }
+ used = cs_queue->used;
+ if (cs_queue->threaded_mode_enabled) {
+ pthread_mutex_unlock (&cs_queue->mutex);
+ }
+
+ return (used);
+}
+
+static inline int cs_queue_usedhw (struct cs_queue *cs_queue) {
+ int usedhw;
+
+ if (cs_queue->threaded_mode_enabled) {
+ pthread_mutex_lock (&cs_queue->mutex);
+ }
+
+ usedhw = cs_queue->usedhw;
+
+ if (cs_queue->threaded_mode_enabled) {
+ pthread_mutex_unlock (&cs_queue->mutex);
+ }
+
+ return (usedhw);
+}
+
+#endif /* CS_QUEUE_H_DEFINED */
diff --git a/exec/fsm.h b/exec/fsm.h
new file mode 100644
index 0000000..87efd7d
--- /dev/null
+++ b/exec/fsm.h
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2010-2012 Red Hat
+ *
+ * All rights reserved.
+ *
+ * Author: Angus Salkeld <asalkeld@redhat.com>
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of the MontaVista Software, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef FSM_H_DEFINED
+#define FSM_H_DEFINED
+
+#include <sys/time.h>
+#include <corosync/corotypes.h>
+#include "util.h"
+
+struct cs_fsm;
+struct cs_fsm_entry;
+typedef void (*cs_fsm_event_action_fn)(struct cs_fsm* fsm, int32_t event, void * data);
+typedef const char * (*cs_fsm_state_to_str_fn)(struct cs_fsm* fsm, int32_t state);
+typedef const char * (*cs_fsm_event_to_str_fn)(struct cs_fsm* fsm, int32_t event);
+
+typedef void (*cs_fsm_cb)(struct cs_fsm *fsm, int cb_event, int32_t curr_state,
+ int32_t next_state, int32_t fsm_event, void *data);
+
+#define CS_FSM_NEXT_STATE_SIZE 32
+
+#define CS_FSM_STATE_NONE -1
+
+#define CS_FSM_CB_EVENT_PROCESS_NF 0
+#define CS_FSM_CB_EVENT_STATE_SET 1
+#define CS_FSM_CB_EVENT_STATE_SET_NF 2
+
+struct cs_fsm_entry {
+ int32_t curr_state;
+ int32_t event;
+ cs_fsm_event_action_fn handler_fn;
+ int32_t next_states[CS_FSM_NEXT_STATE_SIZE];
+};
+
+struct cs_fsm {
+ const char *name;
+ int32_t curr_state;
+ int32_t curr_entry;
+ size_t entries;
+ struct cs_fsm_entry *table;
+ cs_fsm_state_to_str_fn state_to_str;
+ cs_fsm_event_to_str_fn event_to_str;
+};
+
+/*
+ * the table entry is defined by the state + event (curr_entry).
+ * so cs_fsm_process() sets the entry and cs_fsm_state_set()
+ * sets the new state.
+ */
+static inline void cs_fsm_process (struct cs_fsm *fsm, int32_t new_event, void * data, cs_fsm_cb cb)
+{
+ int32_t i;
+
+ for (i = 0; i < fsm->entries; i++) {
+ if (fsm->table[i].event == new_event &&
+ fsm->table[i].curr_state == fsm->curr_state) {
+
+ assert (fsm->table[i].handler_fn != NULL);
+ /* set current entry */
+ fsm->curr_entry = i;
+ fsm->table[i].handler_fn (fsm, new_event, data);
+ return;
+ }
+ }
+
+ if (cb != NULL) {
+ cb(fsm, CS_FSM_CB_EVENT_PROCESS_NF, fsm->curr_state, CS_FSM_STATE_NONE, new_event, data);
+ }
+}
+
+static inline void cs_fsm_state_set (struct cs_fsm* fsm, int32_t next_state, void* data, cs_fsm_cb cb)
+{
+ int i;
+ struct cs_fsm_entry *entry = &fsm->table[fsm->curr_entry];
+
+ if (fsm->curr_state == next_state) {
+ return;
+ }
+ /*
+ * confirm that "next_state" is in the current entry's next list
+ */
+ for (i = 0; i < CS_FSM_NEXT_STATE_SIZE; i++) {
+ if (entry->next_states[i] < 0) {
+ break;
+ }
+ if (entry->next_states[i] == next_state) {
+ if (cb != NULL) {
+ cb(fsm, CS_FSM_CB_EVENT_STATE_SET, fsm->curr_state, next_state, entry->event, data);
+ }
+ fsm->curr_state = next_state;
+ return;
+ }
+ }
+ if (cb != NULL) {
+ cb(fsm, CS_FSM_CB_EVENT_STATE_SET_NF, fsm->curr_state, next_state, entry->event, data);
+ }
+}
+
+#endif /* FSM_H_DEFINED */
+
+
diff --git a/exec/icmap.c b/exec/icmap.c
new file mode 100644
index 0000000..4aeabab
--- /dev/null
+++ b/exec/icmap.c
@@ -0,0 +1,1330 @@
+/*
+ * Copyright (c) 2011 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Author: Jan Friesse (jfriesse@redhat.com)
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of the Red Hat, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include <string.h>
+#include <stdio.h>
+
+#include <corosync/corotypes.h>
+
+#include <qb/qbdefs.h>
+#include <qb/qblist.h>
+#include <corosync/icmap.h>
+
+#define ICMAP_MAX_VALUE_LEN (16*1024)
+
+struct icmap_item {
+ char *key_name;
+ icmap_value_types_t type;
+ size_t value_len;
+ char value[];
+};
+
+struct icmap_map {
+ qb_map_t *qb_map;
+};
+
+static icmap_map_t icmap_global_map;
+
+struct icmap_track {
+ char *key_name;
+ int32_t track_type;
+ icmap_notify_fn_t notify_fn;
+ void *user_data;
+ struct qb_list_head list;
+};
+
+struct icmap_ro_access_item {
+ char *key_name;
+ int prefix;
+ struct qb_list_head list;
+};
+
+QB_LIST_DECLARE (icmap_ro_access_item_list_head);
+QB_LIST_DECLARE (icmap_track_list_head);
+
+/*
+ * Static functions declarations
+ */
+
+/*
+ * Check if key_name is valid icmap key name. Returns 0 on success, and -1 on fail
+ */
+static int icmap_check_key_name(const char *key_name);
+
+/*
+ * Check that value with given type has correct length value_len. Returns 0 on success,
+ * and -1 on fail
+ */
+static int icmap_check_value_len(const void *value, size_t value_len, icmap_value_types_t type);
+
+/*
+ * Checks if item has same value as value with value_len and given type. Returns 0 if not, otherwise !0.
+ */
+static int icmap_item_eq(const struct icmap_item *item, const void *value, size_t value_len, icmap_value_types_t type);
+
+/*
+ * Checks if given character is valid in key name. Returns 0 if not, otherwise !0.
+ */
+static int icmap_is_valid_name_char(char c);
+
+/*
+ * Helper for getting integer and float value with given type for key key_name and store it in value.
+ */
+static cs_error_t icmap_get_int_r(
+ const icmap_map_t map,
+ const char *key_name,
+ void *value,
+ icmap_value_types_t type);
+
+/*
+ * Return raw item value data. Internal function used by icmap_get_r which does most
+ * of arguments validity checks but doesn't copy data (it returns raw item data
+ * pointer). It's not very safe tho it's static.
+ */
+static cs_error_t icmap_get_ref_r(
+ const icmap_map_t map,
+ const char *key_name,
+ void **value,
+ size_t *value_len,
+ icmap_value_types_t *type);
+
+/*
+ * Function implementation
+ */
+int32_t icmap_tt_to_qbtt(int32_t track_type)
+{
+ int32_t res = 0;
+
+ if (track_type & ICMAP_TRACK_DELETE) {
+ res |= QB_MAP_NOTIFY_DELETED;
+ }
+
+ if (track_type & ICMAP_TRACK_MODIFY) {
+ res |= QB_MAP_NOTIFY_REPLACED;
+ }
+
+ if (track_type & ICMAP_TRACK_ADD) {
+ res |= QB_MAP_NOTIFY_INSERTED;
+ }
+
+ if (track_type & ICMAP_TRACK_PREFIX) {
+ res |= QB_MAP_NOTIFY_RECURSIVE;
+ }
+
+ return (res);
+}
+
+int32_t icmap_qbtt_to_tt(int32_t track_type)
+{
+ int32_t res = 0;
+
+ if (track_type & QB_MAP_NOTIFY_DELETED) {
+ res |= ICMAP_TRACK_DELETE;
+ }
+
+ if (track_type & QB_MAP_NOTIFY_REPLACED) {
+ res |= ICMAP_TRACK_MODIFY;
+ }
+
+ if (track_type & QB_MAP_NOTIFY_INSERTED) {
+ res |= ICMAP_TRACK_ADD;
+ }
+
+ if (track_type & QB_MAP_NOTIFY_RECURSIVE) {
+ res |= ICMAP_TRACK_PREFIX;
+ }
+
+ return (res);
+}
+
+static void icmap_map_free_cb(uint32_t event,
+ char* key, void* old_value,
+ void* value, void* user_data)
+{
+ struct icmap_item *item = (struct icmap_item *)old_value;
+
+ /*
+ * value == old_value -> fast_adjust_int was used, don't free data
+ */
+ if (item != NULL && value != old_value) {
+ free(item->key_name);
+ free(item);
+ }
+}
+
+cs_error_t icmap_init_r(icmap_map_t *result)
+{
+ int32_t err;
+
+ *result = malloc(sizeof(struct icmap_map));
+ if (*result == NULL) {
+ return (CS_ERR_NO_MEMORY);
+ }
+
+ (*result)->qb_map = qb_trie_create();
+ if ((*result)->qb_map == NULL) {
+ free(*result);
+ return (CS_ERR_INIT);
+ }
+
+ err = qb_map_notify_add((*result)->qb_map, NULL, icmap_map_free_cb, QB_MAP_NOTIFY_FREE, NULL);
+
+ return (qb_to_cs_error(err));
+}
+
+cs_error_t icmap_init(void)
+{
+ return (icmap_init_r(&icmap_global_map));
+}
+
+static void icmap_set_ro_access_free(void)
+{
+ struct qb_list_head *iter, *tmp_iter;
+ struct icmap_ro_access_item *icmap_ro_ai;
+
+ qb_list_for_each_safe(iter, tmp_iter, &icmap_ro_access_item_list_head) {
+ icmap_ro_ai = qb_list_entry(iter, struct icmap_ro_access_item, list);
+ qb_list_del(&icmap_ro_ai->list);
+ free(icmap_ro_ai->key_name);
+ free(icmap_ro_ai);
+ }
+}
+
+static void icmap_del_all_track(void)
+{
+ struct qb_list_head *iter, *tmp_iter;
+ struct icmap_track *icmap_track;
+
+ qb_list_for_each_safe(iter, tmp_iter, &icmap_track_list_head) {
+ icmap_track = qb_list_entry(iter, struct icmap_track, list);
+
+ icmap_track_delete(icmap_track);
+ }
+}
+
+void icmap_fini_r(const icmap_map_t map)
+{
+
+ qb_map_destroy(map->qb_map);
+ free(map);
+
+ return;
+}
+
+void icmap_fini(void)
+{
+
+ icmap_del_all_track();
+ /*
+ * catch 22 warning:
+ * We need to drop this notify but we can't because it calls icmap_map_free_cb
+ * while destroying the tree to free icmap_item(s).
+ * -> qb_map_notify_del_2(icmap_map, NULL, icmap_map_free_cb, QB_MAP_NOTIFY_FREE, NULL);
+ * and we cannot call it after map_destroy. joy! :)
+ */
+ icmap_fini_r(icmap_global_map);
+ icmap_set_ro_access_free();
+
+ return ;
+}
+
+icmap_map_t icmap_get_global_map(void)
+{
+
+ return (icmap_global_map);
+}
+
+static int icmap_is_valid_name_char(char c)
+{
+ return ((c >= 'a' && c <= 'z') ||
+ (c >= 'A' && c <= 'Z') ||
+ (c >= '0' && c <= '9') ||
+ c == '.' || c == '_' || c == '-' || c == '/' || c == ':');
+}
+
+void icmap_convert_name_to_valid_name(char *key_name)
+{
+ int i;
+
+ for (i = 0; i < strlen(key_name); i++) {
+ if (!icmap_is_valid_name_char(key_name[i])) {
+ key_name[i] = '_';
+ }
+ }
+}
+
+static int icmap_check_key_name(const char *key_name)
+{
+ int i;
+
+ if ((strlen(key_name) < ICMAP_KEYNAME_MINLEN) || strlen(key_name) > ICMAP_KEYNAME_MAXLEN) {
+ return (-1);
+ }
+
+ for (i = 0; i < strlen(key_name); i++) {
+ if (!icmap_is_valid_name_char(key_name[i])) {
+ return (-1);
+ }
+ }
+
+ return (0);
+}
+
+size_t icmap_get_valuetype_len(icmap_value_types_t type)
+{
+ size_t res = 0;
+
+ switch (type) {
+ case ICMAP_VALUETYPE_INT8: res = sizeof(int8_t); break;
+ case ICMAP_VALUETYPE_UINT8: res = sizeof(uint8_t); break;
+ case ICMAP_VALUETYPE_INT16: res = sizeof(int16_t); break;
+ case ICMAP_VALUETYPE_UINT16: res = sizeof(uint16_t); break;
+ case ICMAP_VALUETYPE_INT32: res = sizeof(int32_t); break;
+ case ICMAP_VALUETYPE_UINT32: res = sizeof(uint32_t); break;
+ case ICMAP_VALUETYPE_INT64: res = sizeof(int64_t); break;
+ case ICMAP_VALUETYPE_UINT64: res = sizeof(uint64_t); break;
+ case ICMAP_VALUETYPE_FLOAT: res = sizeof(float); break;
+ case ICMAP_VALUETYPE_DOUBLE: res = sizeof(double); break;
+ case ICMAP_VALUETYPE_STRING:
+ case ICMAP_VALUETYPE_BINARY:
+ res = 0;
+ break;
+ }
+
+ return (res);
+}
+
+static int icmap_check_value_len(const void *value, size_t value_len, icmap_value_types_t type)
+{
+
+ if (value_len > ICMAP_MAX_VALUE_LEN) {
+ return (-1);
+ }
+
+ if (type != ICMAP_VALUETYPE_STRING && type != ICMAP_VALUETYPE_BINARY) {
+ if (icmap_get_valuetype_len(type) == value_len) {
+ return (0);
+ } else {
+ return (-1);
+ }
+ }
+
+ if (type == ICMAP_VALUETYPE_STRING) {
+ /*
+ * value_len can be shorter then real string length, but never
+ * longer (+ 1 is because of 0 at the end of string)
+ */
+ if (value_len > strlen((const char *)value) + 1) {
+ return (-1);
+ } else {
+ return (0);
+ }
+ }
+
+ return (0);
+}
+
+static int icmap_item_eq(const struct icmap_item *item, const void *value, size_t value_len, icmap_value_types_t type)
+{
+ size_t ptr_len;
+
+ if (item->type != type) {
+ return (0);
+ }
+
+ if (item->type == ICMAP_VALUETYPE_STRING) {
+ ptr_len = strlen((const char *)value);
+ if (ptr_len > value_len) {
+ ptr_len = value_len;
+ }
+ ptr_len++;
+ } else {
+ ptr_len = value_len;
+ }
+
+ if (item->value_len == ptr_len) {
+ return (memcmp(item->value, value, value_len) == 0);
+ };
+
+ return (0);
+}
+
+int icmap_key_value_eq(
+ const icmap_map_t map1,
+ const char *key_name1,
+ const icmap_map_t map2,
+ const char *key_name2)
+{
+ struct icmap_item *item1, *item2;
+
+ if (map1 == NULL || key_name1 == NULL || map2 == NULL || key_name2 == NULL) {
+ return (0);
+ }
+
+ item1 = qb_map_get(map1->qb_map, key_name1);
+ item2 = qb_map_get(map2->qb_map, key_name2);
+
+ if (item1 == NULL || item2 == NULL) {
+ return (0);
+ }
+
+ return (icmap_item_eq(item1, item2->value, item2->value_len, item2->type));
+}
+
+cs_error_t icmap_set_r(
+ const icmap_map_t map,
+ const char *key_name,
+ const void *value,
+ size_t value_len,
+ icmap_value_types_t type)
+{
+ struct icmap_item *item;
+ struct icmap_item *new_item;
+ size_t new_value_len;
+ size_t new_item_size;
+
+ if (value == NULL || key_name == NULL) {
+ return (CS_ERR_INVALID_PARAM);
+ }
+
+ if (icmap_check_value_len(value, value_len, type) != 0) {
+ return (CS_ERR_INVALID_PARAM);
+ }
+
+ item = qb_map_get(map->qb_map, key_name);
+ if (item != NULL) {
+ /*
+ * Check that key is really changed
+ */
+ if (icmap_item_eq(item, value, value_len, type)) {
+ return (CS_OK);
+ }
+ } else {
+ if (icmap_check_key_name(key_name) != 0) {
+ return (CS_ERR_NAME_TOO_LONG);
+ }
+ }
+
+ if (type == ICMAP_VALUETYPE_BINARY || type == ICMAP_VALUETYPE_STRING) {
+ if (type == ICMAP_VALUETYPE_STRING) {
+ new_value_len = strlen((const char *)value);
+ if (new_value_len > value_len) {
+ new_value_len = value_len;
+ }
+ new_value_len++;
+ } else {
+ new_value_len = value_len;
+ }
+ } else {
+ new_value_len = icmap_get_valuetype_len(type);
+ }
+
+ new_item_size = sizeof(struct icmap_item) + new_value_len;
+ new_item = malloc(new_item_size);
+ if (new_item == NULL) {
+ return (CS_ERR_NO_MEMORY);
+ }
+ memset(new_item, 0, new_item_size);
+
+ if (item == NULL) {
+ new_item->key_name = strdup(key_name);
+ if (new_item->key_name == NULL) {
+ free(new_item);
+ return (CS_ERR_NO_MEMORY);
+ }
+ } else {
+ new_item->key_name = item->key_name;
+ item->key_name = NULL;
+ }
+
+ new_item->type = type;
+ new_item->value_len = new_value_len;
+
+ memcpy(new_item->value, value, new_value_len);
+
+ if (new_item->type == ICMAP_VALUETYPE_STRING) {
+ ((char *)new_item->value)[new_value_len - 1] = 0;
+ }
+
+ qb_map_put(map->qb_map, new_item->key_name, new_item);
+
+ return (CS_OK);
+}
+
+cs_error_t icmap_set(
+ const char *key_name,
+ const void *value,
+ size_t value_len,
+ icmap_value_types_t type)
+{
+
+ return (icmap_set_r(icmap_global_map, key_name, value, value_len, type));
+}
+
+cs_error_t icmap_set_int8_r(const icmap_map_t map, const char *key_name, int8_t value)
+{
+
+ return (icmap_set_r(map, key_name, &value, sizeof(value), ICMAP_VALUETYPE_INT8));
+}
+
+cs_error_t icmap_set_uint8_r(const icmap_map_t map, const char *key_name, uint8_t value)
+{
+
+ return (icmap_set_r(map, key_name, &value, sizeof(value), ICMAP_VALUETYPE_UINT8));
+}
+
+cs_error_t icmap_set_int16_r(const icmap_map_t map, const char *key_name, int16_t value)
+{
+
+ return (icmap_set_r(map,key_name, &value, sizeof(value), ICMAP_VALUETYPE_INT16));
+}
+
+cs_error_t icmap_set_uint16_r(const icmap_map_t map, const char *key_name, uint16_t value)
+{
+
+ return (icmap_set_r(map, key_name, &value, sizeof(value), ICMAP_VALUETYPE_UINT16));
+}
+
+cs_error_t icmap_set_int32_r(const icmap_map_t map, const char *key_name, int32_t value)
+{
+
+ return (icmap_set_r(map, key_name, &value, sizeof(value), ICMAP_VALUETYPE_INT32));
+}
+
+cs_error_t icmap_set_uint32_r(const icmap_map_t map, const char *key_name, uint32_t value)
+{
+
+ return (icmap_set_r(map, key_name, &value, sizeof(value), ICMAP_VALUETYPE_UINT32));
+}
+
+cs_error_t icmap_set_int64_r(const icmap_map_t map, const char *key_name, int64_t value)
+{
+
+ return (icmap_set_r(map, key_name, &value, sizeof(value), ICMAP_VALUETYPE_INT64));
+}
+
+cs_error_t icmap_set_uint64_r(const icmap_map_t map, const char *key_name, uint64_t value)
+{
+
+ return (icmap_set_r(map, key_name, &value, sizeof(value), ICMAP_VALUETYPE_UINT64));
+}
+
+cs_error_t icmap_set_float_r(const icmap_map_t map, const char *key_name, float value)
+{
+
+ return (icmap_set_r(map, key_name, &value, sizeof(value), ICMAP_VALUETYPE_FLOAT));
+}
+
+cs_error_t icmap_set_double_r(const icmap_map_t map, const char *key_name, double value)
+{
+
+ return (icmap_set_r(map, key_name, &value, sizeof(value), ICMAP_VALUETYPE_DOUBLE));
+}
+
+cs_error_t icmap_set_string_r(const icmap_map_t map, const char *key_name, const char *value)
+{
+
+ if (value == NULL) {
+ return (CS_ERR_INVALID_PARAM);
+ }
+
+ return (icmap_set_r(map, key_name, value, strlen(value), ICMAP_VALUETYPE_STRING));
+}
+
+cs_error_t icmap_set_int8(const char *key_name, int8_t value)
+{
+
+ return (icmap_set_int8_r(icmap_global_map, key_name, value));
+}
+
+cs_error_t icmap_set_uint8(const char *key_name, uint8_t value)
+{
+
+ return (icmap_set_uint8_r(icmap_global_map, key_name, value));
+}
+
+cs_error_t icmap_set_int16(const char *key_name, int16_t value)
+{
+
+ return (icmap_set_int16_r(icmap_global_map, key_name, value));
+}
+
+cs_error_t icmap_set_uint16(const char *key_name, uint16_t value)
+{
+
+ return (icmap_set_uint16_r(icmap_global_map, key_name, value));
+}
+
+cs_error_t icmap_set_int32(const char *key_name, int32_t value)
+{
+
+ return (icmap_set_int32_r(icmap_global_map, key_name, value));
+}
+
+cs_error_t icmap_set_uint32(const char *key_name, uint32_t value)
+{
+
+ return (icmap_set_uint32_r(icmap_global_map, key_name, value));
+}
+
+cs_error_t icmap_set_int64(const char *key_name, int64_t value)
+{
+
+ return (icmap_set_int64_r(icmap_global_map, key_name, value));
+}
+
+cs_error_t icmap_set_uint64(const char *key_name, uint64_t value)
+{
+
+ return (icmap_set_uint64_r(icmap_global_map, key_name, value));
+}
+
+cs_error_t icmap_set_float(const char *key_name, float value)
+{
+
+ return (icmap_set_float_r(icmap_global_map, key_name, value));
+}
+
+cs_error_t icmap_set_double(const char *key_name, double value)
+{
+
+ return (icmap_set_double_r(icmap_global_map, key_name, value));
+}
+
+cs_error_t icmap_set_string(const char *key_name, const char *value)
+{
+
+ return (icmap_set_string_r(icmap_global_map, key_name, value));
+}
+
+cs_error_t icmap_delete_r(const icmap_map_t map, const char *key_name)
+{
+ struct icmap_item *item;
+
+ if (key_name == NULL) {
+ return (CS_ERR_INVALID_PARAM);
+ }
+
+ item = qb_map_get(map->qb_map, key_name);
+ if (item == NULL) {
+ return (CS_ERR_NOT_EXIST);
+ }
+
+ if (qb_map_rm(map->qb_map, item->key_name) != QB_TRUE) {
+ return (CS_ERR_NOT_EXIST);
+ }
+
+ return (CS_OK);
+}
+
+cs_error_t icmap_delete(const char *key_name)
+{
+
+ return (icmap_delete_r(icmap_global_map, key_name));
+}
+
+static cs_error_t icmap_get_ref_r(
+ const icmap_map_t map,
+ const char *key_name,
+ void **value,
+ size_t *value_len,
+ icmap_value_types_t *type)
+{
+ struct icmap_item *item;
+
+ if (key_name == NULL) {
+ return (CS_ERR_INVALID_PARAM);
+ }
+
+ item = qb_map_get(map->qb_map, key_name);
+ if (item == NULL) {
+ return (CS_ERR_NOT_EXIST);
+ }
+
+ if (type != NULL) {
+ *type = item->type;
+ }
+
+ if (value_len != NULL) {
+ *value_len = item->value_len;
+ }
+
+ if (value != NULL) {
+ *value = item->value;
+ }
+
+ return (CS_OK);
+}
+
+cs_error_t icmap_get_r(
+ const icmap_map_t map,
+ const char *key_name,
+ void *value,
+ size_t *value_len,
+ icmap_value_types_t *type)
+{
+ cs_error_t res;
+ void *tmp_value;
+ size_t tmp_value_len;
+
+ res = icmap_get_ref_r(map, key_name, &tmp_value, &tmp_value_len, type);
+ if (res != CS_OK) {
+ return (res);
+ }
+
+ if (value == NULL) {
+ if (value_len != NULL) {
+ *value_len = tmp_value_len;
+ }
+ } else {
+ if (value_len == NULL || *value_len < tmp_value_len) {
+ return (CS_ERR_INVALID_PARAM);
+ }
+
+ *value_len = tmp_value_len;
+
+ memcpy(value, tmp_value, tmp_value_len);
+ }
+
+ return (CS_OK);
+}
+
+cs_error_t icmap_get(
+ const char *key_name,
+ void *value,
+ size_t *value_len,
+ icmap_value_types_t *type)
+{
+
+ return (icmap_get_r(icmap_global_map, key_name, value, value_len, type));
+}
+
+cs_error_t icmap_get_string_r(icmap_map_t map, const char *key_name, char **str)
+{
+ cs_error_t res;
+ size_t str_len;
+ icmap_value_types_t type;
+
+ res = icmap_get_r(map, key_name, NULL, &str_len, &type);
+ if (res != CS_OK || type != ICMAP_VALUETYPE_STRING) {
+ if (res == CS_OK) {
+ res = CS_ERR_INVALID_PARAM;
+ }
+
+ goto return_error;
+ }
+
+ *str = malloc(str_len);
+ if (*str == NULL) {
+ res = CS_ERR_NO_MEMORY;
+
+ goto return_error;
+ }
+
+ res = icmap_get_r(map, key_name, *str, &str_len, &type);
+ if (res != CS_OK) {
+ free(*str);
+ goto return_error;
+ }
+
+ return (CS_OK);
+
+return_error:
+ return (res);
+}
+
+static cs_error_t icmap_get_int_r(
+ const icmap_map_t map,
+ const char *key_name,
+ void *value,
+ icmap_value_types_t type)
+{
+ char key_value[16];
+ size_t key_size;
+ cs_error_t err;
+ icmap_value_types_t key_type;
+
+ key_size = sizeof(key_value);
+ memset(key_value, 0, key_size);
+
+ err = icmap_get_r(map, key_name, key_value, &key_size, &key_type);
+ if (err != CS_OK)
+ return (err);
+
+ if (key_type != type) {
+ return (CS_ERR_INVALID_PARAM);
+ }
+
+ memcpy(value, key_value, icmap_get_valuetype_len(key_type));
+
+ return (CS_OK);
+}
+
+cs_error_t icmap_get_int8_r(const icmap_map_t map, const char *key_name, int8_t *i8)
+{
+
+ return (icmap_get_int_r(map, key_name, i8, ICMAP_VALUETYPE_INT8));
+}
+
+cs_error_t icmap_get_uint8_r(const icmap_map_t map, const char *key_name, uint8_t *u8)
+{
+
+ return (icmap_get_int_r(map, key_name, u8, ICMAP_VALUETYPE_UINT8));
+}
+
+cs_error_t icmap_get_int16_r(const icmap_map_t map, const char *key_name, int16_t *i16)
+{
+
+ return (icmap_get_int_r(map, key_name, i16, ICMAP_VALUETYPE_INT16));
+}
+
+cs_error_t icmap_get_uint16_r(const icmap_map_t map, const char *key_name, uint16_t *u16)
+{
+
+ return (icmap_get_int_r(map, key_name, u16, ICMAP_VALUETYPE_UINT16));
+}
+
+cs_error_t icmap_get_int32_r(const icmap_map_t map, const char *key_name, int32_t *i32)
+{
+
+ return (icmap_get_int_r(map, key_name, i32, ICMAP_VALUETYPE_INT32));
+}
+
+cs_error_t icmap_get_uint32_r(const icmap_map_t map, const char *key_name, uint32_t *u32)
+{
+
+ return (icmap_get_int_r(map, key_name, u32, ICMAP_VALUETYPE_UINT32));
+}
+
+cs_error_t icmap_get_int64_r(const icmap_map_t map, const char *key_name, int64_t *i64)
+{
+
+ return(icmap_get_int_r(map, key_name, i64, ICMAP_VALUETYPE_INT64));
+}
+
+cs_error_t icmap_get_uint64_r(const icmap_map_t map, const char *key_name, uint64_t *u64)
+{
+
+ return (icmap_get_int_r(map, key_name, u64, ICMAP_VALUETYPE_UINT64));
+}
+
+cs_error_t icmap_get_float_r(const icmap_map_t map, const char *key_name, float *flt)
+{
+
+ return (icmap_get_int_r(map, key_name, flt, ICMAP_VALUETYPE_FLOAT));
+}
+
+cs_error_t icmap_get_double_r(const icmap_map_t map, const char *key_name, double *dbl)
+{
+
+ return (icmap_get_int_r(map, key_name, dbl, ICMAP_VALUETYPE_DOUBLE));
+}
+
+cs_error_t icmap_get_string(const char *key_name, char **str)
+{
+
+ return (icmap_get_string_r(icmap_global_map, key_name, str));
+}
+
+cs_error_t icmap_get_int8(const char *key_name, int8_t *i8)
+{
+
+ return (icmap_get_int8_r(icmap_global_map, key_name, i8));
+}
+
+cs_error_t icmap_get_uint8(const char *key_name, uint8_t *u8)
+{
+
+ return (icmap_get_uint8_r(icmap_global_map, key_name, u8));
+}
+
+cs_error_t icmap_get_int16(const char *key_name, int16_t *i16)
+{
+
+ return (icmap_get_int16_r(icmap_global_map, key_name, i16));
+}
+
+cs_error_t icmap_get_uint16(const char *key_name, uint16_t *u16)
+{
+
+ return (icmap_get_uint16_r(icmap_global_map, key_name, u16));
+}
+
+cs_error_t icmap_get_int32(const char *key_name, int32_t *i32)
+{
+
+ return (icmap_get_int32_r(icmap_global_map, key_name, i32));
+}
+
+cs_error_t icmap_get_uint32(const char *key_name, uint32_t *u32)
+{
+
+ return (icmap_get_uint32_r(icmap_global_map, key_name, u32));
+}
+
+cs_error_t icmap_get_int64(const char *key_name, int64_t *i64)
+{
+
+ return(icmap_get_int64_r(icmap_global_map, key_name, i64));
+}
+
+cs_error_t icmap_get_uint64(const char *key_name, uint64_t *u64)
+{
+
+ return (icmap_get_uint64_r(icmap_global_map, key_name, u64));
+}
+
+cs_error_t icmap_get_float(const char *key_name, float *flt)
+{
+
+ return (icmap_get_float_r(icmap_global_map, key_name, flt));
+}
+
+cs_error_t icmap_get_double(const char *key_name, double *dbl)
+{
+
+ return (icmap_get_double_r(icmap_global_map, key_name, dbl));
+}
+
+cs_error_t icmap_adjust_int_r(
+ const icmap_map_t map,
+ const char *key_name,
+ int32_t step)
+{
+ struct icmap_item *item;
+ uint8_t u8;
+ uint16_t u16;
+ uint32_t u32;
+ uint64_t u64;
+ cs_error_t err = CS_OK;
+
+ if (key_name == NULL) {
+ return (CS_ERR_INVALID_PARAM);
+ }
+
+ item = qb_map_get(map->qb_map, key_name);
+ if (item == NULL) {
+ return (CS_ERR_NOT_EXIST);
+ }
+
+ switch (item->type) {
+ case ICMAP_VALUETYPE_INT8:
+ case ICMAP_VALUETYPE_UINT8:
+ memcpy(&u8, item->value, sizeof(u8));
+ u8 += step;
+ err = icmap_set(key_name, &u8, sizeof(u8), item->type);
+ break;
+ case ICMAP_VALUETYPE_INT16:
+ case ICMAP_VALUETYPE_UINT16:
+ memcpy(&u16, item->value, sizeof(u16));
+ u16 += step;
+ err = icmap_set(key_name, &u16, sizeof(u16), item->type);
+ break;
+ case ICMAP_VALUETYPE_INT32:
+ case ICMAP_VALUETYPE_UINT32:
+ memcpy(&u32, item->value, sizeof(u32));
+ u32 += step;
+ err = icmap_set(key_name, &u32, sizeof(u32), item->type);
+ break;
+ case ICMAP_VALUETYPE_INT64:
+ case ICMAP_VALUETYPE_UINT64:
+ memcpy(&u64, item->value, sizeof(u64));
+ u64 += step;
+ err = icmap_set(key_name, &u64, sizeof(u64), item->type);
+ break;
+ case ICMAP_VALUETYPE_FLOAT:
+ case ICMAP_VALUETYPE_DOUBLE:
+ case ICMAP_VALUETYPE_STRING:
+ case ICMAP_VALUETYPE_BINARY:
+ err = CS_ERR_INVALID_PARAM;
+ break;
+ }
+
+ return (err);
+}
+
+cs_error_t icmap_adjust_int(
+ const char *key_name,
+ int32_t step)
+{
+
+ return (icmap_adjust_int_r(icmap_global_map, key_name, step));
+}
+
+cs_error_t icmap_fast_adjust_int_r(
+ const icmap_map_t map,
+ const char *key_name,
+ int32_t step)
+{
+ struct icmap_item *item;
+ cs_error_t err = CS_OK;
+
+ if (key_name == NULL) {
+ return (CS_ERR_INVALID_PARAM);
+ }
+
+ item = qb_map_get(map->qb_map, key_name);
+ if (item == NULL) {
+ return (CS_ERR_NOT_EXIST);
+ }
+
+ switch (item->type) {
+ case ICMAP_VALUETYPE_INT8:
+ case ICMAP_VALUETYPE_UINT8:
+ *(uint8_t *)item->value += step;
+ break;
+ case ICMAP_VALUETYPE_INT16:
+ case ICMAP_VALUETYPE_UINT16:
+ *(uint16_t *)item->value += step;
+ break;
+ case ICMAP_VALUETYPE_INT32:
+ case ICMAP_VALUETYPE_UINT32:
+ *(uint32_t *)item->value += step;
+ break;
+ case ICMAP_VALUETYPE_INT64:
+ case ICMAP_VALUETYPE_UINT64:
+ *(uint64_t *)item->value += step;
+ break;
+ case ICMAP_VALUETYPE_FLOAT:
+ case ICMAP_VALUETYPE_DOUBLE:
+ case ICMAP_VALUETYPE_STRING:
+ case ICMAP_VALUETYPE_BINARY:
+ err = CS_ERR_INVALID_PARAM;
+ break;
+ }
+
+ if (err == CS_OK) {
+ qb_map_put(map->qb_map, item->key_name, item);
+ }
+
+ return (err);
+}
+
+cs_error_t icmap_fast_adjust_int(
+ const char *key_name,
+ int32_t step)
+{
+
+ return (icmap_fast_adjust_int_r(icmap_global_map, key_name, step));
+}
+
+cs_error_t icmap_inc_r(const icmap_map_t map, const char *key_name)
+{
+ return (icmap_adjust_int_r(map, key_name, 1));
+}
+
+cs_error_t icmap_inc(const char *key_name)
+{
+ return (icmap_inc_r(icmap_global_map, key_name));
+}
+
+cs_error_t icmap_dec_r(const icmap_map_t map, const char *key_name)
+{
+ return (icmap_adjust_int_r(map, key_name, -1));
+}
+
+cs_error_t icmap_dec(const char *key_name)
+{
+ return (icmap_dec_r(icmap_global_map, key_name));
+}
+
+cs_error_t icmap_fast_inc_r(const icmap_map_t map, const char *key_name)
+{
+ return (icmap_fast_adjust_int_r(map, key_name, 1));
+}
+
+cs_error_t icmap_fast_inc(const char *key_name)
+{
+ return (icmap_fast_inc_r(icmap_global_map, key_name));
+}
+
+cs_error_t icmap_fast_dec_r(const icmap_map_t map, const char *key_name)
+{
+ return (icmap_fast_adjust_int_r(map, key_name, -1));
+}
+
+cs_error_t icmap_fast_dec(const char *key_name)
+{
+ return (icmap_fast_dec_r(icmap_global_map, key_name));
+}
+
+icmap_iter_t icmap_iter_init_r(const icmap_map_t map, const char *prefix)
+{
+ return (qb_map_pref_iter_create(map->qb_map, prefix));
+}
+
+icmap_iter_t icmap_iter_init(const char *prefix)
+{
+ return (icmap_iter_init_r(icmap_global_map, prefix));
+}
+
+
+const char *icmap_iter_next(icmap_iter_t iter, size_t *value_len, icmap_value_types_t *type)
+{
+ struct icmap_item *item;
+ const char *res;
+
+ res = qb_map_iter_next(iter, (void **)&item);
+ if (res == NULL) {
+ return (res);
+ }
+
+ if (value_len != NULL) {
+ *value_len = item->value_len;
+ }
+
+ if (type != NULL) {
+ *type = item->type;
+ }
+
+ return (res);
+}
+
+void icmap_iter_finalize(icmap_iter_t iter)
+{
+ qb_map_iter_free(iter);
+}
+
+static void icmap_notify_fn(uint32_t event, char *key, void *old_value, void *value, void *user_data)
+{
+ icmap_track_t icmap_track = (icmap_track_t)user_data;
+ struct icmap_item *new_item = (struct icmap_item *)value;
+ struct icmap_item *old_item = (struct icmap_item *)old_value;
+ struct icmap_notify_value new_val;
+ struct icmap_notify_value old_val;
+
+ if (value == NULL && old_value == NULL) {
+ return ;
+ }
+
+ if (new_item != NULL) {
+ new_val.type = new_item->type;
+ new_val.len = new_item->value_len;
+ new_val.data = new_item->value;
+ } else {
+ memset(&new_val, 0, sizeof(new_val));
+ }
+
+ /*
+ * old_item == new_item if fast functions are used -> don't fill old value
+ */
+ if (old_item != NULL && old_item != new_item) {
+ old_val.type = old_item->type;
+ old_val.len = old_item->value_len;
+ old_val.data = old_item->value;
+ } else {
+ memset(&old_val, 0, sizeof(old_val));
+ }
+
+ icmap_track->notify_fn(icmap_qbtt_to_tt(event),
+ key,
+ new_val,
+ old_val,
+ icmap_track->user_data);
+}
+
+cs_error_t icmap_track_add(
+ const char *key_name,
+ int32_t track_type,
+ icmap_notify_fn_t notify_fn,
+ void *user_data,
+ icmap_track_t *icmap_track)
+{
+ int32_t err;
+
+ if (notify_fn == NULL || icmap_track == NULL) {
+ return (CS_ERR_INVALID_PARAM);
+ }
+
+ if ((track_type & ~(ICMAP_TRACK_ADD | ICMAP_TRACK_DELETE | ICMAP_TRACK_MODIFY | ICMAP_TRACK_PREFIX)) != 0) {
+ return (CS_ERR_INVALID_PARAM);
+ }
+
+ *icmap_track = malloc(sizeof(**icmap_track));
+ if (*icmap_track == NULL) {
+ return (CS_ERR_NO_MEMORY);
+ }
+ memset(*icmap_track, 0, sizeof(**icmap_track));
+
+ if (key_name != NULL) {
+ (*icmap_track)->key_name = strdup(key_name);
+ };
+
+ (*icmap_track)->track_type = track_type;
+ (*icmap_track)->notify_fn = notify_fn;
+ (*icmap_track)->user_data = user_data;
+
+ if ((err = qb_map_notify_add(icmap_global_map->qb_map, (*icmap_track)->key_name, icmap_notify_fn,
+ icmap_tt_to_qbtt(track_type), *icmap_track)) != 0) {
+ free((*icmap_track)->key_name);
+ free(*icmap_track);
+
+ return (qb_to_cs_error(err));
+ }
+
+ qb_list_init(&(*icmap_track)->list);
+ qb_list_add (&(*icmap_track)->list, &icmap_track_list_head);
+
+ return (CS_OK);
+}
+
+cs_error_t icmap_track_delete(icmap_track_t icmap_track)
+{
+ int32_t err;
+
+ if ((err = qb_map_notify_del_2(icmap_global_map->qb_map, icmap_track->key_name,
+ icmap_notify_fn, icmap_tt_to_qbtt(icmap_track->track_type), icmap_track)) != 0) {
+ return (qb_to_cs_error(err));
+ }
+
+ qb_list_del(&icmap_track->list);
+ free(icmap_track->key_name);
+ free(icmap_track);
+
+ return (CS_OK);
+}
+
+void *icmap_track_get_user_data(icmap_track_t icmap_track)
+{
+ return (icmap_track->user_data);
+}
+
+cs_error_t icmap_set_ro_access(const char *key_name, int prefix, int ro_access)
+{
+ struct qb_list_head *iter, *tmp_iter;
+ struct icmap_ro_access_item *icmap_ro_ai;
+
+ qb_list_for_each_safe(iter, tmp_iter, &icmap_ro_access_item_list_head) {
+ icmap_ro_ai = qb_list_entry(iter, struct icmap_ro_access_item, list);
+
+ if (icmap_ro_ai->prefix == prefix && strcmp(key_name, icmap_ro_ai->key_name) == 0) {
+ /*
+ * We found item
+ */
+ if (ro_access) {
+ return (CS_ERR_EXIST);
+ } else {
+ qb_list_del(&icmap_ro_ai->list);
+ free(icmap_ro_ai->key_name);
+ free(icmap_ro_ai);
+
+ return (CS_OK);
+ }
+ }
+ }
+
+ if (!ro_access) {
+ return (CS_ERR_NOT_EXIST);
+ }
+
+ icmap_ro_ai = malloc(sizeof(*icmap_ro_ai));
+ if (icmap_ro_ai == NULL) {
+ return (CS_ERR_NO_MEMORY);
+ }
+
+ memset(icmap_ro_ai, 0, sizeof(*icmap_ro_ai));
+ icmap_ro_ai->key_name = strdup(key_name);
+ if (icmap_ro_ai->key_name == NULL) {
+ free(icmap_ro_ai);
+ return (CS_ERR_NO_MEMORY);
+ }
+
+ icmap_ro_ai->prefix = prefix;
+ qb_list_init(&icmap_ro_ai->list);
+ qb_list_add (&icmap_ro_ai->list, &icmap_ro_access_item_list_head);
+
+ return (CS_OK);
+}
+
+int icmap_is_key_ro(const char *key_name)
+{
+ struct qb_list_head *iter;
+ struct icmap_ro_access_item *icmap_ro_ai;
+
+ qb_list_for_each(iter, &icmap_ro_access_item_list_head) {
+ icmap_ro_ai = qb_list_entry(iter, struct icmap_ro_access_item, list);
+
+ if (icmap_ro_ai->prefix) {
+ if (strlen(icmap_ro_ai->key_name) > strlen(key_name))
+ continue;
+
+ if (strncmp(icmap_ro_ai->key_name, key_name, strlen(icmap_ro_ai->key_name)) == 0) {
+ return (CS_TRUE);
+ }
+ } else {
+ if (strcmp(icmap_ro_ai->key_name, key_name) == 0) {
+ return (CS_TRUE);
+ }
+ }
+ }
+
+ return (CS_FALSE);
+
+}
+
+cs_error_t icmap_copy_map(icmap_map_t dst_map, const icmap_map_t src_map)
+{
+ icmap_iter_t iter;
+ size_t value_len;
+ icmap_value_types_t value_type;
+ const char *key_name;
+ cs_error_t err;
+ void *value;
+
+ iter = icmap_iter_init_r(src_map, NULL);
+ if (iter == NULL) {
+ return (CS_ERR_NO_MEMORY);
+ }
+
+ err = CS_OK;
+
+ while ((key_name = icmap_iter_next(iter, &value_len, &value_type)) != NULL) {
+ err = icmap_get_ref_r(src_map, key_name, &value, &value_len, &value_type);
+ if (err != CS_OK) {
+ goto exit_iter_finalize;
+ }
+
+ err = icmap_set_r(dst_map, key_name, value, value_len, value_type);
+ if (err != CS_OK) {
+ goto exit_iter_finalize;
+ }
+ }
+
+exit_iter_finalize:
+ icmap_iter_finalize(iter);
+
+ return (err);
+}
diff --git a/exec/ipc_glue.c b/exec/ipc_glue.c
new file mode 100644
index 0000000..aa86e5c
--- /dev/null
+++ b/exec/ipc_glue.c
@@ -0,0 +1,829 @@
+/*
+ * Copyright (c) 2010-2017 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Author: Angus Salkeld <asalkeld@redhat.com>
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of Red Hat, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+#include <assert.h>
+#include <sys/uio.h>
+#include <string.h>
+
+#include <qb/qbdefs.h>
+#include <qb/qblist.h>
+#include <qb/qbutil.h>
+#include <qb/qbloop.h>
+#include <qb/qbipcs.h>
+
+#include <corosync/swab.h>
+#include <corosync/corotypes.h>
+#include <corosync/corodefs.h>
+#include <corosync/totem/totempg.h>
+#include <corosync/logsys.h>
+#include <corosync/icmap.h>
+
+#include "sync.h"
+#include "timer.h"
+#include "main.h"
+#include "util.h"
+#include "apidef.h"
+#include "service.h"
+#include "ipcs_stats.h"
+#include "stats.h"
+
+LOGSYS_DECLARE_SUBSYS ("MAIN");
+
+static struct corosync_api_v1 *api = NULL;
+static int32_t ipc_not_enough_fds_left = 0;
+static int32_t ipc_fc_is_quorate; /* boolean */
+static int32_t ipc_fc_totem_queue_level; /* percentage used */
+static int32_t ipc_fc_sync_in_process; /* boolean */
+static int32_t ipc_allow_connections = 0; /* boolean */
+
+#define CS_IPCS_MAPPER_SERV_NAME 256
+
+struct cs_ipcs_mapper {
+ int32_t id;
+ qb_ipcs_service_t *inst;
+ char name[CS_IPCS_MAPPER_SERV_NAME];
+};
+
+struct outq_item {
+ void *msg;
+ size_t mlen;
+ struct qb_list_head list;
+};
+
+static struct cs_ipcs_mapper ipcs_mapper[SERVICES_COUNT_MAX];
+
+static int32_t cs_ipcs_job_add(enum qb_loop_priority p, void *data, qb_loop_job_dispatch_fn fn);
+static int32_t cs_ipcs_dispatch_add(enum qb_loop_priority p, int32_t fd, int32_t events,
+ void *data, qb_ipcs_dispatch_fn_t fn);
+static int32_t cs_ipcs_dispatch_mod(enum qb_loop_priority p, int32_t fd, int32_t events,
+ void *data, qb_ipcs_dispatch_fn_t fn);
+static int32_t cs_ipcs_dispatch_del(int32_t fd);
+static void outq_flush (void *data);
+
+
+static struct qb_ipcs_poll_handlers corosync_poll_funcs = {
+ .job_add = cs_ipcs_job_add,
+ .dispatch_add = cs_ipcs_dispatch_add,
+ .dispatch_mod = cs_ipcs_dispatch_mod,
+ .dispatch_del = cs_ipcs_dispatch_del,
+};
+
+static int32_t cs_ipcs_connection_accept (qb_ipcs_connection_t *c, uid_t euid, gid_t egid);
+static void cs_ipcs_connection_created(qb_ipcs_connection_t *c);
+static int32_t cs_ipcs_msg_process(qb_ipcs_connection_t *c,
+ void *data, size_t size);
+static int32_t cs_ipcs_connection_closed (qb_ipcs_connection_t *c);
+static void cs_ipcs_connection_destroyed (qb_ipcs_connection_t *c);
+
+static struct qb_ipcs_service_handlers corosync_service_funcs = {
+ .connection_accept = cs_ipcs_connection_accept,
+ .connection_created = cs_ipcs_connection_created,
+ .msg_process = cs_ipcs_msg_process,
+ .connection_closed = cs_ipcs_connection_closed,
+ .connection_destroyed = cs_ipcs_connection_destroyed,
+};
+
+static struct ipcs_global_stats global_stats;
+
+static const char* cs_ipcs_serv_short_name(int32_t service_id)
+{
+ const char *name;
+ switch (service_id) {
+ case CFG_SERVICE:
+ name = "cfg";
+ break;
+ case CPG_SERVICE:
+ name = "cpg";
+ break;
+ case QUORUM_SERVICE:
+ name = "quorum";
+ break;
+ case PLOAD_SERVICE:
+ name = "pload";
+ break;
+ case VOTEQUORUM_SERVICE:
+ name = "votequorum";
+ break;
+ case MON_SERVICE:
+ name = "mon";
+ break;
+ case WD_SERVICE:
+ name = "wd";
+ break;
+ case CMAP_SERVICE:
+ name = "cmap";
+ break;
+ default:
+ name = NULL;
+ break;
+ }
+ return name;
+}
+
+void cs_ipc_allow_connections(int32_t allow)
+{
+ ipc_allow_connections = allow;
+}
+
+int32_t cs_ipcs_service_destroy(int32_t service_id)
+{
+ if (ipcs_mapper[service_id].inst) {
+ qb_ipcs_destroy(ipcs_mapper[service_id].inst);
+ ipcs_mapper[service_id].inst = NULL;
+ }
+ return 0;
+}
+
+static int32_t cs_ipcs_connection_accept (qb_ipcs_connection_t *c, uid_t euid, gid_t egid)
+{
+ int32_t service = qb_ipcs_service_id_get(c);
+ uint8_t u8;
+ char key_name[ICMAP_KEYNAME_MAXLEN];
+
+ if (!ipc_allow_connections) {
+ log_printf(LOGSYS_LEVEL_DEBUG, "Denied connection, corosync is not ready");
+ return -EAGAIN;
+ }
+
+ if (corosync_service[service] == NULL ||
+ ipcs_mapper[service].inst == NULL) {
+ return -ENOSYS;
+ }
+
+ if (ipc_not_enough_fds_left) {
+ return -EMFILE;
+ }
+
+ if (euid == 0 || egid == 0) {
+ return 0;
+ }
+
+ snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "uidgid.uid.%u", euid);
+ if (icmap_get_uint8(key_name, &u8) == CS_OK && u8 == 1)
+ return 0;
+
+ snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "uidgid.config.uid.%u", euid);
+ if (icmap_get_uint8(key_name, &u8) == CS_OK && u8 == 1)
+ return 0;
+
+ snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "uidgid.gid.%u", egid);
+ if (icmap_get_uint8(key_name, &u8) == CS_OK && u8 == 1)
+ return 0;
+
+ snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "uidgid.config.gid.%u", egid);
+ if (icmap_get_uint8(key_name, &u8) == CS_OK && u8 == 1)
+ return 0;
+
+ log_printf(LOGSYS_LEVEL_ERROR, "Denied connection attempt from %d:%d", euid, egid);
+
+ return -EACCES;
+}
+
+static char * pid_to_name (pid_t pid, char *out_name, size_t name_len)
+{
+ char *name;
+ char *rest;
+ FILE *fp;
+ char fname[32];
+ char buf[256];
+
+ snprintf (fname, 32, "/proc/%d/stat", pid);
+ fp = fopen (fname, "r");
+ if (!fp) {
+ return NULL;
+ }
+
+ if (fgets (buf, sizeof (buf), fp) == NULL) {
+ fclose (fp);
+ return NULL;
+ }
+ fclose (fp);
+
+ name = strrchr (buf, '(');
+ if (!name) {
+ return NULL;
+ }
+
+ /* move past the bracket */
+ name++;
+
+ rest = strrchr (buf, ')');
+
+ if (rest == NULL || rest[1] != ' ') {
+ return NULL;
+ }
+
+ *rest = '\0';
+ /* move past the NULL and space */
+ rest += 2;
+
+ /* copy the name */
+ strncpy (out_name, name, name_len - 1);
+ out_name[name_len - 1] = '\0';
+ return out_name;
+}
+
+static void cs_ipcs_connection_created(qb_ipcs_connection_t *c)
+{
+ int32_t service = 0;
+ struct cs_ipcs_conn_context *context;
+ struct qb_ipcs_connection_stats stats;
+ size_t size = sizeof(struct cs_ipcs_conn_context);
+
+ log_printf(LOG_DEBUG, "connection created");
+
+ service = qb_ipcs_service_id_get(c);
+
+ size += corosync_service[service]->private_data_size;
+ context = calloc(1, size);
+ if (context == NULL) {
+ qb_ipcs_disconnect(c);
+ return;
+ }
+
+ qb_list_init(&context->outq_head);
+ context->queuing = QB_FALSE;
+ context->queued = 0;
+ context->sent = 0;
+
+ qb_ipcs_context_set(c, context);
+
+ if (corosync_service[service]->lib_init_fn(c) != 0) {
+ log_printf(LOG_ERR, "lib_init_fn failed, disconnecting");
+ qb_ipcs_disconnect(c);
+ return;
+ }
+
+ qb_ipcs_connection_stats_get(c, &stats, QB_FALSE);
+
+ if (!pid_to_name (stats.client_pid, context->proc_name, sizeof(context->proc_name))) {
+ context->proc_name[0] = '\0';
+ }
+ stats_ipcs_add_connection(service, stats.client_pid, c);
+ global_stats.active++;
+}
+
+void cs_ipc_refcnt_inc(void *conn)
+{
+ qb_ipcs_connection_ref(conn);
+}
+
+void cs_ipc_refcnt_dec(void *conn)
+{
+ qb_ipcs_connection_unref(conn);
+}
+
+void *cs_ipcs_private_data_get(void *conn)
+{
+ struct cs_ipcs_conn_context *cnx;
+ cnx = qb_ipcs_context_get(conn);
+ return &cnx->data[0];
+}
+
+static void cs_ipcs_connection_destroyed (qb_ipcs_connection_t *c)
+{
+ struct cs_ipcs_conn_context *context;
+ struct qb_list_head *list, *tmp_iter;
+ struct outq_item *outq_item;
+
+ log_printf(LOG_DEBUG, "%s() ", __func__);
+
+ context = qb_ipcs_context_get(c);
+ if (context) {
+ qb_list_for_each_safe(list, tmp_iter, &(context->outq_head)) {
+ outq_item = qb_list_entry (list, struct outq_item, list);
+
+ qb_list_del (list);
+ free (outq_item->msg);
+ free (outq_item);
+ }
+ free(context);
+ }
+}
+
+static int32_t cs_ipcs_connection_closed (qb_ipcs_connection_t *c)
+{
+ int32_t res = 0;
+ int32_t service = qb_ipcs_service_id_get(c);
+ struct qb_ipcs_connection_stats stats;
+
+ log_printf(LOG_DEBUG, "%s() ", __func__);
+ res = corosync_service[service]->lib_exit_fn(c);
+ if (res != 0) {
+ return res;
+ }
+
+ qb_loop_job_del(cs_poll_handle_get(), QB_LOOP_HIGH, c, outq_flush);
+
+ qb_ipcs_connection_stats_get(c, &stats, QB_FALSE);
+
+ stats_ipcs_del_connection(service, stats.client_pid, c);
+
+ global_stats.active--;
+ global_stats.closed++;
+ return 0;
+}
+
+int cs_ipcs_response_iov_send (void *conn,
+ const struct iovec *iov,
+ unsigned int iov_len)
+{
+ int32_t rc = qb_ipcs_response_sendv(conn, iov, iov_len);
+ if (rc >= 0) {
+ return 0;
+ }
+ return rc;
+}
+
+int cs_ipcs_response_send(void *conn, const void *msg, size_t mlen)
+{
+ int32_t rc = qb_ipcs_response_send(conn, msg, mlen);
+ if (rc >= 0) {
+ return 0;
+ }
+ return rc;
+}
+
+static void outq_flush (void *data)
+{
+ qb_ipcs_connection_t *conn = data;
+ struct qb_list_head *list, *tmp_iter;
+ struct outq_item *outq_item;
+ int32_t rc;
+ struct cs_ipcs_conn_context *context = qb_ipcs_context_get(conn);
+
+ qb_list_for_each_safe(list, tmp_iter, &(context->outq_head)) {
+ outq_item = qb_list_entry (list, struct outq_item, list);
+
+ rc = qb_ipcs_event_send(conn, outq_item->msg, outq_item->mlen);
+ if (rc < 0 && rc != -EAGAIN) {
+ errno = -rc;
+ qb_perror(LOG_ERR, "qb_ipcs_event_send");
+ return;
+ } else if (rc == -EAGAIN) {
+ break;
+ }
+ assert(rc == outq_item->mlen);
+ context->sent++;
+ context->queued--;
+
+ qb_list_del (list);
+ free (outq_item->msg);
+ free (outq_item);
+ }
+ if (qb_list_empty (&context->outq_head)) {
+ context->queuing = QB_FALSE;
+ log_printf(LOGSYS_LEVEL_INFO, "Q empty, queued:%d sent:%d.",
+ context->queued, context->sent);
+ context->queued = 0;
+ context->sent = 0;
+ } else {
+ qb_loop_job_add(cs_poll_handle_get(), QB_LOOP_HIGH, conn, outq_flush);
+ }
+}
+
+static void msg_send_or_queue(qb_ipcs_connection_t *conn, const struct iovec *iov, uint32_t iov_len)
+{
+ int32_t rc = 0;
+ int32_t i;
+ int32_t bytes_msg = 0;
+ struct outq_item *outq_item;
+ char *write_buf = 0;
+ struct cs_ipcs_conn_context *context = qb_ipcs_context_get(conn);
+
+ for (i = 0; i < iov_len; i++) {
+ bytes_msg += iov[i].iov_len;
+ }
+
+ if (!context->queuing) {
+ assert(qb_list_empty (&context->outq_head));
+ rc = qb_ipcs_event_sendv(conn, iov, iov_len);
+ if (rc == bytes_msg) {
+ context->sent++;
+ return;
+ }
+ if (rc == -EAGAIN) {
+ context->queued = 0;
+ context->sent = 0;
+ context->queuing = QB_TRUE;
+ qb_loop_job_add(cs_poll_handle_get(), QB_LOOP_HIGH, conn, outq_flush);
+ } else {
+ log_printf(LOGSYS_LEVEL_ERROR, "event_send retuned %d, expected %d!", rc, bytes_msg);
+ return;
+ }
+ }
+ outq_item = malloc (sizeof (struct outq_item));
+ if (outq_item == NULL) {
+ qb_ipcs_disconnect(conn);
+ return;
+ }
+ outq_item->msg = malloc (bytes_msg);
+ if (outq_item->msg == NULL) {
+ free (outq_item);
+ qb_ipcs_disconnect(conn);
+ return;
+ }
+
+ write_buf = outq_item->msg;
+ for (i = 0; i < iov_len; i++) {
+ memcpy (write_buf, iov[i].iov_base, iov[i].iov_len);
+ write_buf += iov[i].iov_len;
+ }
+ outq_item->mlen = bytes_msg;
+ qb_list_init (&outq_item->list);
+ qb_list_add_tail (&outq_item->list, &context->outq_head);
+ context->queued++;
+}
+
+int cs_ipcs_dispatch_send(void *conn, const void *msg, size_t mlen)
+{
+ struct iovec iov;
+ iov.iov_base = (void *)msg;
+ iov.iov_len = mlen;
+ msg_send_or_queue (conn, &iov, 1);
+ return 0;
+}
+
+int cs_ipcs_dispatch_iov_send (void *conn,
+ const struct iovec *iov,
+ unsigned int iov_len)
+{
+ msg_send_or_queue(conn, iov, iov_len);
+ return 0;
+}
+
+static int32_t cs_ipcs_msg_process(qb_ipcs_connection_t *c,
+ void *data, size_t size)
+{
+ struct qb_ipc_response_header response;
+ struct qb_ipc_request_header *request_pt = (struct qb_ipc_request_header *)data;
+ int32_t service = qb_ipcs_service_id_get(c);
+ int32_t send_ok = 0;
+ int32_t is_async_call = QB_FALSE;
+ ssize_t res = -1;
+ int sending_allowed_private_data;
+ struct cs_ipcs_conn_context *cnx;
+
+ send_ok = corosync_sending_allowed (service,
+ request_pt->id,
+ request_pt,
+ &sending_allowed_private_data);
+
+ is_async_call = (service == CPG_SERVICE && request_pt->id == 2);
+
+ /*
+ * This happens when the message contains some kind of invalid
+ * parameter, such as an invalid size
+ */
+ if (send_ok == -EINVAL) {
+ response.size = sizeof (response);
+ response.id = 0;
+ response.error = CS_ERR_INVALID_PARAM;
+
+ cnx = qb_ipcs_context_get(c);
+ if (cnx) {
+ cnx->invalid_request++;
+ }
+
+ if (is_async_call) {
+ log_printf(LOGSYS_LEVEL_INFO, "*** %s() invalid message! size:%d error:%d",
+ __func__, response.size, response.error);
+ } else {
+ qb_ipcs_response_send (c,
+ &response,
+ sizeof (response));
+ }
+ res = -EINVAL;
+ } else if (send_ok < 0) {
+ cnx = qb_ipcs_context_get(c);
+ if (cnx) {
+ cnx->overload++;
+ }
+ if (!is_async_call) {
+ /*
+ * Overload, tell library to retry
+ */
+ response.size = sizeof (response);
+ response.id = 0;
+ response.error = CS_ERR_TRY_AGAIN;
+ qb_ipcs_response_send (c,
+ &response,
+ sizeof (response));
+ } else {
+ log_printf(LOGSYS_LEVEL_WARNING,
+ "*** %s() (%d:%d - %d) %s!",
+ __func__, service, request_pt->id,
+ is_async_call, strerror(-send_ok));
+ }
+ res = -ENOBUFS;
+ }
+
+ if (send_ok >= 0) {
+ corosync_service[service]->lib_engine[request_pt->id].lib_handler_fn(c, request_pt);
+ res = 0;
+ }
+ corosync_sending_allowed_release (&sending_allowed_private_data);
+ return res;
+}
+
+
+static int32_t cs_ipcs_job_add(enum qb_loop_priority p, void *data, qb_loop_job_dispatch_fn fn)
+{
+ return qb_loop_job_add(cs_poll_handle_get(), p, data, fn);
+}
+
+static int32_t cs_ipcs_dispatch_add(enum qb_loop_priority p, int32_t fd, int32_t events,
+ void *data, qb_ipcs_dispatch_fn_t fn)
+{
+ return qb_loop_poll_add(cs_poll_handle_get(), p, fd, events, data, fn);
+}
+
+static int32_t cs_ipcs_dispatch_mod(enum qb_loop_priority p, int32_t fd, int32_t events,
+ void *data, qb_ipcs_dispatch_fn_t fn)
+{
+ return qb_loop_poll_mod(cs_poll_handle_get(), p, fd, events, data, fn);
+}
+
+static int32_t cs_ipcs_dispatch_del(int32_t fd)
+{
+ return qb_loop_poll_del(cs_poll_handle_get(), fd);
+}
+
+static void cs_ipcs_low_fds_event(int32_t not_enough, int32_t fds_available)
+{
+ ipc_not_enough_fds_left = not_enough;
+ if (not_enough) {
+ log_printf(LOGSYS_LEVEL_WARNING, "refusing new connections (fds_available:%d)",
+ fds_available);
+ } else {
+ log_printf(LOGSYS_LEVEL_NOTICE, "allowing new connections (fds_available:%d)",
+ fds_available);
+
+ }
+}
+
+int32_t cs_ipcs_q_level_get(void)
+{
+ return ipc_fc_totem_queue_level;
+}
+
+static qb_loop_timer_handle ipcs_check_for_flow_control_timer;
+static void cs_ipcs_check_for_flow_control(void)
+{
+ int32_t i;
+ int32_t fc_enabled;
+
+ for (i = 0; i < SERVICES_COUNT_MAX; i++) {
+ if (corosync_service[i] == NULL || ipcs_mapper[i].inst == NULL) {
+ continue;
+ }
+ fc_enabled = QB_IPCS_RATE_OFF;
+ if (ipc_fc_is_quorate == 1 ||
+ corosync_service[i]->allow_inquorate == CS_LIB_ALLOW_INQUORATE) {
+ /*
+ * we are quorate
+ * now check flow control
+ */
+ if (ipc_fc_totem_queue_level != TOTEM_Q_LEVEL_CRITICAL &&
+ ipc_fc_sync_in_process == 0) {
+ fc_enabled = QB_FALSE;
+ } else if (ipc_fc_totem_queue_level != TOTEM_Q_LEVEL_CRITICAL &&
+ i == VOTEQUORUM_SERVICE) {
+ /*
+ * Allow message processing for votequorum service even
+ * in sync phase
+ */
+ fc_enabled = QB_FALSE;
+ } else {
+ fc_enabled = QB_IPCS_RATE_OFF_2;
+ }
+ }
+ if (fc_enabled) {
+ qb_ipcs_request_rate_limit(ipcs_mapper[i].inst, fc_enabled);
+
+ qb_loop_timer_add(cs_poll_handle_get(), QB_LOOP_MED, 1*QB_TIME_NS_IN_MSEC,
+ NULL, corosync_recheck_the_q_level, &ipcs_check_for_flow_control_timer);
+ } else if (ipc_fc_totem_queue_level == TOTEM_Q_LEVEL_LOW) {
+ qb_ipcs_request_rate_limit(ipcs_mapper[i].inst, QB_IPCS_RATE_FAST);
+ } else if (ipc_fc_totem_queue_level == TOTEM_Q_LEVEL_GOOD) {
+ qb_ipcs_request_rate_limit(ipcs_mapper[i].inst, QB_IPCS_RATE_NORMAL);
+ } else if (ipc_fc_totem_queue_level == TOTEM_Q_LEVEL_HIGH) {
+ qb_ipcs_request_rate_limit(ipcs_mapper[i].inst, QB_IPCS_RATE_SLOW);
+ }
+ }
+}
+
+static void cs_ipcs_fc_quorum_changed(int quorate, void *context)
+{
+ ipc_fc_is_quorate = quorate;
+ cs_ipcs_check_for_flow_control();
+}
+
+static void cs_ipcs_totem_queue_level_changed(enum totem_q_level level)
+{
+ ipc_fc_totem_queue_level = level;
+ cs_ipcs_check_for_flow_control();
+}
+
+void cs_ipcs_sync_state_changed(int32_t sync_in_process)
+{
+ ipc_fc_sync_in_process = sync_in_process;
+ cs_ipcs_check_for_flow_control();
+}
+
+void cs_ipcs_get_global_stats(struct ipcs_global_stats *ipcs_stats)
+{
+ memcpy(ipcs_stats, &global_stats, sizeof(global_stats));
+}
+
+cs_error_t cs_ipcs_get_conn_stats(int service_id, uint32_t pid, void *conn_ptr, struct ipcs_conn_stats *ipcs_stats)
+{
+ struct cs_ipcs_conn_context *cnx;
+ qb_ipcs_connection_t *c, *prev;
+ int found = 0;
+
+ if (corosync_service[service_id] == NULL || ipcs_mapper[service_id].inst == NULL) {
+ return CS_ERR_NOT_EXIST;
+ }
+
+ qb_ipcs_stats_get(ipcs_mapper[service_id].inst, &ipcs_stats->srv, QB_FALSE);
+
+ for (c = qb_ipcs_connection_first_get(ipcs_mapper[service_id].inst);
+ c;
+ prev = c, c = qb_ipcs_connection_next_get(ipcs_mapper[service_id].inst, prev), qb_ipcs_connection_unref(prev)) {
+
+ cnx = qb_ipcs_context_get(c);
+ if (cnx == NULL) continue;
+ if (c != conn_ptr) continue;
+
+ qb_ipcs_connection_stats_get(c, &ipcs_stats->conn, QB_FALSE);
+ if (ipcs_stats->conn.client_pid != pid) {
+ continue;
+ }
+ found = 1;
+ memcpy(&ipcs_stats->cnx, cnx, sizeof(struct cs_ipcs_conn_context));
+ }
+ if (!found) {
+ return CS_ERR_NOT_EXIST;
+ }
+
+ return CS_OK;
+}
+
+void cs_ipcs_clear_stats()
+{
+ struct cs_ipcs_conn_context *cnx;
+ struct ipcs_conn_stats ipcs_stats;
+ qb_ipcs_connection_t *c, *prev;
+ int service_id;
+
+ /* Global stats are easy */
+ memset(&global_stats, 0, sizeof(global_stats));
+
+ for (service_id = 0; service_id < SERVICES_COUNT_MAX; service_id++) {
+ if (!ipcs_mapper[service_id].inst) {
+ continue;
+ }
+
+ for (c = qb_ipcs_connection_first_get(ipcs_mapper[service_id].inst);
+ c;
+ prev = c, c = qb_ipcs_connection_next_get(ipcs_mapper[service_id].inst, prev), qb_ipcs_connection_unref(prev)) {
+ /* Get stats with 'clear_after_read' set */
+ qb_ipcs_connection_stats_get(c, &ipcs_stats.conn, QB_TRUE);
+
+ /* Our own stats */
+ cnx = qb_ipcs_context_get(c);
+ if (cnx == NULL) continue;
+ cnx->invalid_request = 0;
+ cnx->overload = 0;
+ cnx->sent = 0;
+
+ }
+ }
+}
+
+static enum qb_ipc_type cs_get_ipc_type (void)
+{
+ char *str;
+ int found = 0;
+ enum qb_ipc_type ret = QB_IPC_NATIVE;
+
+ if (icmap_get_string("system.qb_ipc_type", &str) != CS_OK) {
+ log_printf(LOGSYS_LEVEL_DEBUG, "No configured system.qb_ipc_type. Using native ipc");
+ return QB_IPC_NATIVE;
+ }
+
+ if (strcmp(str, "native") == 0) {
+ ret = QB_IPC_NATIVE;
+ found = 1;
+ }
+
+ if (strcmp(str, "shm") == 0) {
+ ret = QB_IPC_SHM;
+ found = 1;
+ }
+
+ if (strcmp(str, "socket") == 0) {
+ ret = QB_IPC_SOCKET;
+ found = 1;
+ }
+
+ if (found) {
+ log_printf(LOGSYS_LEVEL_DEBUG, "Using %s ipc", str);
+ } else {
+ log_printf(LOGSYS_LEVEL_DEBUG, "Unknown ipc type %s", str);
+ }
+
+ free(str);
+
+ return ret;
+}
+
+const char *cs_ipcs_service_init(struct corosync_service_engine *service)
+{
+ const char *serv_short_name;
+
+ serv_short_name = cs_ipcs_serv_short_name(service->id);
+
+ if (service->lib_engine_count == 0) {
+ log_printf (LOGSYS_LEVEL_DEBUG,
+ "NOT Initializing IPC on %s [%d]",
+ serv_short_name,
+ service->id);
+ return NULL;
+ }
+
+ if (strlen(serv_short_name) >= CS_IPCS_MAPPER_SERV_NAME) {
+ log_printf (LOGSYS_LEVEL_ERROR, "service name %s is too long", serv_short_name);
+ return "qb_ipcs_run error";
+ }
+
+ ipcs_mapper[service->id].id = service->id;
+ strcpy(ipcs_mapper[service->id].name, serv_short_name);
+ log_printf (LOGSYS_LEVEL_DEBUG,
+ "Initializing IPC on %s [%d]",
+ ipcs_mapper[service->id].name,
+ ipcs_mapper[service->id].id);
+ ipcs_mapper[service->id].inst = qb_ipcs_create(ipcs_mapper[service->id].name,
+ ipcs_mapper[service->id].id,
+ cs_get_ipc_type(),
+ &corosync_service_funcs);
+ assert(ipcs_mapper[service->id].inst);
+ qb_ipcs_poll_handlers_set(ipcs_mapper[service->id].inst,
+ &corosync_poll_funcs);
+ if (qb_ipcs_run(ipcs_mapper[service->id].inst) != 0) {
+ log_printf (LOGSYS_LEVEL_ERROR, "Can't initialize IPC");
+ return "qb_ipcs_run error";
+ }
+
+ return NULL;
+}
+
+void cs_ipcs_init(void)
+{
+ api = apidef_get ();
+
+ qb_loop_poll_low_fds_event_set(cs_poll_handle_get(), cs_ipcs_low_fds_event);
+
+ api->quorum_register_callback (cs_ipcs_fc_quorum_changed, NULL);
+ totempg_queue_level_register_callback (cs_ipcs_totem_queue_level_changed);
+
+ global_stats.active = 0;
+ global_stats.closed = 0;
+}
diff --git a/exec/ipcs_stats.h b/exec/ipcs_stats.h
new file mode 100644
index 0000000..a8047b3
--- /dev/null
+++ b/exec/ipcs_stats.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2017 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Authors: Christine Caulfield (ccaulfie@redhat.com)
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of the MontaVista Software, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+struct cs_ipcs_conn_context {
+ struct qb_list_head outq_head;
+ int32_t queuing;
+ uint32_t queued;
+ uint64_t invalid_request;
+ uint64_t overload;
+ uint32_t sent;
+ char proc_name[32];
+ char data[1];
+};
+
+struct ipcs_global_stats
+{
+ uint64_t active;
+ uint64_t closed;
+};
+
+struct ipcs_conn_stats
+{
+ struct qb_ipcs_stats srv;
+ struct qb_ipcs_connection_stats conn;
+ struct cs_ipcs_conn_context cnx;
+};
+
+cs_error_t cs_ipcs_get_conn_stats(int service_id, uint32_t pid, void *conn_ptr, struct ipcs_conn_stats *ipcs_stats);
+void cs_ipcs_get_global_stats(struct ipcs_global_stats *ipcs_stats);
+void cs_ipcs_clear_stats(void);
diff --git a/exec/logconfig.c b/exec/logconfig.c
new file mode 100644
index 0000000..350d8a9
--- /dev/null
+++ b/exec/logconfig.c
@@ -0,0 +1,757 @@
+/*
+ * Copyright (c) 2002-2005 MontaVista Software, Inc.
+ * Copyright (c) 2006-2011 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Author: Steven Dake (sdake@redhat.com)
+ * Jan Friesse (jfriesse@redhat.com)
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of the MontaVista Software, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include <corosync/totem/totem.h>
+#include <corosync/logsys.h>
+#ifdef LOGCONFIG_USE_ICMAP
+#include <corosync/icmap.h>
+#define MAP_KEYNAME_MAXLEN ICMAP_KEYNAME_MAXLEN
+#define map_get_string(key_name, value) icmap_get_string(key_name, value)
+#else
+#include <corosync/cmap.h>
+static cmap_handle_t cmap_handle;
+static const char *main_logfile;
+#define MAP_KEYNAME_MAXLEN CMAP_KEYNAME_MAXLEN
+#define map_get_string(key_name, value) cmap_get_string(cmap_handle, key_name, value)
+#endif
+
+#include "util.h"
+#include "logconfig.h"
+#include "totemknet.h"
+
+static char error_string_response[512];
+
+/**
+ * insert_into_buffer
+ * @target_buffer: a buffer where to write results
+ * @bufferlen: tell us the size of the buffer to avoid overflows
+ * @entry: entry that needs to be added to the buffer
+ * @after: can either be NULL or set to a string.
+ * if NULL, @entry is prependend to logsys_format_get buffer.
+ * if set, @entry is added immediately after @after.
+ *
+ * Since the function is specific to logsys_format_get handling, it is implicit
+ * that source is logsys_format_get();
+ *
+ * In case of failure, target_buffer could be left dirty. So don't trust
+ * any data leftover in it.
+ *
+ * Searching for "after" assumes that there is only entry of "after"
+ * in the source. Afterall we control the string here and for logging format
+ * it makes little to no sense to have duplicate format entries.
+ *
+ * Returns: 0 on success, -1 on failure
+ **/
+static int insert_into_buffer(
+ char *target_buffer,
+ size_t bufferlen,
+ const char *entry,
+ const char *after)
+{
+ const char *current_format = NULL;
+
+ current_format = logsys_format_get();
+
+ /* if the entry is already in the format we don't add it again */
+ if (strstr(current_format, entry) != NULL) {
+ return -1;
+ }
+
+ /* if there is no "after", simply prepend the requested entry
+ * otherwise go for beautiful string manipulation.... </sarcasm> */
+ if (!after) {
+ if (snprintf(target_buffer, bufferlen - 1, "%s%s",
+ entry,
+ current_format) >= bufferlen - 1) {
+ return -1;
+ }
+ } else {
+ const char *afterpos;
+ size_t afterlen;
+ size_t templen;
+
+ /* check if after is contained in the format
+ * and afterlen has a meaning or return an error */
+ afterpos = strstr(current_format, after);
+ afterlen = strlen(after);
+ if ((!afterpos) || (!afterlen)) {
+ return -1;
+ }
+
+ templen = afterpos - current_format + afterlen;
+ if (snprintf(target_buffer, templen + 1, "%s", current_format)
+ >= bufferlen - 1) {
+ return -1;
+ }
+ if (snprintf(target_buffer + templen, bufferlen - ( templen + 1 ),
+ "%s%s", entry, current_format + templen)
+ >= bufferlen - ( templen + 1 )) {
+ return -1;
+ }
+ }
+ return 0;
+}
+
+/*
+ * format set is global specific option that
+ * doesn't apply at system/subsystem level.
+ */
+static int corosync_main_config_format_set (
+ const char **error_string)
+{
+ const char *error_reason;
+ char new_format_buffer[PATH_MAX];
+ char *value = NULL;
+ int err = 0;
+ char timestamp_str_to_add[8];
+
+ if (map_get_string("logging.fileline", &value) == CS_OK) {
+ if (strcmp (value, "on") == 0) {
+ if (!insert_into_buffer(new_format_buffer,
+ sizeof(new_format_buffer),
+ " %f:%l", "g]")) {
+ err = logsys_format_set(new_format_buffer);
+ } else
+ if (!insert_into_buffer(new_format_buffer,
+ sizeof(new_format_buffer),
+ "%f:%l", NULL)) {
+ err = logsys_format_set(new_format_buffer);
+ }
+ } else
+ if (strcmp (value, "off") == 0) {
+ /* nothing to do here */
+ } else {
+ error_reason = "unknown value for fileline";
+ free(value);
+ goto parse_error;
+ }
+
+ free(value);
+ }
+
+ if (err) {
+ error_reason = "not enough memory to set logging format buffer";
+ goto parse_error;
+ }
+
+ if (map_get_string("logging.function_name", &value) == CS_OK) {
+ if (strcmp (value, "on") == 0) {
+ if (!insert_into_buffer(new_format_buffer,
+ sizeof(new_format_buffer),
+ "%n:", "f:")) {
+ err = logsys_format_set(new_format_buffer);
+ } else
+ if (!insert_into_buffer(new_format_buffer,
+ sizeof(new_format_buffer),
+ " %n", "g]")) {
+ err = logsys_format_set(new_format_buffer);
+ }
+ } else
+ if (strcmp (value, "off") == 0) {
+ /* nothing to do here */
+ } else {
+ error_reason = "unknown value for function_name";
+ free(value);
+ goto parse_error;
+ }
+
+ free(value);
+ }
+
+ if (err) {
+ error_reason = "not enough memory to set logging format buffer";
+ goto parse_error;
+ }
+
+ memset(timestamp_str_to_add, 0, sizeof(timestamp_str_to_add));
+
+ if (map_get_string("logging.timestamp", &value) == CS_OK) {
+ if (strcmp (value, "on") == 0) {
+ strcpy(timestamp_str_to_add, "%t");
+#ifdef QB_FEATURE_LOG_HIRES_TIMESTAMPS
+ } else if (strcmp (value, "hires") == 0) {
+ strcpy(timestamp_str_to_add, "%T");
+#endif
+ } else if (strcmp (value, "off") == 0) {
+ /* nothing to do here */
+ } else {
+ error_reason = "unknown value for timestamp";
+ free(value);
+ goto parse_error;
+ }
+
+ free(value);
+ } else {
+ /*
+ * Display hires timestamp by default, otherwise standard timestamp
+ */
+#ifdef QB_FEATURE_LOG_HIRES_TIMESTAMPS
+ strcpy(timestamp_str_to_add, "%T");
+#else
+ strcpy(timestamp_str_to_add, "%t");
+#endif
+ }
+
+ if(strcmp(timestamp_str_to_add, "") != 0) {
+ strcat(timestamp_str_to_add, " ");
+ if (insert_into_buffer(new_format_buffer, sizeof(new_format_buffer),
+ timestamp_str_to_add, NULL) == 0) {
+ err = logsys_format_set(new_format_buffer);
+ }
+ }
+
+ if (err) {
+ error_reason = "not enough memory to set logging format buffer";
+ goto parse_error;
+ }
+
+ return (0);
+
+parse_error:
+ *error_string = error_reason;
+
+ return (-1);
+}
+
+/*
+ * blackbox is another global specific option that
+ * doesn't apply at system/subsystem level.
+ */
+static int corosync_main_config_blackbox_set (
+ const char **error_string)
+{
+ const char *error_reason;
+ char *value = NULL;
+
+ if (map_get_string("logging.blackbox", &value) == CS_OK) {
+ if (strcmp (value, "on") == 0) {
+ (void)logsys_blackbox_set(QB_TRUE);
+ } else if (strcmp (value, "off") == 0) {
+ (void)logsys_blackbox_set(QB_FALSE);
+ } else {
+ error_reason = "unknown value for blackbox";
+ free(value);
+ goto parse_error;
+ }
+
+ free(value);
+ } else {
+ (void)logsys_blackbox_set(QB_TRUE);
+ }
+
+ return (0);
+
+parse_error:
+ *error_string = error_reason;
+
+ return (-1);
+}
+
+static int corosync_main_config_log_destination_set (
+ const char *path,
+ const char *key,
+ const char *subsys,
+ const char **error_string,
+ unsigned int mode_mask,
+ char deprecated,
+ char default_value,
+ const char *replacement)
+{
+ static char formatted_error_reason[128];
+ char *value = NULL;
+ unsigned int mode;
+ char key_name[MAP_KEYNAME_MAXLEN];
+
+ snprintf(key_name, MAP_KEYNAME_MAXLEN, "%s.%s", path, key);
+ if (map_get_string(key_name, &value) == CS_OK) {
+ if (deprecated) {
+ log_printf(LOGSYS_LEVEL_WARNING,
+ "Warning: the %s config parameter has been obsoleted."
+ " See corosync.conf man page %s directive.",
+ key, replacement);
+ }
+
+ mode = logsys_config_mode_get (subsys);
+
+ if (strcmp (value, "yes") == 0 || strcmp (value, "on") == 0) {
+ mode |= mode_mask;
+ if (logsys_config_mode_set(subsys, mode) < 0) {
+ sprintf (formatted_error_reason, "unable to set mode %s", key);
+ goto parse_error;
+ }
+ } else
+ if (strcmp (value, "no") == 0 || strcmp (value, "off") == 0) {
+ mode &= ~mode_mask;
+ if (logsys_config_mode_set(subsys, mode) < 0) {
+ sprintf (formatted_error_reason, "unable to unset mode %s", key);
+ goto parse_error;
+ }
+ } else {
+ sprintf (formatted_error_reason, "unknown value for %s", key);
+ goto parse_error;
+ }
+ }
+ /* Set to default if we are the top-level logger */
+ else if (!subsys && !deprecated) {
+
+ mode = logsys_config_mode_get (subsys);
+ if (default_value) {
+ mode |= mode_mask;
+ }
+ else {
+ mode &= ~mode_mask;
+ }
+ if (logsys_config_mode_set(subsys, mode) < 0) {
+ sprintf (formatted_error_reason, "unable to change mode %s", key);
+ goto parse_error;
+ }
+ }
+
+ free(value);
+ return (0);
+
+parse_error:
+ *error_string = formatted_error_reason;
+ free(value);
+ return (-1);
+}
+
+static int corosync_main_config_set (
+ const char *path,
+ const char *subsys,
+ const char **error_string)
+{
+ const char *error_reason = error_string_response;
+ char *value = NULL;
+ int mode;
+ char key_name[MAP_KEYNAME_MAXLEN];
+
+ /*
+ * this bit abuses the internal logsys exported API
+ * to guarantee that all configured subsystems are
+ * initialized too.
+ *
+ * using this approach avoids some headaches caused
+ * by IPC and TOTEM that have a special logging
+ * handling requirements
+ */
+ if (subsys != NULL) {
+ if (_logsys_subsys_create(subsys, NULL) < 0) {
+ error_reason = "unable to create new logging subsystem";
+ goto parse_error;
+ }
+ }
+
+ mode = logsys_config_mode_get(subsys);
+ if (mode < 0) {
+ error_reason = "unable to get mode";
+ goto parse_error;
+ }
+
+ if (corosync_main_config_log_destination_set (path, "to_stderr", subsys, &error_reason,
+ LOGSYS_MODE_OUTPUT_STDERR, 0, 1, NULL) != 0)
+ goto parse_error;
+
+ if (corosync_main_config_log_destination_set (path, "to_syslog", subsys, &error_reason,
+ LOGSYS_MODE_OUTPUT_SYSLOG, 0, 1, NULL) != 0)
+ goto parse_error;
+
+ snprintf(key_name, MAP_KEYNAME_MAXLEN, "%s.%s", path, "syslog_facility");
+ if (map_get_string(key_name, &value) == CS_OK) {
+ int syslog_facility;
+
+ syslog_facility = qb_log_facility2int(value);
+ if (syslog_facility < 0) {
+ error_reason = "unknown syslog facility specified";
+ goto parse_error;
+ }
+ if (logsys_config_syslog_facility_set(subsys,
+ syslog_facility) < 0) {
+ error_reason = "unable to set syslog facility";
+ goto parse_error;
+ }
+
+ free(value);
+ }
+ else {
+ /* Set default here in case of a reload */
+ if (logsys_config_syslog_facility_set(subsys,
+ qb_log_facility2int("daemon")) < 0) {
+ error_reason = "unable to set syslog facility";
+ goto parse_error;
+ }
+ }
+
+ snprintf(key_name, MAP_KEYNAME_MAXLEN, "%s.%s", path, "syslog_level");
+ if (map_get_string(key_name, &value) == CS_OK) {
+ int syslog_priority;
+
+ log_printf(LOGSYS_LEVEL_WARNING,
+ "Warning: the syslog_level config parameter has been obsoleted."
+ " See corosync.conf man page syslog_priority directive.");
+
+ syslog_priority = logsys_priority_id_get(value);
+ free(value);
+
+ if (syslog_priority < 0) {
+ error_reason = "unknown syslog level specified";
+ goto parse_error;
+ }
+ if (logsys_config_syslog_priority_set(subsys,
+ syslog_priority) < 0) {
+ error_reason = "unable to set syslog level";
+ goto parse_error;
+ }
+ }
+
+ snprintf(key_name, MAP_KEYNAME_MAXLEN, "%s.%s", path, "syslog_priority");
+ if (map_get_string(key_name, &value) == CS_OK) {
+ int syslog_priority;
+
+ syslog_priority = logsys_priority_id_get(value);
+ free(value);
+ if (syslog_priority < 0) {
+ error_reason = "unknown syslog priority specified";
+ goto parse_error;
+ }
+ if (logsys_config_syslog_priority_set(subsys,
+ syslog_priority) < 0) {
+ error_reason = "unable to set syslog priority";
+ goto parse_error;
+ }
+ }
+ else if(strcmp(key_name, "logging.syslog_priority") == 0){
+ if (logsys_config_syslog_priority_set(subsys,
+ logsys_priority_id_get("info")) < 0) {
+ error_reason = "unable to set syslog level";
+ goto parse_error;
+ }
+ }
+
+#ifdef LOGCONFIG_USE_ICMAP
+ snprintf(key_name, MAP_KEYNAME_MAXLEN, "%s.%s", path, "logfile");
+ if (map_get_string(key_name, &value) == CS_OK) {
+ if (logsys_config_file_set (subsys, &error_reason, value) < 0) {
+ goto parse_error;
+ }
+ free(value);
+ }
+#else
+ if (!subsys) {
+ if (logsys_config_file_set (subsys, &error_reason, main_logfile) < 0) {
+ goto parse_error;
+ }
+ }
+#endif
+
+ if (corosync_main_config_log_destination_set (path, "to_file", subsys, &error_reason,
+ LOGSYS_MODE_OUTPUT_FILE, 1, 0, "to_logfile") != 0)
+ goto parse_error;
+
+ if (corosync_main_config_log_destination_set (path, "to_logfile", subsys, &error_reason,
+ LOGSYS_MODE_OUTPUT_FILE, 0, 0, NULL) != 0)
+ goto parse_error;
+
+ snprintf(key_name, MAP_KEYNAME_MAXLEN, "%s.%s", path, "logfile_priority");
+ if (map_get_string(key_name, &value) == CS_OK) {
+ int logfile_priority;
+
+ logfile_priority = logsys_priority_id_get(value);
+ free(value);
+ if (logfile_priority < 0) {
+ error_reason = "unknown logfile priority specified";
+ goto parse_error;
+ }
+ if (logsys_config_logfile_priority_set(subsys,
+ logfile_priority) < 0) {
+ error_reason = "unable to set logfile priority";
+ goto parse_error;
+ }
+ }
+ else if(strcmp(key_name,"logging.logfile_priority") == 0){
+ if (logsys_config_logfile_priority_set(subsys,
+ logsys_priority_id_get("info")) < 0) {
+ error_reason = "unable to set syslog level";
+ goto parse_error;
+ }
+ }
+
+ snprintf(key_name, MAP_KEYNAME_MAXLEN, "%s.%s", path, "debug");
+ if (map_get_string(key_name, &value) == CS_OK) {
+ if (strcmp (value, "trace") == 0) {
+ if (logsys_config_debug_set (subsys, LOGSYS_DEBUG_TRACE) < 0) {
+ error_reason = "unable to set debug trace";
+ free(value);
+ goto parse_error;
+ }
+ } else
+ if (strcmp (value, "on") == 0) {
+ if (logsys_config_debug_set (subsys, LOGSYS_DEBUG_ON) < 0) {
+ error_reason = "unable to set debug on";
+ free(value);
+ goto parse_error;
+ }
+ } else
+ if (strcmp (value, "off") == 0) {
+ if (logsys_config_debug_set (subsys, LOGSYS_DEBUG_OFF) < 0) {
+ error_reason = "unable to set debug off";
+ free(value);
+ goto parse_error;
+ }
+ } else {
+ error_reason = "unknown value for debug";
+ free(value);
+ goto parse_error;
+ }
+ free(value);
+ }
+ else {
+ if (logsys_config_debug_set (subsys, LOGSYS_DEBUG_OFF) < 0) {
+ error_reason = "unable to set debug off";
+ goto parse_error;
+ }
+ }
+
+ return (0);
+
+parse_error:
+ *error_string = error_reason;
+
+ return (-1);
+}
+
+static int corosync_main_config_read_logging (
+ const char **error_string)
+{
+ const char *error_reason;
+#ifdef LOGCONFIG_USE_ICMAP
+ icmap_iter_t iter;
+ const char *key_name;
+#else
+ cmap_iter_handle_t iter;
+ char key_name[CMAP_KEYNAME_MAXLEN];
+#endif
+ char key_subsys[MAP_KEYNAME_MAXLEN];
+ char key_item[MAP_KEYNAME_MAXLEN];
+ int res;
+
+ /* format set is supported only for toplevel */
+ if (corosync_main_config_format_set(&error_reason) < 0) {
+ goto parse_error;
+ }
+
+ if (corosync_main_config_blackbox_set(&error_reason) < 0) {
+ goto parse_error;
+ }
+
+ if (corosync_main_config_set ("logging", NULL, &error_reason) < 0) {
+ goto parse_error;
+ }
+
+ /*
+ * we will need 2 of these to compensate for new logging
+ * config format
+ */
+#ifdef LOGCONFIG_USE_ICMAP
+ iter = icmap_iter_init("logging.logger_subsys.");
+ while ((key_name = icmap_iter_next(iter, NULL, NULL)) != NULL) {
+#else
+ cmap_iter_init(cmap_handle, "logging.logger_subsys.", &iter);
+ while ((cmap_iter_next(cmap_handle, iter, key_name, NULL, NULL)) == CS_OK) {
+#endif
+ res = sscanf(key_name, "logging.logger_subsys.%[^.].%s", key_subsys, key_item);
+
+ if (res != 2) {
+ continue ;
+ }
+
+ if (strcmp(key_item, "subsys") != 0) {
+ continue ;
+ }
+
+ if (snprintf(key_item, MAP_KEYNAME_MAXLEN, "logging.logger_subsys.%s",
+ key_subsys) >= MAP_KEYNAME_MAXLEN) {
+ /*
+ * This should never happen
+ */
+ error_reason = "Can't snprintf logger_subsys key_item";
+ goto parse_error;
+ }
+
+ if (corosync_main_config_set(key_item, key_subsys, &error_reason) < 0) {
+ goto parse_error;
+ }
+ }
+#ifdef LOGCONFIG_USE_ICMAP
+ icmap_iter_finalize(iter);
+#else
+ cmap_iter_finalize(cmap_handle, iter);
+#endif
+
+ logsys_config_apply();
+
+ /* Reconfigure knet logging */
+ totemknet_configure_log_level();
+ return 0;
+
+parse_error:
+ *error_string = error_reason;
+
+ return (-1);
+}
+
+#ifdef LOGCONFIG_USE_ICMAP
+static void main_logging_notify(
+ int32_t event,
+ const char *key_name,
+ struct icmap_notify_value new_val,
+ struct icmap_notify_value old_val,
+ void *user_data)
+#else
+static void main_logging_notify(
+ cmap_handle_t cmap_handle_unused,
+ cmap_handle_t cmap_track_handle_unused,
+ int32_t event,
+ const char *key_name,
+ struct cmap_notify_value new_val,
+ struct cmap_notify_value old_val,
+ void *user_data)
+#endif
+{
+ const char *error_string;
+ static int reload_in_progress = 0;
+
+ /* If a full reload happens then suspend updates for individual keys until
+ * it's all completed
+ */
+ if (strcmp(key_name, "config.reload_in_progress") == 0) {
+ if (*(uint8_t *)new_val.data == 1) {
+ reload_in_progress = 1;
+ } else {
+ reload_in_progress = 0;
+ }
+ }
+ if (reload_in_progress) {
+ log_printf(LOGSYS_LEVEL_DEBUG, "Ignoring key change, reload in progress. %s\n", key_name);
+ return;
+ }
+
+ /*
+ * Reload the logsys configuration
+ */
+ if (logsys_format_set(NULL) == -1) {
+ fprintf (stderr, "Unable to setup logging format.\n");
+ }
+ corosync_main_config_read_logging(&error_string);
+}
+
+#ifdef LOGCONFIG_USE_ICMAP
+static void add_logsys_config_notification(void)
+{
+ icmap_track_t icmap_track = NULL;
+
+ icmap_track_add("logging.",
+ ICMAP_TRACK_ADD | ICMAP_TRACK_DELETE | ICMAP_TRACK_MODIFY | ICMAP_TRACK_PREFIX,
+ main_logging_notify,
+ NULL,
+ &icmap_track);
+
+ icmap_track_add("config.reload_in_progress",
+ ICMAP_TRACK_ADD | ICMAP_TRACK_MODIFY,
+ main_logging_notify,
+ NULL,
+ &icmap_track);
+}
+#else
+static void add_logsys_config_notification(void)
+{
+ cmap_track_handle_t cmap_track;
+
+ cmap_track_add(cmap_handle, "logging.",
+ CMAP_TRACK_ADD | CMAP_TRACK_DELETE | CMAP_TRACK_MODIFY | CMAP_TRACK_PREFIX,
+ main_logging_notify,
+ NULL,
+ &cmap_track);
+
+ cmap_track_add(cmap_handle, "config.reload_in_progress",
+ CMAP_TRACK_ADD | CMAP_TRACK_MODIFY,
+ main_logging_notify,
+ NULL,
+ &cmap_track);
+}
+#endif
+
+int corosync_log_config_read (
+#ifndef LOGCONFIG_USE_ICMAP
+ cmap_handle_t cmap_h,
+ const char *default_logfile,
+#endif
+ const char **error_string)
+{
+ const char *error_reason = error_string_response;
+
+#ifndef LOGCONFIG_USE_ICMAP
+ if (!cmap_h) {
+ error_reason = "No cmap handle";
+ return (-1);
+ }
+ if (!default_logfile) {
+ error_reason = "No default logfile";
+ return (-1);
+ }
+ cmap_handle = cmap_h;
+ main_logfile = default_logfile;
+#endif
+
+ if (corosync_main_config_read_logging(error_string) < 0) {
+ error_reason = *error_string;
+ goto parse_error;
+ }
+
+ add_logsys_config_notification();
+
+ return 0;
+
+parse_error:
+ snprintf (error_string_response, sizeof(error_string_response),
+ "parse error in config: %s.\n",
+ error_reason);
+
+ *error_string = error_string_response;
+ return (-1);
+}
diff --git a/exec/logconfig.h b/exec/logconfig.h
new file mode 100644
index 0000000..14305ad
--- /dev/null
+++ b/exec/logconfig.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2002-2005 MontaVista Software, Inc.
+ * Copyright (c) 2006-2012 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Author: Steven Dake (sdake@redhat.com)
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of the MontaVista Software, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef LOGCONFIG_H_DEFINED
+#define LOGCONFIG_H_DEFINED
+
+#include <corosync/logsys.h>
+#include <corosync/coroapi.h>
+#include <corosync/cmap.h>
+
+/**
+ * All service handlers
+ */
+struct dynamic_service {
+ char *name;
+ unsigned int ver;
+ unsigned int handle;
+};
+#define MAX_DYNAMIC_SERVICES 128
+
+#ifdef LOGCONFIG_USE_ICMAP
+extern int corosync_log_config_read (
+ const char **error_string);
+#else
+extern int corosync_log_config_read (
+ cmap_handle_t cmap_h,
+ const char *default_logfile,
+ const char **error_string);
+#endif
+
+#endif /* LOGCONFIG_H_DEFINED */
diff --git a/exec/logsys.c b/exec/logsys.c
new file mode 100644
index 0000000..30a4ee6
--- /dev/null
+++ b/exec/logsys.c
@@ -0,0 +1,952 @@
+/*
+ * Copyright (c) 2002-2004 MontaVista Software, Inc.
+ * Copyright (c) 2006-2012 Red Hat, Inc.
+ *
+ * Author: Steven Dake (sdake@redhat.com)
+ * Author: Lon Hohberger (lhh@redhat.com)
+ * Author: Fabio M. Di Nitto (fdinitto@redhat.com)
+ *
+ * All rights reserved.
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of the MontaVista Software, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include <stdint.h>
+#include <ctype.h>
+#include <assert.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <qb/qbdefs.h>
+#include <qb/qbutil.h>
+#include <qb/qblog.h>
+
+#include <corosync/logsys.h>
+
+/*
+ * syslog prioritynames, facility names to value mapping
+ * Some C libraries build this in to their headers, but it is non-portable
+ * so logsys supplies its own version.
+ */
+struct syslog_names {
+ const char *c_name;
+ int c_val;
+};
+
+static struct syslog_names prioritynames[] =
+{
+ { "alert", LOG_ALERT },
+ { "crit", LOG_CRIT },
+ { "debug", LOG_DEBUG },
+ { "emerg", LOG_EMERG },
+ { "err", LOG_ERR },
+ { "error", LOG_ERR },
+ { "info", LOG_INFO },
+ { "notice", LOG_NOTICE },
+ { "warning", LOG_WARNING },
+ { NULL, -1 }
+};
+
+#define MAX_FILES_PER_SUBSYS 32
+#ifdef HAVE_SMALL_MEMORY_FOOTPRINT
+#define IPC_LOGSYS_SIZE 8192*64
+#else
+#define IPC_LOGSYS_SIZE 8192*1024
+#endif
+
+/*
+ * need unlogical order to preserve 64bit alignment
+ */
+struct logsys_logger {
+ char subsys[LOGSYS_MAX_SUBSYS_NAMELEN]; /* subsystem name */
+ char *logfile; /* log to file */
+ unsigned int mode; /* subsystem mode */
+ unsigned int debug; /* debug on|off|trace */
+ int syslog_priority; /* priority */
+ int logfile_priority; /* priority to file */
+ int init_status; /* internal field to handle init queues
+ for subsystems */
+ int32_t target_id;
+ char *files[MAX_FILES_PER_SUBSYS];
+ int32_t file_idx;
+ int32_t dirty;
+};
+
+/* values for logsys_logger init_status */
+#define LOGSYS_LOGGER_INIT_DONE 0
+#define LOGSYS_LOGGER_NEEDS_INIT 1
+
+static int logsys_system_needs_init = LOGSYS_LOGGER_NEEDS_INIT;
+
+static struct logsys_logger logsys_loggers[LOGSYS_MAX_SUBSYS_COUNT + 1];
+
+static pthread_mutex_t logsys_config_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+static int32_t _logsys_config_mode_set_unlocked(int32_t subsysid, uint32_t new_mode);
+static void _logsys_config_apply_per_file(int32_t s, const char *filename);
+static void _logsys_config_apply_per_subsys(int32_t s);
+static void _logsys_subsys_filename_add (int32_t s, const char *filename);
+static void logsys_file_format_get(char* file_format, int buf_len);
+
+static char *format_buffer=NULL;
+
+static int logsys_thread_started = 0;
+
+static int logsys_blackbox_enabled = 1;
+
+static int _logsys_config_subsys_get_unlocked (const char *subsys)
+{
+ unsigned int i;
+
+ if (!subsys) {
+ return LOGSYS_MAX_SUBSYS_COUNT;
+ }
+
+ for (i = 0; i <= LOGSYS_MAX_SUBSYS_COUNT; i++) {
+ if (strcmp (logsys_loggers[i].subsys, subsys) == 0) {
+ return i;
+ }
+ }
+
+ return (-1);
+}
+
+
+/*
+ * we need a version that can work when somebody else is already
+ * holding a config mutex lock or we will never get out of here
+ */
+static int logsys_config_file_set_unlocked (
+ int subsysid,
+ const char **error_string,
+ const char *file)
+{
+ static char error_string_response[512];
+ int i;
+ char file_format[128];
+
+ if (logsys_loggers[subsysid].target_id > 0) {
+ int32_t f;
+ for (f = 0; f < logsys_loggers[subsysid].file_idx; f++) {
+ qb_log_filter_ctl(logsys_loggers[subsysid].target_id,
+ QB_LOG_FILTER_REMOVE,
+ QB_LOG_FILTER_FILE,
+ logsys_loggers[subsysid].files[f],
+ LOG_TRACE);
+ }
+ }
+
+ logsys_loggers[subsysid].dirty = QB_TRUE;
+ if (file == NULL) {
+ return (0);
+ }
+
+ if (logsys_loggers[subsysid].target_id > 0 &&
+ logsys_loggers[subsysid].logfile != NULL &&
+ strcmp(file, logsys_loggers[subsysid].logfile) == 0) {
+ return (0);
+ }
+
+ if (strlen(file) >= PATH_MAX) {
+ snprintf (error_string_response,
+ sizeof(error_string_response),
+ "%s: logfile name exceed maximum system filename length",
+ logsys_loggers[subsysid].subsys);
+ *error_string = error_string_response;
+ return (-1);
+ }
+
+ if (logsys_loggers[subsysid].logfile != NULL) {
+ free(logsys_loggers[subsysid].logfile);
+ logsys_loggers[subsysid].logfile = NULL;
+ }
+
+ logsys_loggers[subsysid].logfile = strdup(file);
+
+ if (logsys_loggers[subsysid].logfile == NULL) {
+ snprintf (error_string_response,
+ sizeof(error_string_response),
+ "Unable to allocate memory for logfile '%s'",
+ file);
+ *error_string = error_string_response;
+ return (-1);
+ }
+
+ for (i = 0; i <= LOGSYS_MAX_SUBSYS_COUNT; i++) {
+ if ((logsys_loggers[i].logfile != NULL) &&
+ (strcmp (logsys_loggers[i].logfile, file) == 0) &&
+ (i != subsysid)) {
+ /* we have found another subsys with this config file
+ * so add a filter
+ */
+ logsys_loggers[subsysid].target_id = logsys_loggers[i].target_id;
+ return (0);
+ }
+ }
+
+ if (logsys_loggers[subsysid].target_id > 0) {
+ int num_using_current = 0;
+ for (i = 0; i <= LOGSYS_MAX_SUBSYS_COUNT; i++) {
+ if (logsys_loggers[subsysid].target_id ==
+ logsys_loggers[i].target_id) {
+ num_using_current++;
+ }
+ }
+ if (num_using_current == 1) {
+ /* no one else is using this close it */
+ qb_log_file_close(logsys_loggers[subsysid].target_id);
+ }
+ }
+
+ logsys_loggers[subsysid].target_id = qb_log_file_open(file);
+ if (logsys_loggers[subsysid].target_id < 0) {
+ int err = -logsys_loggers[subsysid].target_id;
+ char error_str[LOGSYS_MAX_PERROR_MSG_LEN];
+ const char *error_ptr;
+ error_ptr = qb_strerror_r(err, error_str, sizeof(error_str));
+
+ free(logsys_loggers[subsysid].logfile);
+ logsys_loggers[subsysid].logfile = NULL;
+ snprintf (error_string_response,
+ sizeof(error_string_response),
+ "Can't open logfile '%s' for reason: %s (%d)",
+ file, error_ptr, err);
+ *error_string = error_string_response;
+ return (-1);
+ }
+ logsys_file_format_get(file_format, 128);
+ qb_log_format_set(logsys_loggers[subsysid].target_id, file_format);
+
+ qb_log_ctl(logsys_loggers[subsysid].target_id,
+ QB_LOG_CONF_ENABLED,
+ (logsys_loggers[subsysid].mode & LOGSYS_MODE_OUTPUT_FILE));
+ if (logsys_thread_started) {
+ qb_log_ctl(logsys_loggers[subsysid].target_id, QB_LOG_CONF_THREADED, QB_TRUE);
+ }
+
+ return (0);
+}
+
+static void logsys_subsys_init (
+ const char *subsys,
+ int subsysid)
+{
+ if (logsys_system_needs_init == LOGSYS_LOGGER_NEEDS_INIT) {
+ logsys_loggers[subsysid].init_status =
+ LOGSYS_LOGGER_NEEDS_INIT;
+ } else {
+ logsys_loggers[subsysid].mode = logsys_loggers[LOGSYS_MAX_SUBSYS_COUNT].mode;
+ logsys_loggers[subsysid].debug = logsys_loggers[LOGSYS_MAX_SUBSYS_COUNT].debug;
+ logsys_loggers[subsysid].syslog_priority = logsys_loggers[LOGSYS_MAX_SUBSYS_COUNT].syslog_priority;
+ logsys_loggers[subsysid].logfile_priority = logsys_loggers[LOGSYS_MAX_SUBSYS_COUNT].logfile_priority;
+ logsys_loggers[subsysid].init_status = LOGSYS_LOGGER_INIT_DONE;
+ }
+ strncpy (logsys_loggers[subsysid].subsys, subsys,
+ sizeof (logsys_loggers[subsysid].subsys));
+ logsys_loggers[subsysid].subsys[
+ sizeof (logsys_loggers[subsysid].subsys) - 1] = '\0';
+ logsys_loggers[subsysid].file_idx = 0;
+}
+
+static const char *_logsys_tags_stringify(uint32_t tags)
+{
+ if (tags == QB_LOG_TAG_LIBQB_MSG) {
+ return "QB";
+ } else {
+ return logsys_loggers[tags].subsys;
+ }
+}
+
+void logsys_system_fini (void)
+{
+ int i;
+ int f;
+ for (i = 0; i < LOGSYS_MAX_SUBSYS_COUNT; i++) {
+ free(logsys_loggers[i].logfile);
+ for (f = 0; f < logsys_loggers[i].file_idx; f++) {
+ free(logsys_loggers[i].files[f]);
+ }
+ }
+
+ qb_log_fini ();
+}
+
+/*
+ * Internal API - exported
+ */
+
+int _logsys_system_setup(
+ const char *mainsystem,
+ unsigned int mode,
+ int syslog_facility,
+ int syslog_priority)
+{
+ int i;
+ int32_t fidx;
+ char tempsubsys[LOGSYS_MAX_SUBSYS_NAMELEN];
+
+ if ((mainsystem == NULL) ||
+ (strlen(mainsystem) >= LOGSYS_MAX_SUBSYS_NAMELEN)) {
+ return -1;
+ }
+
+ /*
+ * Setup libqb as a subsys
+ */
+ i = _logsys_subsys_create ("QB", "array.c,log.c,log_syslog.c,log_blackbox.c,log_format.c,"
+ "log_file.c,log_dcs.c,log_thread.c,ipc_shm.c,ipcs.c,ipc_us.c,loop.c,"
+ "loop_poll_epoll.c,loop_job.c,loop_poll_poll.c,loop_poll_kqueue.c,"
+ "loop_timerlist.c,loop_poll.c,ringbuffer.c,ringbuffer_helper.c,trie.c,"
+ "map.c,skiplist.c,rpl_sem.c,hdb.c,unix.c,hashtable.c,strlcpy.c,ipc_socket.c,"
+ "strchrnul.c,ipc_setup.c,strlcat.c");
+ if (i < 0) {
+ return -1;
+ }
+
+ /*
+ * name clash
+ * _logsys_subsys_filename_add (i, "util.c");
+ */
+
+ /*
+ * This file (logsys.c) is not exactly QB. We need tag for logsys.c if flightrecorder init
+ * fails, and QB seems to be closest.
+ */
+ _logsys_subsys_filename_add (i, "logsys.c");
+
+ i = LOGSYS_MAX_SUBSYS_COUNT;
+
+ pthread_mutex_lock (&logsys_config_mutex);
+
+ snprintf(logsys_loggers[i].subsys,
+ LOGSYS_MAX_SUBSYS_NAMELEN,
+ "%s", mainsystem);
+
+ logsys_loggers[i].mode = mode;
+ logsys_loggers[i].debug = LOGSYS_DEBUG_OFF;
+ logsys_loggers[i].file_idx = 0;
+ logsys_loggers[i].logfile_priority = syslog_priority;
+ logsys_loggers[i].syslog_priority = syslog_priority;
+
+ qb_log_init(mainsystem, syslog_facility, syslog_priority);
+ if (logsys_loggers[i].mode & LOGSYS_MODE_OUTPUT_STDERR) {
+ qb_log_ctl(QB_LOG_STDERR, QB_LOG_CONF_ENABLED, QB_TRUE);
+ } else {
+ qb_log_ctl(QB_LOG_STDERR, QB_LOG_CONF_ENABLED, QB_FALSE);
+ }
+ if (logsys_loggers[i].mode & LOGSYS_MODE_OUTPUT_SYSLOG) {
+ qb_log_ctl(QB_LOG_SYSLOG, QB_LOG_CONF_ENABLED, QB_TRUE);
+ } else {
+ qb_log_ctl(QB_LOG_SYSLOG, QB_LOG_CONF_ENABLED, QB_FALSE);
+ }
+ qb_log_ctl(QB_LOG_SYSLOG, QB_LOG_CONF_PRIORITY_BUMP, LOG_INFO - LOG_DEBUG);
+
+ qb_log_filter_ctl(QB_LOG_BLACKBOX, QB_LOG_FILTER_ADD,
+ QB_LOG_FILTER_FILE, "*", LOG_TRACE);
+ qb_log_ctl(QB_LOG_BLACKBOX, QB_LOG_CONF_SIZE, IPC_LOGSYS_SIZE);
+ qb_log_ctl(QB_LOG_BLACKBOX, QB_LOG_CONF_THREADED, QB_FALSE);
+
+ /*
+ * Blackbox is disabled at the init and enabled later based
+ * on config (logging.blackbox) value.
+ */
+ qb_log_ctl(QB_LOG_BLACKBOX, QB_LOG_CONF_ENABLED, QB_FALSE);
+
+ if (logsys_format_set(NULL) == -1) {
+ pthread_mutex_unlock (&logsys_config_mutex);
+
+ return -1;
+ }
+
+ qb_log_tags_stringify_fn_set(_logsys_tags_stringify);
+
+ logsys_loggers[i].init_status = LOGSYS_LOGGER_INIT_DONE;
+ logsys_system_needs_init = LOGSYS_LOGGER_INIT_DONE;
+
+ for (i = 0; i < LOGSYS_MAX_SUBSYS_COUNT; i++) {
+ if ((strcmp (logsys_loggers[i].subsys, "") != 0) &&
+ (logsys_loggers[i].init_status ==
+ LOGSYS_LOGGER_NEEDS_INIT)) {
+ fidx = logsys_loggers[i].file_idx;
+ strncpy (tempsubsys, logsys_loggers[i].subsys,
+ sizeof (tempsubsys));
+ tempsubsys[sizeof (tempsubsys) - 1] = '\0';
+ logsys_subsys_init(tempsubsys, i);
+ logsys_loggers[i].file_idx = fidx;
+ _logsys_config_mode_set_unlocked(i, logsys_loggers[i].mode);
+ _logsys_config_apply_per_subsys(i);
+ }
+ }
+
+ pthread_mutex_unlock (&logsys_config_mutex);
+
+ return (0);
+}
+
+
+static void _logsys_subsys_filename_add (int32_t s, const char *filename)
+{
+ int i;
+
+ if (filename == NULL) {
+ return;
+ }
+ assert(logsys_loggers[s].file_idx < MAX_FILES_PER_SUBSYS);
+ assert(logsys_loggers[s].file_idx >= 0);
+
+ for (i = 0; i < logsys_loggers[s].file_idx; i++) {
+ if (strcmp(logsys_loggers[s].files[i], filename) == 0) {
+ return;
+ }
+ }
+ logsys_loggers[s].files[logsys_loggers[s].file_idx++] = strdup(filename);
+
+ if (logsys_system_needs_init == LOGSYS_LOGGER_INIT_DONE) {
+ _logsys_config_apply_per_file(s, filename);
+ }
+}
+
+int _logsys_subsys_create (const char *subsys, const char *filename)
+{
+ int i;
+
+ if ((subsys == NULL) ||
+ (strlen(subsys) >= LOGSYS_MAX_SUBSYS_NAMELEN)) {
+ return -1;
+ }
+
+ pthread_mutex_lock (&logsys_config_mutex);
+
+ i = _logsys_config_subsys_get_unlocked (subsys);
+ if ((i > -1) && (i < LOGSYS_MAX_SUBSYS_COUNT)) {
+ _logsys_subsys_filename_add(i, filename);
+ pthread_mutex_unlock (&logsys_config_mutex);
+ return i;
+ }
+
+ for (i = 0; i < LOGSYS_MAX_SUBSYS_COUNT; i++) {
+ if (strcmp (logsys_loggers[i].subsys, "") == 0) {
+ logsys_subsys_init(subsys, i);
+ _logsys_subsys_filename_add(i, filename);
+ break;
+ }
+ }
+
+ if (i >= LOGSYS_MAX_SUBSYS_COUNT) {
+ i = -1;
+ }
+
+ pthread_mutex_unlock (&logsys_config_mutex);
+ return i;
+}
+
+int _logsys_config_subsys_get (const char *subsys)
+{
+ unsigned int i;
+
+ pthread_mutex_lock (&logsys_config_mutex);
+
+ i = _logsys_config_subsys_get_unlocked (subsys);
+
+ pthread_mutex_unlock (&logsys_config_mutex);
+
+ return i;
+}
+
+static int32_t _logsys_config_mode_set_unlocked(int32_t subsysid, uint32_t new_mode)
+{
+ if ( logsys_loggers[subsysid].mode == new_mode) {
+ return 0;
+ }
+ if (logsys_loggers[subsysid].target_id > 0) {
+ qb_log_ctl(logsys_loggers[subsysid].target_id,
+ QB_LOG_CONF_ENABLED,
+ (new_mode & LOGSYS_MODE_OUTPUT_FILE));
+ }
+
+ if (subsysid == LOGSYS_MAX_SUBSYS_COUNT) {
+ qb_log_ctl(QB_LOG_STDERR,
+ QB_LOG_CONF_ENABLED,
+ (new_mode & LOGSYS_MODE_OUTPUT_STDERR));
+ qb_log_ctl(QB_LOG_SYSLOG,
+ QB_LOG_CONF_ENABLED,
+ (new_mode & LOGSYS_MODE_OUTPUT_SYSLOG));
+ }
+ logsys_loggers[subsysid].mode = new_mode;
+ return 0;
+}
+
+int logsys_config_mode_set (const char *subsys, unsigned int mode)
+{
+ int i;
+
+ pthread_mutex_lock (&logsys_config_mutex);
+ if (subsys != NULL) {
+ i = _logsys_config_subsys_get_unlocked (subsys);
+ if (i >= 0) {
+ i = _logsys_config_mode_set_unlocked(i, mode);
+ }
+ } else {
+ for (i = 0; i <= LOGSYS_MAX_SUBSYS_COUNT; i++) {
+ _logsys_config_mode_set_unlocked(i, mode);
+ }
+ i = 0;
+ }
+
+ pthread_mutex_unlock (&logsys_config_mutex);
+
+ return i;
+}
+
+unsigned int logsys_config_mode_get (const char *subsys)
+{
+ int i;
+
+ i = _logsys_config_subsys_get (subsys);
+ if (i < 0) {
+ return i;
+ }
+
+ return logsys_loggers[i].mode;
+}
+
+int logsys_config_file_set (
+ const char *subsys,
+ const char **error_string,
+ const char *file)
+{
+ int i;
+ int res;
+
+ pthread_mutex_lock (&logsys_config_mutex);
+
+ if (subsys != NULL) {
+ i = _logsys_config_subsys_get_unlocked (subsys);
+ if (i < 0) {
+ res = i;
+ } else {
+ res = logsys_config_file_set_unlocked(i, error_string, file);
+ }
+ } else {
+ for (i = 0; i <= LOGSYS_MAX_SUBSYS_COUNT; i++) {
+ res = logsys_config_file_set_unlocked(i, error_string, file);
+ if (res < 0) {
+ break;
+ }
+ }
+ }
+
+ pthread_mutex_unlock (&logsys_config_mutex);
+ return res;
+}
+
+static void
+logsys_file_format_get(char* file_format, int buf_len)
+{
+ char *format_buffer_start;
+ char *str_pos;
+
+ file_format[0] = '\0';
+
+ format_buffer_start = format_buffer;
+
+ if ((str_pos = strstr(format_buffer, "%t"))) {
+ strcpy(file_format, "%t ");
+ format_buffer_start = str_pos + 2;
+ }
+
+ if ((str_pos = strstr(format_buffer, "%T"))) {
+ strcpy(file_format, "%T ");
+ format_buffer_start = str_pos + 2;
+ }
+
+ strcat(file_format, "[%P] %H %N");
+ strncat(file_format, format_buffer_start, buf_len - strlen(file_format));
+}
+
+int logsys_format_set (const char *format)
+{
+ int i;
+ int c;
+ int w;
+ int reminder;
+ char syslog_format[128];
+ char file_format[128];
+
+ if (format_buffer) {
+ free(format_buffer);
+ format_buffer = NULL;
+ }
+
+ format_buffer = strdup(format ? format : "%7p [%6g] %b");
+ if (format_buffer == NULL) {
+ return -1;
+ }
+
+ qb_log_format_set(QB_LOG_STDERR, format_buffer);
+
+ logsys_file_format_get(file_format, 128);
+ for (i = 0; i <= LOGSYS_MAX_SUBSYS_COUNT; i++) {
+ if (logsys_loggers[i].target_id > 0) {
+ qb_log_format_set(logsys_loggers[i].target_id, file_format);
+ }
+ }
+
+ /*
+ * This just goes through and remove %t, %T and %p from
+ * the format string for syslog.
+ */
+ w = 0;
+ memset(syslog_format, '\0', sizeof(syslog_format));
+ for (c = 0; c < strlen(format_buffer); c++) {
+ if (format_buffer[c] == '%') {
+ reminder = c;
+ for (c++; c < strlen(format_buffer); c++) {
+ if (isdigit(format_buffer[c])) {
+ continue;
+ }
+ if (format_buffer[c] == 't' ||
+ format_buffer[c] == 'p' ||
+ format_buffer[c] == 'T') {
+ c++;
+ } else {
+ c = reminder;
+ }
+ break;
+ }
+ }
+ syslog_format[w] = format_buffer[c];
+ w++;
+ }
+ qb_log_format_set(QB_LOG_SYSLOG, syslog_format);
+
+ return 0;
+}
+
+char *logsys_format_get (void)
+{
+ return format_buffer;
+}
+
+int logsys_config_syslog_facility_set (
+ const char *subsys,
+ unsigned int facility)
+{
+ return qb_log_ctl(QB_LOG_SYSLOG, QB_LOG_CONF_FACILITY, facility);
+}
+
+int logsys_config_syslog_priority_set (
+ const char *subsys,
+ unsigned int priority)
+{
+ int i;
+
+ pthread_mutex_lock (&logsys_config_mutex);
+ if (subsys != NULL) {
+ i = _logsys_config_subsys_get_unlocked (subsys);
+ if (i >= 0) {
+ logsys_loggers[i].syslog_priority = priority;
+ logsys_loggers[i].dirty = QB_TRUE;
+
+ i = 0;
+ }
+ } else {
+ for (i = 0; i <= LOGSYS_MAX_SUBSYS_COUNT; i++) {
+ logsys_loggers[i].syslog_priority = priority;
+ logsys_loggers[i].dirty = QB_TRUE;
+ }
+ i = 0;
+ }
+ pthread_mutex_unlock (&logsys_config_mutex);
+
+ return i;
+}
+
+int logsys_config_logfile_priority_set (
+ const char *subsys,
+ unsigned int priority)
+{
+ int i;
+
+ pthread_mutex_lock (&logsys_config_mutex);
+ if (subsys != NULL) {
+ i = _logsys_config_subsys_get_unlocked (subsys);
+ if (i >= 0) {
+ logsys_loggers[i].logfile_priority = priority;
+ logsys_loggers[i].dirty = QB_TRUE;
+ i = 0;
+ }
+ } else {
+ for (i = 0; i <= LOGSYS_MAX_SUBSYS_COUNT; i++) {
+ logsys_loggers[i].logfile_priority = priority;
+ logsys_loggers[i].dirty = QB_TRUE;
+ }
+ i = 0;
+ }
+ pthread_mutex_unlock (&logsys_config_mutex);
+
+ return i;
+}
+
+
+static void _logsys_config_apply_per_file(int32_t s, const char *filename)
+{
+ uint32_t syslog_priority = logsys_loggers[s].syslog_priority;
+ uint32_t logfile_priority = logsys_loggers[s].logfile_priority;
+
+ qb_log_filter_ctl(s, QB_LOG_TAG_SET, QB_LOG_FILTER_FILE,
+ filename, LOG_TRACE);
+
+ qb_log_filter_ctl(QB_LOG_SYSLOG, QB_LOG_FILTER_REMOVE,
+ QB_LOG_FILTER_FILE, filename, LOG_TRACE);
+ qb_log_filter_ctl(QB_LOG_STDERR, QB_LOG_FILTER_REMOVE,
+ QB_LOG_FILTER_FILE, filename, LOG_TRACE);
+ if (logsys_loggers[s].target_id > 0) {
+ qb_log_filter_ctl(logsys_loggers[s].target_id,
+ QB_LOG_FILTER_REMOVE,
+ QB_LOG_FILTER_FILE, filename, LOG_TRACE);
+ }
+
+ if (logsys_loggers[s].debug != LOGSYS_DEBUG_OFF) {
+ switch (logsys_loggers[s].debug) {
+ case LOGSYS_DEBUG_ON:
+ syslog_priority = LOG_DEBUG;
+ logfile_priority = LOG_DEBUG;
+ break;
+ case LOGSYS_DEBUG_TRACE:
+ syslog_priority = LOG_TRACE;
+ logfile_priority = LOG_TRACE;
+ break;
+ default:
+ assert(0);
+ }
+ }
+ qb_log_filter_ctl(QB_LOG_SYSLOG, QB_LOG_FILTER_ADD,
+ QB_LOG_FILTER_FILE, filename,
+ syslog_priority);
+ qb_log_filter_ctl(QB_LOG_STDERR, QB_LOG_FILTER_ADD,
+ QB_LOG_FILTER_FILE, filename,
+ logfile_priority);
+ if (logsys_loggers[s].target_id > 0) {
+ qb_log_filter_ctl(logsys_loggers[s].target_id,
+ QB_LOG_FILTER_ADD,
+ QB_LOG_FILTER_FILE, filename,
+ logfile_priority);
+ }
+}
+
+static void _logsys_config_apply_per_subsys(int32_t s)
+{
+ int32_t f;
+ for (f = 0; f < logsys_loggers[s].file_idx; f++) {
+ _logsys_config_apply_per_file(s, logsys_loggers[s].files[f]);
+ }
+ if (logsys_loggers[s].target_id > 0) {
+ qb_log_ctl(logsys_loggers[s].target_id,
+ QB_LOG_CONF_ENABLED,
+ (logsys_loggers[s].mode & LOGSYS_MODE_OUTPUT_FILE));
+ }
+ logsys_loggers[s].dirty = QB_FALSE;
+}
+
+static void _logsys_config_apply_blackbox(void) {
+ int blackbox_enable_res;
+
+ blackbox_enable_res = qb_log_ctl(QB_LOG_BLACKBOX, QB_LOG_CONF_ENABLED, logsys_blackbox_enabled);
+
+ if (blackbox_enable_res < 0) {
+ LOGSYS_PERROR (-blackbox_enable_res, LOGSYS_LEVEL_WARNING,
+ "Unable to initialize log flight recorder. "\
+ "The most common cause of this error is " \
+ "not enough space on /dev/shm. Corosync will continue work, " \
+ "but blackbox will not be available");
+ }
+}
+
+void logsys_config_apply(void)
+{
+ int32_t s;
+
+ _logsys_config_apply_blackbox();
+
+ for (s = 0; s <= LOGSYS_MAX_SUBSYS_COUNT; s++) {
+ if (strcmp(logsys_loggers[s].subsys, "") == 0) {
+ continue;
+ }
+ _logsys_config_apply_per_subsys(s);
+ }
+}
+
+extern int logsys_config_debug_get (
+ const char *subsys)
+{
+ int debug_level = logsys_loggers[0].debug;
+ int i;
+
+ if (subsys != NULL) {
+ pthread_mutex_lock (&logsys_config_mutex);
+ i = _logsys_config_subsys_get_unlocked (subsys);
+ if (i >= 0) {
+ debug_level = logsys_loggers[i].debug;
+ }
+ pthread_mutex_unlock (&logsys_config_mutex);
+ }
+ return debug_level;
+}
+
+int logsys_config_debug_set (
+ const char *subsys,
+ unsigned int debug)
+{
+ int i;
+
+ pthread_mutex_lock (&logsys_config_mutex);
+ if (subsys != NULL) {
+ i = _logsys_config_subsys_get_unlocked (subsys);
+ if (i >= 0) {
+ logsys_loggers[i].dirty = QB_TRUE;
+ logsys_loggers[i].debug = debug;
+ i = 0;
+ }
+ } else {
+ for (i = 0; i <= LOGSYS_MAX_SUBSYS_COUNT; i++) {
+ logsys_loggers[i].debug = debug;
+ logsys_loggers[i].dirty = QB_TRUE;
+ }
+ i = 0;
+ }
+ pthread_mutex_unlock (&logsys_config_mutex);
+
+ return i;
+}
+
+int logsys_priority_id_get (const 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);
+}
+
+int logsys_thread_start (void)
+{
+ int i;
+ int err;
+
+ err = qb_log_thread_start();
+ if (err != 0) {
+ return (err);
+ }
+
+ qb_log_ctl(QB_LOG_SYSLOG, QB_LOG_CONF_THREADED, QB_TRUE);
+ for (i = 0; i <= LOGSYS_MAX_SUBSYS_COUNT; i++) {
+ if (logsys_loggers[i].target_id > 0) {
+ qb_log_ctl(logsys_loggers[i].target_id, QB_LOG_CONF_THREADED, QB_TRUE);
+ }
+ }
+
+ logsys_thread_started = 1;
+
+ return (0);
+}
+
+void logsys_blackbox_set(int enable)
+{
+
+ pthread_mutex_lock (&logsys_config_mutex);
+
+ logsys_blackbox_enabled = enable;
+
+ pthread_mutex_unlock (&logsys_config_mutex);
+}
+
+/*
+ * To set correct pid to qb blackbox filename after tty dettach (fork) we have to
+ * close (this function) and (if needed) reopen blackbox (logsys_blackbox_postfork function).
+ */
+void logsys_blackbox_prefork(void)
+{
+
+ (void)qb_log_ctl(QB_LOG_BLACKBOX, QB_LOG_CONF_ENABLED, QB_FALSE);
+}
+
+void logsys_blackbox_postfork(void)
+{
+
+ _logsys_config_apply_blackbox();
+}
+
+cs_error_t logsys_reopen_log_files(void)
+{
+ cs_error_t res;
+
+#ifdef HAVE_QB_LOG_FILE_REOPEN
+ int i, j;
+ int num_using_current;
+ int32_t rc;
+
+ res = CS_OK;
+
+ pthread_mutex_lock (&logsys_config_mutex);
+
+ for (i = 0; i <= LOGSYS_MAX_SUBSYS_COUNT; i++) {
+ if (logsys_loggers[i].target_id <= 0 || logsys_loggers[i].logfile == NULL) {
+ continue ;
+ }
+
+ num_using_current = 0;
+ for (j = 0; j <= i; j++) {
+ if (logsys_loggers[i].target_id == logsys_loggers[j].target_id) {
+ num_using_current++;
+ }
+ }
+ if (num_using_current == 1) {
+ /*
+ * First instance of target file. Reopen it.
+ */
+ rc = qb_log_file_reopen(logsys_loggers[i].target_id, NULL);
+ if (rc != 0) {
+ LOGSYS_PERROR (-rc, LOGSYS_LEVEL_WARNING,
+ "Unable to reopen log file %s", logsys_loggers[i].logfile);
+ res = qb_to_cs_error(rc);
+ }
+ }
+ }
+
+ pthread_mutex_unlock (&logsys_config_mutex);
+#else
+ res = CS_ERR_NOT_SUPPORTED;
+#endif
+
+ return (res);
+}
diff --git a/exec/main.c b/exec/main.c
new file mode 100644
index 0000000..977aaf5
--- /dev/null
+++ b/exec/main.c
@@ -0,0 +1,1666 @@
+/*
+ * Copyright (c) 2002-2006 MontaVista Software, Inc.
+ * Copyright (c) 2006-2021 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Author: Steven Dake (sdake@redhat.com)
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of the MontaVista Software, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * \mainpage Corosync
+ *
+ * This is the doxygen generated developer documentation for the Corosync
+ * project. For more information about Corosync, please see the project
+ * web site, <a href="http://www.corosync.org">corosync.org</a>.
+ *
+ * \section license License
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of the MontaVista Software, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include <pthread.h>
+#include <assert.h>
+#include <sys/types.h>
+#include <sys/file.h>
+#include <sys/poll.h>
+#include <sys/uio.h>
+#include <sys/mman.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <sys/stat.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+#include <signal.h>
+#include <sched.h>
+#include <time.h>
+#include <semaphore.h>
+#include <string.h>
+
+#ifdef HAVE_LIBSYSTEMD
+#include <systemd/sd-daemon.h>
+#endif
+
+#include <qb/qbdefs.h>
+#include <qb/qblog.h>
+#include <qb/qbloop.h>
+#include <qb/qbutil.h>
+#include <qb/qbipcs.h>
+
+#include <corosync/swab.h>
+#include <corosync/corotypes.h>
+#include <corosync/corodefs.h>
+#include <corosync/totem/totempg.h>
+#include <corosync/logsys.h>
+#include <corosync/icmap.h>
+
+#include "quorum.h"
+#include "totemsrp.h"
+#include "logconfig.h"
+#include "totemconfig.h"
+#include "main.h"
+#include "sync.h"
+#include "timer.h"
+#include "util.h"
+#include "apidef.h"
+#include "service.h"
+#include "schedwrk.h"
+#include "ipcs_stats.h"
+#include "stats.h"
+
+#ifdef HAVE_SMALL_MEMORY_FOOTPRINT
+#define IPC_LOGSYS_SIZE 1024*64
+#else
+#define IPC_LOGSYS_SIZE 8192*128
+#endif
+
+/*
+ * LibQB adds default "*" syslog filter so we have to set syslog_priority as low
+ * as possible so filters applied later in _logsys_config_apply_per_file takes
+ * effect.
+ */
+LOGSYS_DECLARE_SYSTEM ("corosync",
+ LOGSYS_MODE_OUTPUT_STDERR | LOGSYS_MODE_OUTPUT_SYSLOG,
+ LOG_DAEMON,
+ LOG_EMERG);
+
+LOGSYS_DECLARE_SUBSYS ("MAIN");
+
+#define SERVER_BACKLOG 5
+
+static int sched_priority = 0;
+
+static unsigned int service_count = 32;
+
+static struct totem_logging_configuration totem_logging_configuration;
+
+static struct corosync_api_v1 *api = NULL;
+
+static int sync_in_process = 1;
+
+static qb_loop_t *corosync_poll_handle;
+
+struct sched_param global_sched_param;
+
+static corosync_timer_handle_t corosync_stats_timer_handle;
+
+static const char *corosync_lock_file = LOCALSTATEDIR"/run/corosync.pid";
+
+static char corosync_config_file[PATH_MAX + 1] = COROSYSCONFDIR "/corosync.conf";
+
+static int lockfile_fd = -1;
+
+enum move_to_root_cgroup_mode {
+ MOVE_TO_ROOT_CGROUP_MODE_OFF = 0,
+ MOVE_TO_ROOT_CGROUP_MODE_ON = 1,
+ MOVE_TO_ROOT_CGROUP_MODE_AUTO = 2,
+};
+
+qb_loop_t *cs_poll_handle_get (void)
+{
+ return (corosync_poll_handle);
+}
+
+int cs_poll_dispatch_add (qb_loop_t * handle,
+ int fd,
+ int events,
+ void *data,
+
+ int (*dispatch_fn) (int fd,
+ int revents,
+ void *data))
+{
+ return qb_loop_poll_add(handle, QB_LOOP_MED, fd, events, data,
+ dispatch_fn);
+}
+
+int cs_poll_dispatch_delete(qb_loop_t * handle, int fd)
+{
+ return qb_loop_poll_del(handle, fd);
+}
+
+void corosync_state_dump (void)
+{
+ int i;
+
+ for (i = 0; i < SERVICES_COUNT_MAX; i++) {
+ if (corosync_service[i] && corosync_service[i]->exec_dump_fn) {
+ corosync_service[i]->exec_dump_fn ();
+ }
+ }
+}
+
+const char *corosync_get_config_file(void)
+{
+
+ return (corosync_config_file);
+}
+
+static void corosync_blackbox_write_to_file (void)
+{
+ char fname[PATH_MAX];
+ char fdata_fname[PATH_MAX];
+ char time_str[PATH_MAX];
+ struct tm cur_time_tm;
+ time_t cur_time_t;
+ ssize_t res;
+
+ cur_time_t = time(NULL);
+ localtime_r(&cur_time_t, &cur_time_tm);
+
+ strftime(time_str, PATH_MAX, "%Y-%m-%dT%H:%M:%S", &cur_time_tm);
+ if (snprintf(fname, PATH_MAX, "%s/fdata-%s-%lld",
+ get_state_dir(),
+ time_str,
+ (long long int)getpid()) >= PATH_MAX) {
+ log_printf(LOGSYS_LEVEL_ERROR, "Can't snprintf blackbox file name");
+ return ;
+ }
+
+ if ((res = qb_log_blackbox_write_to_file(fname)) < 0) {
+ LOGSYS_PERROR(-res, LOGSYS_LEVEL_ERROR, "Can't store blackbox file");
+ return ;
+ }
+ snprintf(fdata_fname, sizeof(fdata_fname), "%s/fdata", get_state_dir());
+ unlink(fdata_fname);
+ if (symlink(fname, fdata_fname) == -1) {
+ log_printf(LOGSYS_LEVEL_ERROR, "Can't create symlink to '%s' for corosync blackbox file '%s'",
+ fname, fdata_fname);
+ }
+}
+
+static void unlink_all_completed (void)
+{
+ api->timer_delete (corosync_stats_timer_handle);
+ qb_loop_stop (corosync_poll_handle);
+ icmap_fini();
+}
+
+void corosync_shutdown_request (void)
+{
+ corosync_service_unlink_all (api, unlink_all_completed);
+}
+
+static int32_t sig_diag_handler (int num, void *data)
+{
+ corosync_state_dump ();
+ return 0;
+}
+
+static int32_t sig_exit_handler (int num, void *data)
+{
+ log_printf(LOGSYS_LEVEL_NOTICE, "Node was shut down by a signal");
+ corosync_service_unlink_all (api, unlink_all_completed);
+ return 0;
+}
+
+static void sigsegv_handler (int num)
+{
+ (void)signal (num, SIG_DFL);
+ corosync_blackbox_write_to_file ();
+ qb_log_fini();
+ raise (num);
+}
+
+#define LOCALHOST_IP inet_addr("127.0.0.1")
+
+static void *corosync_group_handle;
+
+static struct totempg_group corosync_group = {
+ .group = "a",
+ .group_len = 1
+};
+
+static void serialize_lock (void)
+{
+}
+
+static void serialize_unlock (void)
+{
+}
+
+static void corosync_sync_completed (void)
+{
+ log_printf (LOGSYS_LEVEL_NOTICE,
+ "Completed service synchronization, ready to provide service.");
+ sync_in_process = 0;
+
+ cs_ipcs_sync_state_changed(sync_in_process);
+ cs_ipc_allow_connections(1);
+ /*
+ * Inform totem to start using new message queue again
+ */
+ totempg_trans_ack();
+
+#ifdef HAVE_LIBSYSTEMD
+ sd_notify (0, "READY=1");
+#endif
+}
+
+static int corosync_sync_callbacks_retrieve (
+ int service_id,
+ struct sync_callbacks *callbacks)
+{
+ if (corosync_service[service_id] == NULL) {
+ return (-1);
+ }
+
+ if (callbacks == NULL) {
+ return (0);
+ }
+
+ callbacks->name = corosync_service[service_id]->name;
+
+ callbacks->sync_init = corosync_service[service_id]->sync_init;
+ callbacks->sync_process = corosync_service[service_id]->sync_process;
+ callbacks->sync_activate = corosync_service[service_id]->sync_activate;
+ callbacks->sync_abort = corosync_service[service_id]->sync_abort;
+ return (0);
+}
+
+static struct memb_ring_id corosync_ring_id;
+
+static void member_object_joined (unsigned int nodeid)
+{
+ char member_ip[ICMAP_KEYNAME_MAXLEN];
+ char member_join_count[ICMAP_KEYNAME_MAXLEN];
+ char member_status[ICMAP_KEYNAME_MAXLEN];
+
+ snprintf(member_ip, ICMAP_KEYNAME_MAXLEN,
+ "runtime.members.%u.ip", nodeid);
+ snprintf(member_join_count, ICMAP_KEYNAME_MAXLEN,
+ "runtime.members.%u.join_count", nodeid);
+ snprintf(member_status, ICMAP_KEYNAME_MAXLEN,
+ "runtime.members.%u.status", nodeid);
+
+ if (icmap_get(member_ip, NULL, NULL, NULL) == CS_OK) {
+ icmap_inc(member_join_count);
+ icmap_set_string(member_status, "joined");
+ } else {
+ icmap_set_string(member_ip, (char*)api->totem_ifaces_print (nodeid));
+ icmap_set_uint32(member_join_count, 1);
+ icmap_set_string(member_status, "joined");
+ }
+
+ log_printf (LOGSYS_LEVEL_DEBUG,
+ "Member joined: %s", api->totem_ifaces_print (nodeid));
+}
+
+static void member_object_left (unsigned int nodeid)
+{
+ char member_status[ICMAP_KEYNAME_MAXLEN];
+
+ snprintf(member_status, ICMAP_KEYNAME_MAXLEN,
+ "runtime.members.%u.status", nodeid);
+ icmap_set_string(member_status, "left");
+
+ log_printf (LOGSYS_LEVEL_DEBUG,
+ "Member left: %s", api->totem_ifaces_print (nodeid));
+}
+
+static void 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;
+ int abort_activate = 0;
+
+ if (sync_in_process == 1) {
+ abort_activate = 1;
+ }
+ sync_in_process = 1;
+ cs_ipcs_sync_state_changed(sync_in_process);
+ memcpy (&corosync_ring_id, ring_id, sizeof (struct memb_ring_id));
+
+ for (i = 0; i < left_list_entries; i++) {
+ member_object_left (left_list[i]);
+ }
+ for (i = 0; i < joined_list_entries; i++) {
+ member_object_joined (joined_list[i]);
+ }
+ /*
+ * Call configuration change for all services
+ */
+ for (i = 0; i < service_count; i++) {
+ if (corosync_service[i] && corosync_service[i]->confchg_fn) {
+ corosync_service[i]->confchg_fn (configuration_type,
+ member_list, member_list_entries,
+ left_list, left_list_entries,
+ joined_list, joined_list_entries, ring_id);
+ }
+ }
+
+ if (abort_activate) {
+ sync_abort ();
+ }
+ if (configuration_type == TOTEM_CONFIGURATION_TRANSITIONAL) {
+ sync_save_transitional (member_list, member_list_entries, ring_id);
+ }
+ if (configuration_type == TOTEM_CONFIGURATION_REGULAR) {
+ sync_start (member_list, member_list_entries, ring_id);
+ }
+}
+
+static void priv_drop (void)
+{
+ return; /* TODO: we are still not dropping privs */
+}
+
+static void corosync_tty_detach (void)
+{
+ int devnull;
+
+ /*
+ * Disconnect from TTY if this is not a debug run
+ */
+
+ switch (fork ()) {
+ case -1:
+ corosync_exit_error (COROSYNC_DONE_FORK);
+ break;
+ case 0:
+ /*
+ * child which is disconnected, run this process
+ */
+ break;
+ default:
+ exit (0);
+ break;
+ }
+
+ /* Create new session */
+ (void)setsid();
+
+ /*
+ * Map stdin/out/err to /dev/null.
+ */
+ devnull = open("/dev/null", O_RDWR);
+ if (devnull == -1) {
+ corosync_exit_error (COROSYNC_DONE_STD_TO_NULL_REDIR);
+ }
+
+ if (dup2(devnull, 0) < 0 || dup2(devnull, 1) < 0
+ || dup2(devnull, 2) < 0) {
+ close(devnull);
+ corosync_exit_error (COROSYNC_DONE_STD_TO_NULL_REDIR);
+ }
+ close(devnull);
+}
+
+static void corosync_mlockall (void)
+{
+ int res;
+ struct rlimit rlimit;
+
+ rlimit.rlim_cur = RLIM_INFINITY;
+ rlimit.rlim_max = RLIM_INFINITY;
+
+#ifndef RLIMIT_MEMLOCK
+#define RLIMIT_MEMLOCK RLIMIT_VMEM
+#endif
+
+ res = setrlimit (RLIMIT_MEMLOCK, &rlimit);
+ if (res == -1) {
+ LOGSYS_PERROR (errno, LOGSYS_LEVEL_WARNING,
+ "Could not increase RLIMIT_MEMLOCK, not locking memory");
+ return;
+ }
+
+ res = mlockall (MCL_CURRENT | MCL_FUTURE);
+ if (res == -1) {
+ LOGSYS_PERROR (errno, LOGSYS_LEVEL_WARNING,
+ "Could not lock memory of service to avoid page faults");
+ };
+}
+
+
+static void corosync_totem_stats_updater (void *data)
+{
+ totempg_stats_t * stats;
+ uint32_t total_mtt_rx_token;
+ uint32_t total_backlog_calc;
+ uint32_t total_token_holdtime;
+ int t, prev;
+ int32_t token_count;
+ const char *cstr;
+
+ stats = api->totem_get_stats();
+
+
+ stats->srp->firewall_enabled_or_nic_failure = stats->srp->continuous_gather > MAX_NO_CONT_GATHER ? 1 : 0;
+
+ if (stats->srp->continuous_gather > MAX_NO_CONT_GATHER ||
+ stats->srp->continuous_sendmsg_failures > MAX_NO_CONT_SENDMSG_FAILURES) {
+ cstr = "";
+
+ if (stats->srp->continuous_sendmsg_failures > MAX_NO_CONT_SENDMSG_FAILURES) {
+ cstr = "number of multicast sendmsg failures is above threshold";
+ }
+
+ if (stats->srp->continuous_gather > MAX_NO_CONT_GATHER) {
+ cstr = "totem is continuously in gather state";
+ }
+
+ log_printf (LOGSYS_LEVEL_WARNING,
+ "Totem is unable to form a cluster because of an "
+ "operating system or network fault (reason: %s). The most common "
+ "cause of this message is that the local firewall is "
+ "configured improperly.", cstr);
+ stats->srp->firewall_enabled_or_nic_failure = 1;
+ } else {
+ stats->srp->firewall_enabled_or_nic_failure = 0;
+ }
+
+ total_mtt_rx_token = 0;
+ total_token_holdtime = 0;
+ total_backlog_calc = 0;
+ token_count = 0;
+ t = stats->srp->latest_token;
+ while (1) {
+ if (t == 0)
+ prev = TOTEM_TOKEN_STATS_MAX - 1;
+ else
+ prev = t - 1;
+ if (prev == stats->srp->earliest_token)
+ break;
+ /* if tx == 0, then dropped token (not ours) */
+ if (stats->srp->token[t].tx != 0 ||
+ (stats->srp->token[t].rx - stats->srp->token[prev].rx) > 0 ) {
+ total_mtt_rx_token += (stats->srp->token[t].rx - stats->srp->token[prev].rx);
+ total_token_holdtime += (stats->srp->token[t].tx - stats->srp->token[t].rx);
+ total_backlog_calc += stats->srp->token[t].backlog_calc;
+ token_count++;
+ }
+ t = prev;
+ }
+ if (token_count) {
+ stats->srp->mtt_rx_token = (total_mtt_rx_token / token_count);
+ stats->srp->avg_token_workload = (total_token_holdtime / token_count);
+ stats->srp->avg_backlog_calc = (total_backlog_calc / token_count);
+ }
+
+ stats->srp->time_since_token_last_received = qb_util_nano_current_get () / QB_TIME_NS_IN_MSEC -
+ stats->srp->token[stats->srp->latest_token].rx;
+
+ stats_trigger_trackers();
+
+ api->timer_add_duration (1500 * MILLI_2_NANO_SECONDS, NULL,
+ corosync_totem_stats_updater,
+ &corosync_stats_timer_handle);
+}
+
+static void corosync_totem_stats_init (void)
+{
+ /* start stats timer */
+ api->timer_add_duration (1500 * MILLI_2_NANO_SECONDS, NULL,
+ corosync_totem_stats_updater,
+ &corosync_stats_timer_handle);
+}
+
+static void deliver_fn (
+ unsigned int nodeid,
+ const void *msg,
+ unsigned int msg_len,
+ int endian_conversion_required)
+{
+ const struct qb_ipc_request_header *header;
+ int32_t service;
+ int32_t fn_id;
+ uint32_t id;
+
+ header = msg;
+ if (endian_conversion_required) {
+ id = swab32 (header->id);
+ } else {
+ id = header->id;
+ }
+
+ /*
+ * Call the proper executive handler
+ */
+ service = id >> 16;
+ fn_id = id & 0xffff;
+
+ if (!corosync_service[service]) {
+ return;
+ }
+ if (fn_id >= corosync_service[service]->exec_engine_count) {
+ log_printf(LOGSYS_LEVEL_WARNING, "discarded unknown message %d for service %d (max id %d)",
+ fn_id, service, corosync_service[service]->exec_engine_count);
+ return;
+ }
+
+ icmap_fast_inc(service_stats_rx[service][fn_id]);
+
+ if (endian_conversion_required) {
+ assert(corosync_service[service]->exec_engine[fn_id].exec_endian_convert_fn != NULL);
+ corosync_service[service]->exec_engine[fn_id].exec_endian_convert_fn
+ ((void *)msg);
+ }
+
+ corosync_service[service]->exec_engine[fn_id].exec_handler_fn
+ (msg, nodeid);
+}
+
+int main_mcast (
+ const struct iovec *iovec,
+ unsigned int iov_len,
+ unsigned int guarantee)
+{
+ const struct qb_ipc_request_header *req = iovec->iov_base;
+ int32_t service;
+ int32_t fn_id;
+
+ service = req->id >> 16;
+ fn_id = req->id & 0xffff;
+
+ if (corosync_service[service]) {
+ icmap_fast_inc(service_stats_tx[service][fn_id]);
+ }
+
+ return (totempg_groups_mcast_joined (corosync_group_handle, iovec, iov_len, guarantee));
+}
+
+static void corosync_ring_id_create_or_load (
+ struct memb_ring_id *memb_ring_id,
+ unsigned int nodeid)
+{
+ int fd;
+ int res = 0;
+ char filename[PATH_MAX];
+
+ snprintf (filename, sizeof(filename), "%s/ringid_%u",
+ get_state_dir(), nodeid);
+ fd = open (filename, O_RDONLY);
+ /*
+ * If file can be opened and read, read the ring id
+ */
+ if (fd != -1) {
+ res = read (fd, &memb_ring_id->seq, sizeof (uint64_t));
+ close (fd);
+ }
+ /*
+ * If file could not be opened or read, create a new ring id
+ */
+ if ((fd == -1) || (res != sizeof (uint64_t))) {
+ memb_ring_id->seq = 0;
+ fd = creat (filename, 0600);
+ if (fd != -1) {
+ res = write (fd, &memb_ring_id->seq, sizeof (uint64_t));
+ close (fd);
+ if (res == -1) {
+ LOGSYS_PERROR (errno, LOGSYS_LEVEL_ERROR,
+ "Couldn't write ringid file '%s'", filename);
+
+ corosync_exit_error (COROSYNC_DONE_STORE_RINGID);
+ }
+ } else {
+ LOGSYS_PERROR (errno, LOGSYS_LEVEL_ERROR,
+ "Couldn't create ringid file '%s'", filename);
+
+ corosync_exit_error (COROSYNC_DONE_STORE_RINGID);
+ }
+ }
+
+ memb_ring_id->rep = nodeid;
+}
+
+static void corosync_ring_id_store (
+ const struct memb_ring_id *memb_ring_id,
+ unsigned int nodeid)
+{
+ char filename[PATH_MAX];
+ int fd;
+ int res;
+
+ snprintf (filename, sizeof(filename), "%s/ringid_%u",
+ get_state_dir(), nodeid);
+
+ fd = creat (filename, 0600);
+ if (fd == -1) {
+ LOGSYS_PERROR(errno, LOGSYS_LEVEL_ERROR,
+ "Couldn't store new ring id " CS_PRI_RING_ID_SEQ " to stable storage",
+ memb_ring_id->seq);
+
+ corosync_exit_error (COROSYNC_DONE_STORE_RINGID);
+ }
+ log_printf (LOGSYS_LEVEL_DEBUG,
+ "Storing new sequence id for ring " CS_PRI_RING_ID_SEQ, memb_ring_id->seq);
+ res = write (fd, &memb_ring_id->seq, sizeof(memb_ring_id->seq));
+ close (fd);
+ if (res != sizeof(memb_ring_id->seq)) {
+ LOGSYS_PERROR(errno, LOGSYS_LEVEL_ERROR,
+ "Couldn't store new ring id " CS_PRI_RING_ID_SEQ " to stable storage",
+ memb_ring_id->seq);
+
+ corosync_exit_error (COROSYNC_DONE_STORE_RINGID);
+ }
+}
+
+static qb_loop_timer_handle recheck_the_q_level_timer;
+void corosync_recheck_the_q_level(void *data)
+{
+ totempg_check_q_level(corosync_group_handle);
+ if (cs_ipcs_q_level_get() == TOTEM_Q_LEVEL_CRITICAL) {
+ qb_loop_timer_add(cs_poll_handle_get(), QB_LOOP_MED, 1*QB_TIME_NS_IN_MSEC,
+ NULL, corosync_recheck_the_q_level, &recheck_the_q_level_timer);
+ }
+}
+
+struct sending_allowed_private_data_struct {
+ int reserved_msgs;
+};
+
+
+int corosync_sending_allowed (
+ unsigned int service,
+ unsigned int id,
+ const void *msg,
+ void *sending_allowed_private_data)
+{
+ struct sending_allowed_private_data_struct *pd =
+ (struct sending_allowed_private_data_struct *)sending_allowed_private_data;
+ struct iovec reserve_iovec;
+ struct qb_ipc_request_header *header = (struct qb_ipc_request_header *)msg;
+ int sending_allowed;
+
+ reserve_iovec.iov_base = (char *)header;
+ reserve_iovec.iov_len = header->size;
+
+ pd->reserved_msgs = totempg_groups_joined_reserve (
+ corosync_group_handle,
+ &reserve_iovec, 1);
+ if (pd->reserved_msgs == -1) {
+ return -EINVAL;
+ }
+
+ /* Message ID out of range */
+ if (id >= corosync_service[service]->lib_engine_count) {
+ return -EINVAL;
+ }
+
+ sending_allowed = QB_FALSE;
+ if (corosync_quorum_is_quorate() == 1 ||
+ corosync_service[service]->allow_inquorate == CS_LIB_ALLOW_INQUORATE) {
+ // we are quorate
+ // now check flow control
+ if (corosync_service[service]->lib_engine[id].flow_control == CS_LIB_FLOW_CONTROL_NOT_REQUIRED) {
+ sending_allowed = QB_TRUE;
+ } else if (pd->reserved_msgs && sync_in_process == 0) {
+ sending_allowed = QB_TRUE;
+ } else if (pd->reserved_msgs == 0) {
+ return -ENOBUFS;
+ } else /* (sync_in_process) */ {
+ return -EINPROGRESS;
+ }
+ } else {
+ return -EHOSTUNREACH;
+ }
+
+ return (sending_allowed);
+}
+
+void corosync_sending_allowed_release (void *sending_allowed_private_data)
+{
+ struct sending_allowed_private_data_struct *pd =
+ (struct sending_allowed_private_data_struct *)sending_allowed_private_data;
+
+ if (pd->reserved_msgs == -1) {
+ return;
+ }
+ totempg_groups_joined_release (pd->reserved_msgs);
+}
+
+int message_source_is_local (const mar_message_source_t *source)
+{
+ int ret = 0;
+
+ assert (source != NULL);
+ if (source->nodeid == totempg_my_nodeid_get ()) {
+ ret = 1;
+ }
+ return ret;
+}
+
+void message_source_set (
+ mar_message_source_t *source,
+ void *conn)
+{
+ assert ((source != NULL) && (conn != NULL));
+ memset (source, 0, sizeof (mar_message_source_t));
+ source->nodeid = totempg_my_nodeid_get ();
+ source->conn = conn;
+}
+
+struct scheduler_pause_timeout_data {
+ struct totem_config *totem_config;
+ qb_loop_timer_handle handle;
+ unsigned long long tv_prev;
+ unsigned long long max_tv_diff;
+};
+
+static void timer_function_scheduler_timeout (void *data)
+{
+ struct scheduler_pause_timeout_data *timeout_data = (struct scheduler_pause_timeout_data *)data;
+ unsigned long long tv_current;
+ unsigned long long tv_diff;
+ uint64_t schedmiss_event_tstamp;
+
+ tv_current = qb_util_nano_current_get ();
+
+ if (timeout_data->tv_prev == 0) {
+ /*
+ * Initial call -> just pretent everything is ok
+ */
+ timeout_data->tv_prev = tv_current;
+ timeout_data->max_tv_diff = 0;
+ }
+
+ tv_diff = tv_current - timeout_data->tv_prev;
+ timeout_data->tv_prev = tv_current;
+
+ if (tv_diff > timeout_data->max_tv_diff) {
+ schedmiss_event_tstamp = qb_util_nano_from_epoch_get() / QB_TIME_NS_IN_MSEC;
+
+ log_printf (LOGSYS_LEVEL_WARNING, "Corosync main process was not scheduled (@%" PRIu64 ") for %0.4f ms "
+ "(threshold is %0.4f ms). Consider token timeout increase.",
+ schedmiss_event_tstamp,
+ (float)tv_diff / QB_TIME_NS_IN_MSEC, (float)timeout_data->max_tv_diff / QB_TIME_NS_IN_MSEC);
+
+ stats_add_schedmiss_event(schedmiss_event_tstamp, (float)tv_diff / QB_TIME_NS_IN_MSEC);
+ }
+
+ /*
+ * Set next threshold, because token_timeout can change
+ */
+ timeout_data->max_tv_diff = timeout_data->totem_config->token_timeout * QB_TIME_NS_IN_MSEC * 0.8;
+ qb_loop_timer_add (corosync_poll_handle,
+ QB_LOOP_MED,
+ timeout_data->totem_config->token_timeout * QB_TIME_NS_IN_MSEC / 3,
+ timeout_data,
+ timer_function_scheduler_timeout,
+ &timeout_data->handle);
+}
+
+
+/*
+ * Set main pid RR scheduler.
+ * silent: don't log sched_get_priority_max and sched_setscheduler errors
+ * Returns: 0 - success, -1 failure, -2 platform doesn't support SCHED_RR
+ */
+static int corosync_set_rr_scheduler (int silent)
+{
+ int ret_val = 0;
+
+#if defined(HAVE_PTHREAD_SETSCHEDPARAM) && defined(HAVE_SCHED_GET_PRIORITY_MAX) && defined(HAVE_SCHED_SETSCHEDULER)
+ int res;
+
+ sched_priority = sched_get_priority_max (SCHED_RR);
+ if (sched_priority != -1) {
+ global_sched_param.sched_priority = sched_priority;
+ res = sched_setscheduler (0, SCHED_RR, &global_sched_param);
+ if (res == -1) {
+ if (!silent) {
+ LOGSYS_PERROR(errno, LOGSYS_LEVEL_WARNING,
+ "Could not set SCHED_RR at priority %d",
+ global_sched_param.sched_priority);
+ }
+
+ global_sched_param.sched_priority = 0;
+#ifdef HAVE_QB_LOG_THREAD_PRIORITY_SET
+ qb_log_thread_priority_set (SCHED_OTHER, 0);
+#endif
+ ret_val = -1;
+ } else {
+
+ /*
+ * Turn on SCHED_RR in logsys system
+ */
+#ifdef HAVE_QB_LOG_THREAD_PRIORITY_SET
+ res = qb_log_thread_priority_set (SCHED_RR, sched_priority);
+#else
+ res = -1;
+#endif
+ if (res == -1) {
+ log_printf (LOGSYS_LEVEL_ERROR,
+ "Could not set logsys thread priority."
+ " Can't continue because of priority inversions.");
+ corosync_exit_error (COROSYNC_DONE_LOGSETUP);
+ }
+ }
+ } else {
+ if (!silent) {
+ LOGSYS_PERROR (errno, LOGSYS_LEVEL_WARNING,
+ "Could not get maximum scheduler priority");
+ }
+ sched_priority = 0;
+ ret_val = -1;
+ }
+#else
+ log_printf(LOGSYS_LEVEL_WARNING,
+ "The Platform is missing process priority setting features. Leaving at default.");
+ ret_val = -2;
+#endif
+
+ return (ret_val);
+}
+
+
+/* The basename man page contains scary warnings about
+ thread-safety and portability, hence this */
+static const char *corosync_basename(const char *file_name)
+{
+ char *base;
+ base = strrchr (file_name, '/');
+ if (base) {
+ return base + 1;
+ }
+
+ return file_name;
+}
+
+static void
+_logsys_log_printf(int level, int subsys,
+ const char *function_name,
+ const char *file_name,
+ int file_line,
+ const char *format,
+ ...) __attribute__((format(printf, 6, 7)));
+
+static void
+_logsys_log_printf(int level, int subsys,
+ const char *function_name,
+ const char *file_name,
+ int file_line,
+ const char *format, ...)
+{
+ va_list ap;
+
+ va_start(ap, format);
+ qb_log_from_external_source_va(function_name, corosync_basename(file_name),
+ format, level, file_line,
+ subsys, ap);
+ va_end(ap);
+}
+
+static void fplay_key_change_notify_fn (
+ int32_t event,
+ const char *key_name,
+ struct icmap_notify_value new_val,
+ struct icmap_notify_value old_val,
+ void *user_data)
+{
+ if (strcmp(key_name, "runtime.blackbox.dump_flight_data") == 0) {
+ fprintf(stderr,"Writetofile\n");
+ corosync_blackbox_write_to_file ();
+ }
+ if (strcmp(key_name, "runtime.blackbox.dump_state") == 0) {
+ fprintf(stderr,"statefump\n");
+ corosync_state_dump ();
+ }
+}
+
+static void corosync_fplay_control_init (void)
+{
+ icmap_track_t track = NULL;
+
+ icmap_set_string("runtime.blackbox.dump_flight_data", "no");
+ icmap_set_string("runtime.blackbox.dump_state", "no");
+
+ icmap_track_add("runtime.blackbox.dump_flight_data",
+ ICMAP_TRACK_ADD | ICMAP_TRACK_DELETE | ICMAP_TRACK_MODIFY,
+ fplay_key_change_notify_fn,
+ NULL, &track);
+ icmap_track_add("runtime.blackbox.dump_state",
+ ICMAP_TRACK_ADD | ICMAP_TRACK_DELETE | ICMAP_TRACK_MODIFY,
+ fplay_key_change_notify_fn,
+ NULL, &track);
+}
+
+static void force_gather_notify_fn(
+ int32_t event,
+ const char *key_name,
+ struct icmap_notify_value new_val,
+ struct icmap_notify_value old_val,
+ void *user_data)
+{
+ char *key_val;
+
+ if (icmap_get_string(key_name, &key_val) == CS_OK && strcmp(key_val, "no") == 0)
+ goto out;
+
+ icmap_set_string("runtime.force_gather", "no");
+
+ if (strcmp(key_name, "runtime.force_gather") == 0) {
+ log_printf(LOGSYS_LEVEL_ERROR, "Forcing into GATHER state\n");
+ totempg_force_gather();
+ }
+
+out:
+ free(key_val);
+}
+
+static void corosync_force_gather_init (void)
+{
+ icmap_track_t track = NULL;
+
+ icmap_set_string("runtime.force_gather", "no");
+
+ icmap_track_add("runtime.force_gather",
+ ICMAP_TRACK_ADD | ICMAP_TRACK_DELETE | ICMAP_TRACK_MODIFY,
+ force_gather_notify_fn,
+ NULL, &track);
+}
+
+/*
+ * Set RO flag for keys, which ether doesn't make sense to change by user (statistic)
+ * or which when changed are not reflected by runtime (totem.crypto_cipher, ...).
+ *
+ * Also some RO keys cannot be determined in this stage, so they are set later in
+ * other functions (like nodelist.local_node_pos, ...)
+ */
+static void set_icmap_ro_keys_flag (void)
+{
+ /*
+ * Set RO flag for all keys of internal configuration and runtime statistics
+ */
+ icmap_set_ro_access("internal_configuration.", CS_TRUE, CS_TRUE);
+ icmap_set_ro_access("runtime.services.", CS_TRUE, CS_TRUE);
+ icmap_set_ro_access("runtime.config.", CS_TRUE, CS_TRUE);
+ icmap_set_ro_access("runtime.totem.", CS_TRUE, CS_TRUE);
+ icmap_set_ro_access("uidgid.config.", CS_TRUE, CS_TRUE);
+ icmap_set_ro_access("system.", CS_TRUE, CS_TRUE);
+ icmap_set_ro_access("nodelist.", CS_TRUE, CS_TRUE);
+
+ /*
+ * Set RO flag for constrete keys of configuration which can't be changed
+ * during runtime
+ */
+ icmap_set_ro_access("totem.crypto_cipher", CS_FALSE, CS_TRUE);
+ icmap_set_ro_access("totem.crypto_hash", CS_FALSE, CS_TRUE);
+ icmap_set_ro_access("totem.crypto_model", CS_FALSE, CS_TRUE);
+ icmap_set_ro_access("totem.keyfile", CS_FALSE, CS_TRUE);
+ icmap_set_ro_access("totem.key", CS_FALSE, CS_TRUE);
+ icmap_set_ro_access("totem.secauth", CS_FALSE, CS_TRUE);
+ icmap_set_ro_access("totem.ip_version", CS_FALSE, CS_TRUE);
+ icmap_set_ro_access("totem.rrp_mode", CS_FALSE, CS_TRUE);
+ icmap_set_ro_access("totem.transport", CS_FALSE, CS_TRUE);
+ icmap_set_ro_access("totem.cluster_name", CS_FALSE, CS_TRUE);
+ icmap_set_ro_access("totem.netmtu", CS_FALSE, CS_TRUE);
+ icmap_set_ro_access("totem.threads", CS_FALSE, CS_TRUE);
+ icmap_set_ro_access("totem.version", CS_FALSE, CS_TRUE);
+ icmap_set_ro_access("totem.nodeid", CS_FALSE, CS_TRUE);
+ icmap_set_ro_access("totem.clear_node_high_bit", CS_FALSE, CS_TRUE);
+ icmap_set_ro_access("config.reload_in_progress", CS_FALSE, CS_TRUE);
+ icmap_set_ro_access("config.totemconfig_reload_in_progress", CS_FALSE, CS_TRUE);
+}
+
+static void main_service_ready (void)
+{
+ int res;
+
+ /*
+ * This must occur after totempg is initialized because "this_ip" must be set
+ */
+ res = corosync_service_defaults_link_and_init (api);
+ if (res == -1) {
+ log_printf (LOGSYS_LEVEL_ERROR, "Could not initialize default services");
+ corosync_exit_error (COROSYNC_DONE_INIT_SERVICES);
+ }
+ cs_ipcs_init();
+ corosync_totem_stats_init ();
+ corosync_fplay_control_init ();
+ corosync_force_gather_init ();
+
+ sync_init (
+ corosync_sync_callbacks_retrieve,
+ corosync_sync_completed);
+}
+
+static enum e_corosync_done corosync_flock (const char *lockfile, pid_t pid)
+{
+ struct flock lock;
+ enum e_corosync_done err;
+ char pid_s[17];
+ int fd_flag;
+
+ err = COROSYNC_DONE_EXIT;
+
+ lockfile_fd = open (lockfile, O_WRONLY | O_CREAT, 0640);
+ if (lockfile_fd == -1) {
+ log_printf (LOGSYS_LEVEL_ERROR, "Corosync Executive couldn't create lock file.");
+ return (COROSYNC_DONE_ACQUIRE_LOCK);
+ }
+
+retry_fcntl:
+ lock.l_type = F_WRLCK;
+ lock.l_start = 0;
+ lock.l_whence = SEEK_SET;
+ lock.l_len = 0;
+ if (fcntl (lockfile_fd, F_SETLK, &lock) == -1) {
+ switch (errno) {
+ case EINTR:
+ goto retry_fcntl;
+ break;
+ case EAGAIN:
+ case EACCES:
+ log_printf (LOGSYS_LEVEL_ERROR, "Another Corosync instance is already running.");
+ err = COROSYNC_DONE_ALREADY_RUNNING;
+ goto error_close;
+ break;
+ default:
+ log_printf (LOGSYS_LEVEL_ERROR, "Corosync Executive couldn't acquire lock. Error was %s",
+ strerror(errno));
+ err = COROSYNC_DONE_ACQUIRE_LOCK;
+ goto error_close;
+ break;
+ }
+ }
+
+ if (ftruncate (lockfile_fd, 0) == -1) {
+ log_printf (LOGSYS_LEVEL_ERROR, "Corosync Executive couldn't truncate lock file. Error was %s",
+ strerror (errno));
+ err = COROSYNC_DONE_ACQUIRE_LOCK;
+ goto error_close_unlink;
+ }
+
+ memset (pid_s, 0, sizeof (pid_s));
+ snprintf (pid_s, sizeof (pid_s) - 1, "%u\n", pid);
+
+retry_write:
+ if (write (lockfile_fd, pid_s, strlen (pid_s)) != strlen (pid_s)) {
+ if (errno == EINTR) {
+ goto retry_write;
+ } else {
+ log_printf (LOGSYS_LEVEL_ERROR, "Corosync Executive couldn't write pid to lock file. "
+ "Error was %s", strerror (errno));
+ err = COROSYNC_DONE_ACQUIRE_LOCK;
+ goto error_close_unlink;
+ }
+ }
+
+ if ((fd_flag = fcntl (lockfile_fd, F_GETFD, 0)) == -1) {
+ log_printf (LOGSYS_LEVEL_ERROR, "Corosync Executive couldn't get close-on-exec flag from lock file. "
+ "Error was %s", strerror (errno));
+ err = COROSYNC_DONE_ACQUIRE_LOCK;
+ goto error_close_unlink;
+ }
+ fd_flag |= FD_CLOEXEC;
+ if (fcntl (lockfile_fd, F_SETFD, fd_flag) == -1) {
+ log_printf (LOGSYS_LEVEL_ERROR, "Corosync Executive couldn't set close-on-exec flag to lock file. "
+ "Error was %s", strerror (errno));
+ err = COROSYNC_DONE_ACQUIRE_LOCK;
+ goto error_close_unlink;
+ }
+
+ return (err);
+
+error_close_unlink:
+ unlink (lockfile);
+error_close:
+ close (lockfile_fd);
+
+ return (err);
+}
+
+static int corosync_move_to_root_cgroup(void) {
+ FILE *f;
+ int res = -1;
+ const char *cgroup_task_fname = NULL;
+
+ /*
+ * /sys/fs/cgroup is hardcoded, because most of Linux distributions are now
+ * using systemd and systemd uses hardcoded path of cgroup mount point.
+ *
+ * This feature is expected to be removed as soon as systemd gets support
+ * for managing RT configuration.
+ */
+ f = fopen("/sys/fs/cgroup/cpu/cpu.rt_runtime_us", "rt");
+ if (f == NULL) {
+ /*
+ * Try cgroup v2
+ */
+ f = fopen("/sys/fs/cgroup/cgroup.procs", "rt");
+ if (f == NULL) {
+ log_printf(LOG_DEBUG, "cpu.rt_runtime_us or cgroup.procs doesn't exist -> "
+ "system without cgroup or with disabled CONFIG_RT_GROUP_SCHED");
+
+ res = 0;
+ goto exit_res;
+ } else {
+ log_printf(LOGSYS_LEVEL_DEBUG, "Moving main pid to cgroup v2 root cgroup");
+
+ cgroup_task_fname = "/sys/fs/cgroup/cgroup.procs";
+ }
+ } else {
+ log_printf(LOGSYS_LEVEL_DEBUG, "Moving main pid to cgroup v1 root cgroup");
+
+ cgroup_task_fname = "/sys/fs/cgroup/cpu/tasks";
+ }
+ (void)fclose(f);
+
+ f = fopen(cgroup_task_fname, "w");
+ if (f == NULL) {
+ log_printf(LOGSYS_LEVEL_WARNING, "Can't open cgroups tasks file for writing");
+
+ goto exit_res;
+ }
+
+ if (fprintf(f, "%jd\n", (intmax_t)getpid()) <= 0) {
+ log_printf(LOGSYS_LEVEL_WARNING, "Can't write corosync pid into cgroups tasks file");
+
+ goto close_and_exit_res;
+ }
+
+close_and_exit_res:
+ if (fclose(f) != 0) {
+ log_printf(LOGSYS_LEVEL_WARNING, "Can't close cgroups tasks file");
+
+ goto exit_res;
+ }
+
+exit_res:
+ return (res);
+}
+
+static void show_version_info_crypto(void)
+{
+ const char *error_string;
+ const char *list_str;
+
+ if (util_is_valid_knet_crypto_model(NULL, &list_str, 1, "", &error_string) != -1) {
+ printf("Available crypto models: %s\n", list_str);
+ } else {
+ perror(error_string);
+ }
+}
+
+static void show_version_info_compress(void)
+{
+ const char *error_string;
+ const char *list_str;
+
+ if (util_is_valid_knet_compress_model(NULL, &list_str, 1, "", &error_string) != -1) {
+ printf("Available compression models: %s\n", list_str);
+ } else {
+ perror(error_string);
+ }
+}
+
+static void show_version_info(void)
+{
+
+ printf ("Corosync Cluster Engine, version '%s'\n", VERSION);
+ printf ("Copyright (c) 2006-2021 Red Hat, Inc.\n");
+
+ printf ("\nBuilt-in features:" PACKAGE_FEATURES "\n");
+
+ show_version_info_crypto();
+ show_version_info_compress();
+}
+
+int main (int argc, char **argv, char **envp)
+{
+ const char *error_string;
+ struct totem_config totem_config;
+ int res, ch;
+ int background, sched_rr, prio, testonly;
+ enum move_to_root_cgroup_mode move_to_root_cgroup;
+ enum e_corosync_done flock_err;
+ uint64_t totem_config_warnings;
+ struct scheduler_pause_timeout_data scheduler_pause_timeout_data;
+ long int tmpli;
+ char *ep;
+ char *tmp_str;
+ int log_subsys_id_totem;
+ int silent;
+
+ /* default configuration
+ */
+ background = 1;
+ testonly = 0;
+
+ while ((ch = getopt (argc, argv, "c:ftv")) != EOF) {
+
+ switch (ch) {
+ case 'c':
+ res = snprintf(corosync_config_file, sizeof(corosync_config_file), "%s", optarg);
+ if (res >= sizeof(corosync_config_file)) {
+ fprintf (stderr, "Config file path too long.\n");
+ syslog (LOGSYS_LEVEL_ERROR, "Config file path too long.");
+
+ logsys_system_fini();
+ return EXIT_FAILURE;
+ }
+ break;
+ case 'f':
+ background = 0;
+ break;
+ case 't':
+ testonly = 1;
+ break;
+ case 'v':
+ show_version_info();
+ logsys_system_fini();
+ return EXIT_SUCCESS;
+
+ break;
+ default:
+ fprintf(stderr, \
+ "usage:\n"\
+ " -c : Corosync config file path.\n"\
+ " -f : Start application in foreground.\n"\
+ " -t : Test configuration and exit.\n"\
+ " -v : Display version, git revision and some useful information about Corosync and exit.\n");
+ logsys_system_fini();
+ return EXIT_FAILURE;
+ }
+ }
+
+
+ /*
+ * Other signals are registered later via qb_loop_signal_add
+ */
+ (void)signal (SIGSEGV, sigsegv_handler);
+ (void)signal (SIGABRT, sigsegv_handler);
+#if MSG_NOSIGNAL != 0
+ (void)signal (SIGPIPE, SIG_IGN);
+#endif
+
+ if (icmap_init() != CS_OK) {
+ fprintf (stderr, "Corosync Executive couldn't initialize configuration component.\n");
+ syslog (LOGSYS_LEVEL_ERROR, "Corosync Executive couldn't initialize configuration component.");
+ corosync_exit_error (COROSYNC_DONE_ICMAP);
+ }
+ set_icmap_ro_keys_flag();
+
+ /*
+ * Initialize the corosync_api_v1 definition
+ */
+ api = apidef_get ();
+
+ res = coroparse_configparse(icmap_get_global_map(), &error_string);
+ if (res == -1) {
+ /*
+ * Logsys can't log properly at this early stage, and we need to get this message out
+ *
+ */
+ fprintf (stderr, "%s\n", error_string);
+ syslog (LOGSYS_LEVEL_ERROR, "%s", error_string);
+ corosync_exit_error (COROSYNC_DONE_MAINCONFIGREAD);
+ }
+
+ if (stats_map_init(api) != CS_OK) {
+ fprintf (stderr, "Corosync Executive couldn't initialize statistics component.\n");
+ syslog (LOGSYS_LEVEL_ERROR, "Corosync Executive couldn't initialize statistics component.");
+ corosync_exit_error (COROSYNC_DONE_STATS);
+ }
+
+ res = corosync_log_config_read (&error_string);
+ if (res == -1) {
+ /*
+ * if we are here, we _must_ flush the logsys queue
+ * and try to inform that we couldn't read the config.
+ * this is a desperate attempt before certain death
+ * and there is no guarantee that we can print to stderr
+ * nor that logsys is sending the messages where we expect.
+ */
+ log_printf (LOGSYS_LEVEL_ERROR, "%s", error_string);
+ fprintf(stderr, "%s", error_string);
+ syslog (LOGSYS_LEVEL_ERROR, "%s", error_string);
+ corosync_exit_error (COROSYNC_DONE_LOGCONFIGREAD);
+ }
+
+ if (!testonly) {
+ log_printf (LOGSYS_LEVEL_NOTICE, "Corosync Cluster Engine %s starting up", VERSION);
+ log_printf (LOGSYS_LEVEL_INFO, "Corosync built-in features:" PACKAGE_FEATURES "");
+ }
+
+ /*
+ * Create totem logsys subsys before totem_config_read so log functions can be used
+ */
+ log_subsys_id_totem = _logsys_subsys_create("TOTEM", "totem,"
+ "totemip.c,totemconfig.c,totemcrypto.c,totemsrp.c,"
+ "totempg.c,totemudp.c,totemudpu.c,totemnet.c,totemknet.c");
+
+ res = chdir(get_state_dir());
+ if (res == -1) {
+ log_printf (LOGSYS_LEVEL_ERROR, "Cannot chdir to state directory %s. %s", get_state_dir(), strerror(errno));
+ corosync_exit_error (COROSYNC_DONE_DIR_NOT_PRESENT);
+ }
+
+ res = totem_config_read (&totem_config, &error_string, &totem_config_warnings);
+ if (res == -1) {
+ log_printf (LOGSYS_LEVEL_ERROR, "%s", error_string);
+ corosync_exit_error (COROSYNC_DONE_MAINCONFIGREAD);
+ }
+
+ if (totem_config_warnings & TOTEM_CONFIG_WARNING_MEMBERS_IGNORED) {
+ log_printf (LOGSYS_LEVEL_WARNING, "member section is used together with nodelist. Members ignored.");
+ }
+
+ if (totem_config_warnings & TOTEM_CONFIG_WARNING_MEMBERS_DEPRECATED) {
+ log_printf (LOGSYS_LEVEL_WARNING, "member section is deprecated.");
+ }
+
+ if (totem_config_warnings & TOTEM_CONFIG_WARNING_TOTEM_NODEID_SET) {
+ log_printf (LOGSYS_LEVEL_WARNING, "nodeid in totem section is deprecated and ignored. "
+ "Nodelist (or autogenerated) nodeid is going to be used.");
+ }
+
+ if (totem_config_warnings & TOTEM_CONFIG_BINDNETADDR_NODELIST_SET) {
+ log_printf (LOGSYS_LEVEL_WARNING, "interface section bindnetaddr is used together with nodelist. "
+ "Nodelist one is going to be used.");
+ }
+
+ if (totem_config_warnings != 0) {
+ log_printf (LOGSYS_LEVEL_WARNING, "Please migrate config file to nodelist.");
+ }
+
+ res = totem_config_validate (&totem_config, &error_string);
+ if (res == -1) {
+ log_printf (LOGSYS_LEVEL_ERROR, "%s", error_string);
+ corosync_exit_error (COROSYNC_DONE_MAINCONFIGREAD);
+ }
+
+ if (testonly) {
+ corosync_exit_error (COROSYNC_DONE_EXIT);
+ }
+
+
+ move_to_root_cgroup = MOVE_TO_ROOT_CGROUP_MODE_AUTO;
+ if (icmap_get_string("system.move_to_root_cgroup", &tmp_str) == CS_OK) {
+ /*
+ * Validity of move_to_root_cgroup values checked in coroparse.c
+ */
+ if (strcmp(tmp_str, "yes") == 0) {
+ move_to_root_cgroup = MOVE_TO_ROOT_CGROUP_MODE_ON;
+ } else if (strcmp(tmp_str, "no") == 0) {
+ move_to_root_cgroup = MOVE_TO_ROOT_CGROUP_MODE_OFF;
+ }
+ free(tmp_str);
+ }
+
+
+ sched_rr = 1;
+ if (icmap_get_string("system.sched_rr", &tmp_str) == CS_OK) {
+ if (strcmp(tmp_str, "yes") != 0) {
+ sched_rr = 0;
+ }
+ free(tmp_str);
+ }
+
+ prio = 0;
+ if (icmap_get_string("system.priority", &tmp_str) == CS_OK) {
+ if (strcmp(tmp_str, "max") == 0) {
+ prio = INT_MIN;
+ } else if (strcmp(tmp_str, "min") == 0) {
+ prio = INT_MAX;
+ } else {
+ errno = 0;
+
+ tmpli = strtol(tmp_str, &ep, 10);
+ if (errno != 0 || *ep != '\0' || tmpli > INT_MAX || tmpli < INT_MIN) {
+ log_printf (LOGSYS_LEVEL_ERROR, "Priority value %s is invalid", tmp_str);
+ corosync_exit_error (COROSYNC_DONE_MAINCONFIGREAD);
+ }
+
+ prio = tmpli;
+ }
+
+ free(tmp_str);
+ }
+
+ if (move_to_root_cgroup == MOVE_TO_ROOT_CGROUP_MODE_ON) {
+ /*
+ * Try to move corosync into root cpu cgroup. Failure is not fatal and
+ * error is deliberately ignored.
+ */
+ (void)corosync_move_to_root_cgroup();
+ }
+
+ /*
+ * Set round robin realtime scheduling with priority 99
+ */
+ if (sched_rr) {
+ silent = (move_to_root_cgroup == MOVE_TO_ROOT_CGROUP_MODE_AUTO);
+ res = corosync_set_rr_scheduler (silent);
+
+ if (res == -1 && move_to_root_cgroup == MOVE_TO_ROOT_CGROUP_MODE_AUTO) {
+ /*
+ * Try to move process to root cgroup and try set priority again
+ */
+ (void)corosync_move_to_root_cgroup();
+
+ res = corosync_set_rr_scheduler (0);
+ }
+
+ if (res != 0) {
+ prio = INT_MIN;
+ } else {
+ prio = 0;
+ }
+ }
+
+ if (prio != 0) {
+ if (setpriority(PRIO_PGRP, 0, prio) != 0) {
+ LOGSYS_PERROR(errno, LOGSYS_LEVEL_WARNING,
+ "Could not set priority %d", prio);
+ }
+ }
+
+ totem_config.totem_memb_ring_id_create_or_load = corosync_ring_id_create_or_load;
+ totem_config.totem_memb_ring_id_store = corosync_ring_id_store;
+
+ totem_config.totem_logging_configuration = totem_logging_configuration;
+ totem_config.totem_logging_configuration.log_subsys_id = log_subsys_id_totem;
+
+ totem_config.totem_logging_configuration.log_level_security = LOGSYS_LEVEL_WARNING;
+ totem_config.totem_logging_configuration.log_level_error = LOGSYS_LEVEL_ERROR;
+ totem_config.totem_logging_configuration.log_level_warning = LOGSYS_LEVEL_WARNING;
+ totem_config.totem_logging_configuration.log_level_notice = LOGSYS_LEVEL_NOTICE;
+ totem_config.totem_logging_configuration.log_level_debug = LOGSYS_LEVEL_DEBUG;
+ totem_config.totem_logging_configuration.log_level_trace = LOGSYS_LEVEL_TRACE;
+ totem_config.totem_logging_configuration.log_printf = _logsys_log_printf;
+
+ logsys_config_apply();
+
+ /*
+ * Now we are fully initialized.
+ */
+ if (background) {
+ logsys_blackbox_prefork();
+
+ corosync_tty_detach ();
+
+ logsys_blackbox_postfork();
+
+ log_printf (LOGSYS_LEVEL_DEBUG, "Corosync TTY detached");
+ }
+
+ /*
+ * Lock all memory to avoid page faults which may interrupt
+ * application healthchecking
+ */
+ corosync_mlockall ();
+
+ corosync_poll_handle = qb_loop_create ();
+
+ memset(&scheduler_pause_timeout_data, 0, sizeof(scheduler_pause_timeout_data));
+ scheduler_pause_timeout_data.totem_config = &totem_config;
+ timer_function_scheduler_timeout (&scheduler_pause_timeout_data);
+
+ qb_loop_signal_add(corosync_poll_handle, QB_LOOP_LOW,
+ SIGUSR2, NULL, sig_diag_handler, NULL);
+ qb_loop_signal_add(corosync_poll_handle, QB_LOOP_HIGH,
+ SIGINT, NULL, sig_exit_handler, NULL);
+ qb_loop_signal_add(corosync_poll_handle, QB_LOOP_HIGH,
+ SIGQUIT, NULL, sig_exit_handler, NULL);
+ qb_loop_signal_add(corosync_poll_handle, QB_LOOP_HIGH,
+ SIGTERM, NULL, sig_exit_handler, NULL);
+
+ if (logsys_thread_start() != 0) {
+ log_printf (LOGSYS_LEVEL_ERROR, "Can't initialize log thread");
+ corosync_exit_error (COROSYNC_DONE_LOGCONFIGREAD);
+ }
+
+ if ((flock_err = corosync_flock (corosync_lock_file, getpid ())) != COROSYNC_DONE_EXIT) {
+ corosync_exit_error (flock_err);
+ }
+
+ /*
+ * if totempg_initialize doesn't have root priveleges, it cannot
+ * bind to a specific interface. This only matters if
+ * there is more then one interface in a system, so
+ * in this case, only a warning is printed
+ */
+ /*
+ * Join multicast group and setup delivery
+ * and configuration change functions
+ */
+ if (totempg_initialize (
+ corosync_poll_handle,
+ &totem_config) != 0) {
+
+ log_printf (LOGSYS_LEVEL_ERROR, "Can't initialize TOTEM layer");
+ corosync_exit_error (COROSYNC_DONE_FATAL_ERR);
+ }
+
+ totempg_service_ready_register (
+ main_service_ready);
+
+ totempg_groups_initialize (
+ &corosync_group_handle,
+ deliver_fn,
+ confchg_fn);
+
+ totempg_groups_join (
+ corosync_group_handle,
+ &corosync_group,
+ 1);
+
+ /*
+ * Drop root privleges to user 'corosync'
+ * TODO: Don't really need full root capabilities;
+ * needed capabilities are:
+ * CAP_NET_RAW (bindtodevice)
+ * CAP_SYS_NICE (setscheduler)
+ * CAP_IPC_LOCK (mlockall)
+ */
+ priv_drop ();
+
+ schedwrk_init (
+ serialize_lock,
+ serialize_unlock);
+
+ /*
+ * Start main processing loop
+ */
+ qb_loop_run (corosync_poll_handle);
+
+ /*
+ * Exit was requested
+ */
+ totempg_finalize ();
+
+ /*
+ * free the loop resources
+ */
+ qb_loop_destroy (corosync_poll_handle);
+
+ /*
+ * free up the icmap
+ */
+
+ /*
+ * Remove pid lock file
+ */
+ close (lockfile_fd);
+ unlink (corosync_lock_file);
+
+ corosync_exit_error (COROSYNC_DONE_EXIT);
+
+ return EXIT_SUCCESS;
+}
diff --git a/exec/main.h b/exec/main.h
new file mode 100644
index 0000000..ee86ad9
--- /dev/null
+++ b/exec/main.h
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2002-2006 MontaVista Software, Inc.
+ * Copyright (c) 2006-2018 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Author: Steven Dake (sdake@redhat.com)
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of the MontaVista Software, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file
+ *
+ * @warning DO NOT USE SYMBOLS IN THIS FILE
+ */
+
+#ifndef MAIN_H_DEFINED
+#define MAIN_H_DEFINED
+
+#define TRUE 1
+#define FALSE 0
+#include <corosync/corotypes.h>
+#include <corosync/hdb.h>
+#include <qb/qbloop.h>
+#include <corosync/totem/totempg.h>
+#include <corosync/icmap.h>
+#include <corosync/coroapi.h>
+
+extern unsigned long long *(*main_clm_get_by_nodeid) (unsigned int node_id);
+
+extern int main_mcast (
+ const struct iovec *iovec,
+ unsigned int iov_len,
+ unsigned int guarantee);
+
+extern void message_source_set (mar_message_source_t *source, void *conn);
+
+extern int message_source_is_local (const mar_message_source_t *source);
+
+extern void corosync_shutdown_request (void);
+
+extern void corosync_state_dump (void);
+
+extern qb_loop_t *cs_poll_handle_get (void);
+
+extern int cs_poll_dispatch_add (qb_loop_t * handle,
+ int fd,
+ int events,
+ void *data,
+
+ int (*dispatch_fn) (int fd,
+ int revents,
+ void *data));
+
+extern int cs_poll_dispatch_delete (
+ qb_loop_t * handle,
+ int fd);
+
+
+extern int corosync_sending_allowed (
+ unsigned int service,
+ unsigned int id,
+ const void *msg,
+ void *sending_allowed_private_data);
+
+extern void corosync_sending_allowed_release (void *sending_allowed_private_data);
+
+extern void corosync_recheck_the_q_level(void *data);
+
+extern void cs_ipcs_init(void);
+
+extern const char *cs_ipcs_service_init(struct corosync_service_engine *service);
+
+extern void cs_ipcs_stats_update(void);
+
+extern int32_t cs_ipcs_service_destroy(int32_t service_id);
+
+extern int32_t cs_ipcs_q_level_get(void);
+
+extern int cs_ipcs_dispatch_send(void *conn, const void *msg, size_t mlen);
+extern int cs_ipcs_dispatch_iov_send (void *conn,
+ const struct iovec *iov,
+ unsigned int iov_len);
+
+extern int cs_ipcs_response_send(void *conn, const void *msg, size_t mlen);
+extern int cs_ipcs_response_iov_send (void *conn,
+ const struct iovec *iov,
+ unsigned int iov_len);
+
+extern void cs_ipcs_sync_state_changed(int32_t sync_in_process);
+
+extern void *cs_ipcs_private_data_get(void *conn);
+
+extern void cs_ipc_refcnt_inc(void *conn);
+
+extern void cs_ipc_refcnt_dec(void *conn);
+
+extern void cs_ipc_allow_connections(int32_t allow);
+
+extern int coroparse_configparse (icmap_map_t config_map, const char **error_string);
+
+extern const char *corosync_get_config_file(void);
+
+#endif /* MAIN_H_DEFINED */
diff --git a/exec/mon.c b/exec/mon.c
new file mode 100644
index 0000000..3f71fb5
--- /dev/null
+++ b/exec/mon.c
@@ -0,0 +1,511 @@
+/*
+ * Copyright (c) 2010-2012 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Author: Angus Salkeld <asalkeld@redhat.com>
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of the MontaVista Software, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include <unistd.h>
+#include <statgrab.h>
+
+#include <corosync/corotypes.h>
+#include <corosync/corodefs.h>
+#include <corosync/coroapi.h>
+#include <qb/qblist.h>
+#include <corosync/logsys.h>
+#include <corosync/icmap.h>
+#include "fsm.h"
+
+#include "service.h"
+
+LOGSYS_DECLARE_SUBSYS ("MON");
+
+/*
+ * Service Interfaces required by service_message_handler struct
+ */
+static char *mon_exec_init_fn (struct corosync_api_v1 *corosync_api);
+
+static struct corosync_api_v1 *api;
+#define MON_DEFAULT_PERIOD 3000
+#define MON_MIN_PERIOD 500
+#define MON_MAX_PERIOD (120 * CS_TIME_MS_IN_SEC)
+
+struct corosync_service_engine mon_service_engine = {
+ .name = "corosync resource monitoring service",
+ .id = MON_SERVICE,
+ .priority = 1,
+ .private_data_size = 0,
+ .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED,
+ .lib_init_fn = NULL,
+ .lib_exit_fn = NULL,
+ .lib_engine = NULL,
+ .lib_engine_count = 0,
+ .exec_engine = NULL,
+ .exec_engine_count = 0,
+ .confchg_fn = NULL,
+ .exec_init_fn = mon_exec_init_fn,
+ .exec_dump_fn = NULL
+};
+
+static QB_LIST_DECLARE (confchg_notify);
+
+
+struct resource_instance {
+ const char *icmap_path;
+ const char *name;
+ corosync_timer_handle_t timer_handle;
+ void (*update_stats_fn) (void *data);
+ struct cs_fsm fsm;
+ uint64_t period;
+ icmap_value_types_t max_type;
+ union {
+ int32_t int32;
+ double dbl;
+ } max;
+};
+
+static void mem_update_stats_fn (void *data);
+static void load_update_stats_fn (void *data);
+
+static struct resource_instance memory_used_inst = {
+ .name = "memory_used",
+ .icmap_path = "resources.system.memory_used.",
+ .update_stats_fn = mem_update_stats_fn,
+ .max_type = ICMAP_VALUETYPE_INT32,
+ .max.int32 = INT32_MAX,
+ .period = MON_DEFAULT_PERIOD,
+};
+
+static struct resource_instance load_15min_inst = {
+ .name = "load_15min",
+ .icmap_path = "resources.system.load_15min.",
+ .update_stats_fn = load_update_stats_fn,
+ .max_type = ICMAP_VALUETYPE_DOUBLE,
+ .max.dbl = INT32_MAX,
+ .period = MON_DEFAULT_PERIOD,
+};
+
+
+/*
+ * F S M
+ */
+static void mon_config_changed (struct cs_fsm* fsm, int32_t event, void * data);
+static void mon_resource_failed (struct cs_fsm* fsm, int32_t event, void * data);
+
+const char * mon_running_str = "running";
+const char * mon_failed_str = "failed";
+const char * mon_failure_str = "failure";
+const char * mon_stopped_str = "stopped";
+const char * mon_config_changed_str = "config_changed";
+
+enum mon_resource_state {
+ MON_S_STOPPED,
+ MON_S_RUNNING,
+ MON_S_FAILED
+};
+enum mon_resource_event {
+ MON_E_CONFIG_CHANGED,
+ MON_E_FAILURE
+};
+
+struct cs_fsm_entry mon_fsm_table[] = {
+ { MON_S_STOPPED, MON_E_CONFIG_CHANGED, mon_config_changed, {MON_S_STOPPED, MON_S_RUNNING, -1} },
+ { MON_S_STOPPED, MON_E_FAILURE, NULL, {-1} },
+ { MON_S_RUNNING, MON_E_CONFIG_CHANGED, mon_config_changed, {MON_S_RUNNING, MON_S_STOPPED, -1} },
+ { MON_S_RUNNING, MON_E_FAILURE, mon_resource_failed, {MON_S_FAILED, -1} },
+ { MON_S_FAILED, MON_E_CONFIG_CHANGED, mon_config_changed, {MON_S_RUNNING, MON_S_STOPPED, -1} },
+ { MON_S_FAILED, MON_E_FAILURE, NULL, {-1} },
+};
+
+struct corosync_service_engine *mon_get_service_engine_ver0 (void)
+{
+ return (&mon_service_engine);
+}
+
+static const char * mon_res_state_to_str(struct cs_fsm* fsm,
+ int32_t state)
+{
+ switch (state) {
+ case MON_S_STOPPED:
+ return mon_stopped_str;
+ break;
+ case MON_S_RUNNING:
+ return mon_running_str;
+ break;
+ case MON_S_FAILED:
+ return mon_failed_str;
+ break;
+ }
+ return NULL;
+}
+
+static const char * mon_res_event_to_str(struct cs_fsm* fsm,
+ int32_t event)
+{
+ switch (event) {
+ case MON_E_CONFIG_CHANGED:
+ return mon_config_changed_str;
+ break;
+ case MON_E_FAILURE:
+ return mon_failure_str;
+ break;
+ }
+ return NULL;
+}
+
+static void mon_fsm_cb (struct cs_fsm *fsm, int cb_event, int32_t curr_state,
+ int32_t next_state, int32_t fsm_event, void *data)
+{
+ switch (cb_event) {
+ case CS_FSM_CB_EVENT_PROCESS_NF:
+ log_printf (LOGSYS_LEVEL_ERROR, "Fsm:%s could not find event \"%s\" in state \"%s\"",
+ fsm->name, fsm->event_to_str(fsm, fsm_event), fsm->state_to_str(fsm, curr_state));
+ corosync_exit_error(COROSYNC_DONE_FATAL_ERR);
+ break;
+ case CS_FSM_CB_EVENT_STATE_SET:
+ log_printf (LOGSYS_LEVEL_INFO, "Fsm:%s event \"%s\", state \"%s\" --> \"%s\"",
+ fsm->name,
+ fsm->event_to_str(fsm, fsm_event),
+ fsm->state_to_str(fsm, fsm->table[fsm->curr_entry].curr_state),
+ fsm->state_to_str(fsm, next_state));
+ break;
+ case CS_FSM_CB_EVENT_STATE_SET_NF:
+ log_printf (LOGSYS_LEVEL_CRIT, "Fsm:%s Can't change state from \"%s\" to \"%s\" (event was \"%s\")",
+ fsm->name,
+ fsm->state_to_str(fsm, fsm->table[fsm->curr_entry].curr_state),
+ fsm->state_to_str(fsm, next_state),
+ fsm->event_to_str(fsm, fsm_event));
+ corosync_exit_error(COROSYNC_DONE_FATAL_ERR);
+ break;
+ default:
+ log_printf (LOGSYS_LEVEL_CRIT, "Fsm: Can't find callback event!");
+ corosync_exit_error(COROSYNC_DONE_FATAL_ERR);
+ break;
+ }
+}
+
+static void mon_fsm_state_set (struct cs_fsm* fsm,
+ enum mon_resource_state next_state, struct resource_instance* inst)
+{
+ enum mon_resource_state prev_state = fsm->curr_state;
+ const char *state_str;
+ char key_name[ICMAP_KEYNAME_MAXLEN];
+
+ ENTER();
+
+ cs_fsm_state_set(fsm, next_state, inst, mon_fsm_cb);
+
+ if (prev_state == fsm->curr_state) {
+ return;
+ }
+ state_str = mon_res_state_to_str(fsm, fsm->curr_state);
+
+ snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "%s%s", inst->icmap_path, "state");
+ icmap_set_string(key_name, state_str);
+}
+
+
+static void mon_config_changed (struct cs_fsm* fsm, int32_t event, void * data)
+{
+ struct resource_instance * inst = (struct resource_instance *)data;
+ char *tmp_str;
+ uint64_t tmp_value;
+ char key_name[ICMAP_KEYNAME_MAXLEN];
+ int run_updater;
+ int scanf_res = 0;
+ int32_t i32;
+ double dbl;
+
+ ENTER();
+
+ snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "%s%s", inst->icmap_path, "poll_period");
+ if (icmap_get_string(key_name, &tmp_str) == CS_OK) {
+ scanf_res = sscanf(tmp_str, "%"PRIu64, &tmp_value);
+ if (scanf_res != 1) {
+ log_printf (LOGSYS_LEVEL_WARNING,
+ "Could NOT use poll_period: %s (not uint64 type) for resource %s",
+ tmp_str, inst->name);
+ }
+ free(tmp_str);
+
+ if (tmp_value >= MON_MIN_PERIOD && tmp_value <= MON_MAX_PERIOD) {
+ log_printf (LOGSYS_LEVEL_DEBUG,
+ "poll_period changing from:%"PRIu64" to %"PRIu64".",
+ inst->period, tmp_value);
+ inst->period = tmp_value;
+ } else {
+ log_printf (LOGSYS_LEVEL_WARNING,
+ "Could NOT use poll_period:%"PRIu64" ms for resource %s",
+ tmp_value, inst->name);
+ }
+ }
+
+ if (inst->timer_handle) {
+ api->timer_delete(inst->timer_handle);
+ inst->timer_handle = 0;
+ }
+
+ run_updater = 0;
+
+ snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "%s%s", inst->icmap_path, "max");
+
+ if (icmap_get_string(key_name, &tmp_str) == CS_OK) {
+ if (inst->max_type == ICMAP_VALUETYPE_INT32) {
+ if (sscanf(tmp_str, "%"PRId32, &i32) != 1) {
+ inst->max.int32 = INT32_MAX;
+
+ mon_fsm_state_set (fsm, MON_S_STOPPED, inst);
+ } else {
+ inst->max.int32 = i32;
+ run_updater = 1;
+ }
+ }
+ if (inst->max_type == ICMAP_VALUETYPE_DOUBLE) {
+ if (sscanf(tmp_str, "%lf", &dbl) != 1) {
+ inst->max.dbl = INT32_MAX;
+
+ mon_fsm_state_set (fsm, MON_S_STOPPED, inst);
+ } else {
+ inst->max.dbl = dbl;
+ run_updater = 1;
+ }
+ }
+ free(tmp_str);
+ }
+
+ if (run_updater) {
+ mon_fsm_state_set (fsm, MON_S_RUNNING, inst);
+ /*
+ * run the updater, incase the period has shortened
+ * and to start the timer.
+ */
+ inst->update_stats_fn (inst);
+ }
+}
+
+void mon_resource_failed (struct cs_fsm* fsm, int32_t event, void * data)
+{
+ struct resource_instance * inst = (struct resource_instance *)data;
+ ENTER();
+ mon_fsm_state_set (fsm, MON_S_FAILED, inst);
+}
+
+static int32_t percent_mem_used_get(void)
+{
+ sg_mem_stats *mem_stats;
+ sg_swap_stats *swap_stats;
+ long long total, freemem;
+
+#ifdef HAVE_LIBSTATGRAB_GE_090
+ mem_stats = sg_get_mem_stats(NULL);
+ swap_stats = sg_get_swap_stats(NULL);
+#else
+ mem_stats = sg_get_mem_stats();
+ swap_stats = sg_get_swap_stats();
+#endif
+
+ if (mem_stats == NULL || swap_stats == NULL) {
+ log_printf (LOGSYS_LEVEL_ERROR, "Unable to get memory stats: %s",
+ sg_str_error(sg_get_error()));
+ return -1;
+ }
+ total = mem_stats->total + swap_stats->total;
+ freemem = mem_stats->free + swap_stats->free;
+ return ((total - freemem) * 100) / total;
+}
+
+static void mem_update_stats_fn (void *data)
+{
+ struct resource_instance * inst = (struct resource_instance *)data;
+ int32_t new_value;
+ uint64_t timestamp;
+ char key_name[ICMAP_KEYNAME_MAXLEN];
+
+ new_value = percent_mem_used_get();
+ if (new_value > 0) {
+ snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "%s%s", inst->icmap_path, "current");
+ icmap_set_uint32(key_name, new_value);
+
+ timestamp = cs_timestamp_get();
+
+ snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "%s%s", inst->icmap_path, "last_updated");
+ icmap_set_uint64(key_name, timestamp);
+
+ if (new_value > inst->max.int32 && inst->fsm.curr_state != MON_S_FAILED) {
+ cs_fsm_process (&inst->fsm, MON_E_FAILURE, inst, mon_fsm_cb);
+ }
+ }
+ api->timer_add_duration(inst->period * MILLI_2_NANO_SECONDS,
+ inst, inst->update_stats_fn, &inst->timer_handle);
+}
+
+static double min15_loadavg_get(void)
+{
+ sg_load_stats *load_stats;
+
+#ifdef HAVE_LIBSTATGRAB_GE_090
+ load_stats = sg_get_load_stats (NULL);
+#else
+ load_stats = sg_get_load_stats ();
+#endif
+ if (load_stats == NULL) {
+ log_printf (LOGSYS_LEVEL_ERROR, "Unable to get load stats: %s",
+ sg_str_error (sg_get_error()));
+ return -1;
+ }
+ return load_stats->min15;
+}
+
+static void load_update_stats_fn (void *data)
+{
+ struct resource_instance * inst = (struct resource_instance *)data;
+ uint64_t timestamp;
+ char key_name[ICMAP_KEYNAME_MAXLEN];
+ double min15 = min15_loadavg_get();
+
+ if (min15 > 0) {
+ snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "%s%s", inst->icmap_path, "current");
+ icmap_set_double(key_name, min15);
+
+ timestamp = cs_timestamp_get();
+
+ snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "%s%s", inst->icmap_path, "last_updated");
+ icmap_set_uint64(key_name, timestamp);
+
+ if (min15 > inst->max.dbl && inst->fsm.curr_state != MON_S_FAILED) {
+ cs_fsm_process (&inst->fsm, MON_E_FAILURE, inst, mon_fsm_cb);
+ }
+ }
+
+ api->timer_add_duration(inst->period * MILLI_2_NANO_SECONDS,
+ inst, inst->update_stats_fn, &inst->timer_handle);
+}
+
+static void mon_key_changed_cb (
+ int32_t event,
+ const char *key_name,
+ struct icmap_notify_value new_value,
+ struct icmap_notify_value old_value,
+ void *user_data)
+{
+ struct resource_instance* inst = (struct resource_instance*)user_data;
+ char *last_key_part;
+
+ if (event == ICMAP_TRACK_DELETE && inst) {
+ log_printf (LOGSYS_LEVEL_WARNING,
+ "resource \"%s\" deleted from cmap!",
+ inst->name);
+
+ cs_fsm_process (&inst->fsm, MON_E_CONFIG_CHANGED, inst, mon_fsm_cb);
+ }
+
+ if (event == ICMAP_TRACK_MODIFY) {
+ last_key_part = strrchr(key_name, '.');
+ if (last_key_part == NULL)
+ return ;
+
+ last_key_part++;
+ if (strcmp(last_key_part, "max") == 0 ||
+ strcmp(last_key_part, "poll_period") == 0) {
+ ENTER();
+ cs_fsm_process (&inst->fsm, MON_E_CONFIG_CHANGED, inst, mon_fsm_cb);
+ }
+ }
+}
+
+static void mon_instance_init (struct resource_instance* inst)
+{
+ uint64_t tmp_value;
+ char key_name[ICMAP_KEYNAME_MAXLEN];
+ icmap_track_t icmap_track = NULL;
+ char *tmp_str;
+
+ snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "%s%s", inst->icmap_path, "current");
+ if (inst->max_type == ICMAP_VALUETYPE_INT32) {
+ icmap_set_int32(key_name, 0);
+ } else {
+ icmap_set_double(key_name, 0);
+ }
+
+ snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "%s%s", inst->icmap_path, "last_updated");
+ icmap_set_uint64(key_name, 0);
+
+ snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "%s%s", inst->icmap_path, "state");
+ icmap_set_string(key_name, mon_stopped_str);
+
+ inst->fsm.name = inst->name;
+ inst->fsm.curr_entry = 0;
+ inst->fsm.curr_state = MON_S_STOPPED;
+ inst->fsm.table = mon_fsm_table;
+ inst->fsm.entries = sizeof(mon_fsm_table) / sizeof(struct cs_fsm_entry);
+ inst->fsm.state_to_str = mon_res_state_to_str;
+ inst->fsm.event_to_str = mon_res_event_to_str;
+
+ snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "%s%s", inst->icmap_path, "poll_period");
+ if (icmap_get_string(key_name, &tmp_str) != CS_OK ||
+ sscanf(tmp_str, "%"PRIu64, &tmp_value) != 1) {
+ icmap_set_uint64(key_name, inst->period);
+ }
+ else {
+ if (tmp_value >= MON_MIN_PERIOD && tmp_value <= MON_MAX_PERIOD) {
+ inst->period = tmp_value;
+ } else {
+ log_printf (LOGSYS_LEVEL_WARNING,
+ "Could NOT use poll_period:%"PRIu64" ms for resource %s",
+ tmp_value, inst->name);
+ }
+ free(tmp_str);
+ }
+ cs_fsm_process (&inst->fsm, MON_E_CONFIG_CHANGED, inst, mon_fsm_cb);
+
+ icmap_track_add(inst->icmap_path,
+ ICMAP_TRACK_ADD | ICMAP_TRACK_MODIFY | ICMAP_TRACK_DELETE | ICMAP_TRACK_PREFIX,
+ mon_key_changed_cb, inst, &icmap_track);
+}
+
+static char *mon_exec_init_fn (struct corosync_api_v1 *corosync_api)
+{
+#ifdef HAVE_LIBSTATGRAB_GE_090
+ sg_init(1);
+#else
+ sg_init();
+#endif
+
+ api = corosync_api;
+
+ mon_instance_init (&memory_used_inst);
+ mon_instance_init (&load_15min_inst);
+
+ return NULL;
+}
+
+
diff --git a/exec/pload.c b/exec/pload.c
new file mode 100644
index 0000000..206338d
--- /dev/null
+++ b/exec/pload.c
@@ -0,0 +1,357 @@
+/*
+ * Copyright (c) 2008-2012 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Authors: Steven Dake (sdake@redhat.com)
+ * Fabio M. Di Nitto (fdinitto@redhat.com)
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of the MontaVista Software, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include <qb/qblist.h>
+#include <qb/qbutil.h>
+#include <qb/qbipc_common.h>
+
+#include <corosync/swab.h>
+#include <corosync/corodefs.h>
+#include <corosync/coroapi.h>
+#include <corosync/icmap.h>
+#include <corosync/logsys.h>
+
+#include "service.h"
+#include "util.h"
+
+LOGSYS_DECLARE_SUBSYS ("PLOAD");
+
+/*
+ * Service Interfaces required by service_message_handler struct
+ */
+static struct corosync_api_v1 *api;
+
+static char *pload_exec_init_fn (struct corosync_api_v1 *corosync_api);
+
+/*
+ * on wire / network bits
+ */
+enum pload_exec_message_req_types {
+ MESSAGE_REQ_EXEC_PLOAD_START = 0,
+ MESSAGE_REQ_EXEC_PLOAD_MCAST = 1
+};
+
+struct req_exec_pload_start {
+ struct qb_ipc_request_header header;
+ uint32_t msg_count;
+ uint32_t msg_size;
+};
+
+struct req_exec_pload_mcast {
+ struct qb_ipc_request_header header;
+};
+
+static void message_handler_req_exec_pload_start (const void *msg,
+ unsigned int nodeid);
+static void req_exec_pload_start_endian_convert (void *msg);
+
+static void message_handler_req_exec_pload_mcast (const void *msg,
+ unsigned int nodeid);
+static void req_exec_pload_mcast_endian_convert (void *msg);
+
+static struct corosync_exec_handler pload_exec_engine[] =
+{
+ {
+ .exec_handler_fn = message_handler_req_exec_pload_start,
+ .exec_endian_convert_fn = req_exec_pload_start_endian_convert
+ },
+ {
+ .exec_handler_fn = message_handler_req_exec_pload_mcast,
+ .exec_endian_convert_fn = req_exec_pload_mcast_endian_convert
+ }
+};
+
+/*
+ * internal bits and pieces
+ */
+
+/*
+ * really unused buffer but we need to give something to iovec
+ */
+static char *buffer = NULL;
+
+/*
+ * wanted/size come from config
+ * sent/delivered track the runtime status
+ */
+static uint32_t msgs_wanted = 0;
+static uint32_t msg_size = 0;
+static uint32_t msgs_sent = 0;
+static uint32_t msgs_delivered = 0;
+
+/*
+ * bit flip to track if we are running or not and avoid multiple instances
+ */
+static uint8_t pload_started = 0;
+
+/*
+ * handle for scheduler
+ */
+static hdb_handle_t start_mcasting_handle;
+
+/*
+ * timing/profiling
+ */
+static unsigned long long int tv1;
+static unsigned long long int tv2;
+static unsigned long long int tv_elapsed;
+
+/*
+ * Service engine hooks
+ */
+struct corosync_service_engine pload_service_engine = {
+ .name = "corosync profile loading service",
+ .id = PLOAD_SERVICE,
+ .priority = 1,
+ .flow_control = CS_LIB_FLOW_CONTROL_REQUIRED,
+ .exec_engine = pload_exec_engine,
+ .exec_engine_count = sizeof (pload_exec_engine) / sizeof (struct corosync_exec_handler),
+ .exec_init_fn = pload_exec_init_fn
+};
+
+struct corosync_service_engine *pload_get_service_engine_ver0 (void)
+{
+ return (&pload_service_engine);
+}
+
+/*
+ * internal use only functions
+ */
+
+/*
+ * not all architectures / OSes define timersub in sys/time.h or time.h
+ */
+
+#ifndef timersub
+#warning Using internal timersub definition. Check your include header files
+#define timersub(a, b, result) \
+do { \
+ (result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \
+ (result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \
+ if ((result)->tv_usec < 0) { \
+ --(result)->tv_sec; \
+ (result)->tv_usec += 1000000; \
+ } \
+} while (0)
+#endif /* timersub */
+
+/*
+ * tell all cluster nodes to start mcasting
+ */
+static void pload_send_start (uint32_t count, uint32_t size)
+{
+ struct req_exec_pload_start req_exec_pload_start;
+ struct iovec iov;
+
+ req_exec_pload_start.header.id = SERVICE_ID_MAKE (PLOAD_SERVICE, MESSAGE_REQ_EXEC_PLOAD_START);
+ req_exec_pload_start.msg_count = count;
+ req_exec_pload_start.msg_size = size;
+ iov.iov_base = (void *)&req_exec_pload_start;
+ iov.iov_len = sizeof (struct req_exec_pload_start);
+
+ api->totem_mcast (&iov, 1, TOTEM_AGREED);
+}
+
+/*
+ * send N empty data messages of size X
+ */
+static int pload_send_message (const void *arg)
+{
+ struct req_exec_pload_mcast req_exec_pload_mcast;
+ struct iovec iov[2];
+ unsigned int res;
+ unsigned int iov_len = 1;
+
+ req_exec_pload_mcast.header.id = SERVICE_ID_MAKE (PLOAD_SERVICE, MESSAGE_REQ_EXEC_PLOAD_MCAST);
+ req_exec_pload_mcast.header.size = sizeof (struct req_exec_pload_mcast) + msg_size;
+
+ iov[0].iov_base = (void *)&req_exec_pload_mcast;
+ iov[0].iov_len = sizeof (struct req_exec_pload_mcast);
+ if (msg_size > sizeof (req_exec_pload_mcast)) {
+ iov[1].iov_base = &buffer;
+ iov[1].iov_len = msg_size - sizeof (req_exec_pload_mcast);
+ iov_len = 2;
+ }
+
+ do {
+ res = api->totem_mcast (iov, iov_len, TOTEM_AGREED);
+ if (res == -1) {
+ break;
+ } else {
+ msgs_sent++;
+ }
+ } while (msgs_sent < msgs_wanted);
+
+ if (msgs_sent == msgs_wanted) {
+ return (0);
+ } else {
+ return (-1);
+ }
+}
+
+/*
+ * hook into icmap to read config at runtime
+ * we do NOT start by default, ever!
+ */
+static void pload_read_config(
+ int32_t event,
+ const char *key_name,
+ struct icmap_notify_value new_val,
+ struct icmap_notify_value old_val,
+ void *user_data)
+{
+ uint32_t pload_count = 1500000;
+ uint32_t pload_size = 300;
+ char *pload_start = NULL;
+
+ icmap_get_uint32("pload.count", &pload_count);
+ icmap_get_uint32("pload.size", &pload_size);
+
+ if (pload_size > MESSAGE_SIZE_MAX) {
+ pload_size = MESSAGE_SIZE_MAX;
+ log_printf(LOGSYS_LEVEL_WARNING, "pload size limited to %u", pload_size);
+ }
+
+ if ((!pload_started) &&
+ (icmap_get_string("pload.start", &pload_start) == CS_OK)) {
+ if (!strcmp(pload_start,
+ "i_totally_understand_pload_will_crash_my_cluster_and_kill_corosync_on_exit")) {
+ buffer = malloc(pload_size);
+ if (buffer) {
+ log_printf(LOGSYS_LEVEL_WARNING, "Starting pload!");
+ pload_send_start(pload_count, pload_size);
+ } else {
+ log_printf(LOGSYS_LEVEL_WARNING,
+ "Unable to allocate pload buffer!");
+ }
+ }
+ free(pload_start);
+ }
+}
+
+/*
+ * exec functions
+ */
+static char *pload_exec_init_fn (struct corosync_api_v1 *corosync_api)
+{
+ icmap_track_t pload_track = NULL;
+
+ api = corosync_api;
+
+ /*
+ * track changes to pload config and start only on demand
+ */
+ if (icmap_track_add("pload.",
+ ICMAP_TRACK_ADD | ICMAP_TRACK_DELETE | ICMAP_TRACK_MODIFY | ICMAP_TRACK_PREFIX,
+ pload_read_config,
+ NULL,
+ &pload_track) != CS_OK) {
+ return (char *)"Unable to setup pload config tracking!\n";
+ }
+
+ return NULL;
+}
+
+/*
+ * network messages/onwire handlers
+ */
+
+static void req_exec_pload_start_endian_convert (void *msg)
+{
+ struct req_exec_pload_start *req_exec_pload_start = msg;
+
+ req_exec_pload_start->msg_count = swab32(req_exec_pload_start->msg_count);
+ req_exec_pload_start->msg_size = swab32(req_exec_pload_start->msg_size);
+}
+
+static void message_handler_req_exec_pload_start (
+ const void *msg,
+ unsigned int nodeid)
+{
+ const struct req_exec_pload_start *req_exec_pload_start = msg;
+
+ /*
+ * don't start multiple instances
+ */
+ if (pload_started) {
+ return;
+ }
+
+ pload_started = 1;
+
+ msgs_wanted = req_exec_pload_start->msg_count;
+ msg_size = req_exec_pload_start->msg_size;
+
+ api->schedwrk_create (
+ &start_mcasting_handle,
+ pload_send_message,
+ &start_mcasting_handle);
+}
+
+static void req_exec_pload_mcast_endian_convert (void *msg)
+{
+}
+
+static void message_handler_req_exec_pload_mcast (
+ const void *msg,
+ unsigned int nodeid)
+{
+ char log_buffer[1024];
+
+ if (msgs_delivered == 0) {
+ tv1 = qb_util_nano_current_get ();
+ }
+ msgs_delivered += 1;
+ if (msgs_delivered == msgs_wanted) {
+ tv2 = qb_util_nano_current_get ();
+ tv_elapsed = tv2 - tv1;
+ sprintf (log_buffer, "%5d Writes %d bytes per write %7.3f seconds runtime, %9.3f TP/S, %9.3f MB/S.",
+ msgs_delivered,
+ msg_size,
+ (tv_elapsed / 1000000000.0),
+ ((float)msgs_delivered) / (tv_elapsed / 1000000000.0),
+ (((float)msgs_delivered) * ((float)msg_size) /
+ (tv_elapsed / 1000000000.0)) / (1024.0 * 1024.0));
+ log_printf (LOGSYS_LEVEL_NOTICE, "%s", log_buffer);
+ log_printf (LOGSYS_LEVEL_WARNING, "Stopping corosync the hard way");
+ if (buffer) {
+ free(buffer);
+ buffer = NULL;
+ }
+ exit(COROSYNC_DONE_PLOAD);
+ }
+}
diff --git a/exec/quorum.c b/exec/quorum.c
new file mode 100644
index 0000000..323a15f
--- /dev/null
+++ b/exec/quorum.c
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2008-2012 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Author: Christine Caulfield (ccaulfie@redhat.com)
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of the MontaVista Software, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.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 <time.h>
+#include <arpa/inet.h>
+
+#include <corosync/corotypes.h>
+#include <corosync/swab.h>
+#include <corosync/totem/totempg.h>
+#include <corosync/totem/totem.h>
+#include <corosync/logsys.h>
+
+#include "quorum.h"
+#include "main.h"
+#include "vsf.h"
+
+LOGSYS_DECLARE_SUBSYS ("QUORUM");
+
+static struct quorum_callin_functions *corosync_quorum_fns = NULL;
+
+int corosync_quorum_is_quorate (void)
+{
+ if (corosync_quorum_fns) {
+ return corosync_quorum_fns->quorate();
+ }
+ else {
+ return 1;
+ }
+}
+
+int corosync_quorum_register_callback (quorum_callback_fn_t fn, void *context)
+{
+ if (corosync_quorum_fns) {
+ return corosync_quorum_fns->register_callback(fn, context);
+ }
+ else {
+ return 0;
+ }
+}
+
+int corosync_quorum_unregister_callback (quorum_callback_fn_t fn, void *context)
+{
+ if (corosync_quorum_fns) {
+ return corosync_quorum_fns->unregister_callback(fn, context);
+ }
+ else {
+ return 0;
+ }
+}
+
+int corosync_quorum_initialize (struct quorum_callin_functions *fns)
+{
+ if (corosync_quorum_fns)
+ return -1;
+
+ corosync_quorum_fns = fns;
+ return 0;
+}
+
+int quorum_none(void)
+{
+ if (corosync_quorum_fns)
+ return 0;
+ else
+ return 1;
+}
diff --git a/exec/quorum.h b/exec/quorum.h
new file mode 100644
index 0000000..bd99ee5
--- /dev/null
+++ b/exec/quorum.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2008-2012 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Author: Christine Caulfield (ccaulfie@redhat.com)
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of the Red Hat, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef QUORUM_H_DEFINED
+#define QUORUM_H_DEFINED
+
+struct memb_ring_id;
+
+typedef void (*quorum_callback_fn_t) (int quorate, void *context);
+
+typedef void (*quorum_set_quorate_fn_t) (const unsigned int *view_list,
+ size_t view_list_entries,
+ int quorate, struct memb_ring_id *);
+
+struct quorum_callin_functions
+{
+ int (*quorate) (void);
+ int (*register_callback) (quorum_callback_fn_t, void*);
+ int (*unregister_callback) (quorum_callback_fn_t, void*);
+};
+
+extern int corosync_quorum_is_quorate (void);
+
+extern int corosync_quorum_register_callback (quorum_callback_fn_t fn, void *context);
+
+extern int corosync_quorum_unregister_callback (quorum_callback_fn_t fn, void *context);
+
+extern int corosync_quorum_initialize (struct quorum_callin_functions *fns);
+
+
+extern int quorum_none(void);
+
+
+#endif /* QUORUM_H_DEFINED */
diff --git a/exec/schedwrk.c b/exec/schedwrk.c
new file mode 100644
index 0000000..3f5d424
--- /dev/null
+++ b/exec/schedwrk.c
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) 2009-2010 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Author: Steven Dake (sdake@redhat.com)
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of the MontaVista Software, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <config.h>
+#include <corosync/totem/totempg.h>
+#include <corosync/hdb.h>
+#include "schedwrk.h"
+
+static void (*serialize_lock) (void);
+static void (*serialize_unlock) (void);
+
+DECLARE_HDB_DATABASE (schedwrk_instance_database,NULL);
+
+struct schedwrk_instance {
+ int (*schedwrk_fn) (const void *);
+ const void *context;
+ void *callback_handle;
+ int lock;
+};
+
+static int schedwrk_do (enum totem_callback_token_type type, const void *context)
+{
+ hdb_handle_t handle = *((hdb_handle_t *)context);
+ struct schedwrk_instance *instance;
+ int res;
+
+ res = hdb_handle_get (&schedwrk_instance_database,
+ handle,
+ (void *)&instance);
+ if (res != 0) {
+ goto error_exit;
+ }
+
+ if (instance->lock)
+ serialize_lock ();
+
+ res = instance->schedwrk_fn (instance->context);
+
+ if (instance->lock)
+ serialize_unlock ();
+
+ if (res == 0) {
+ hdb_handle_destroy (&schedwrk_instance_database, handle);
+ }
+ hdb_handle_put (&schedwrk_instance_database, handle);
+ return (res);
+
+error_exit:
+ return (-1);
+}
+
+void schedwrk_init (
+ void (*serialize_lock_fn) (void),
+ void (*serialize_unlock_fn) (void))
+{
+ serialize_lock = serialize_lock_fn;
+ serialize_unlock = serialize_unlock_fn;
+}
+
+static int schedwrk_internal_create (
+ hdb_handle_t *handle,
+ int (schedwrk_fn) (const void *),
+ const void *context,
+ int lock)
+{
+ struct schedwrk_instance *instance;
+ int res;
+
+ res = hdb_handle_create (&schedwrk_instance_database,
+ sizeof (struct schedwrk_instance), handle);
+ if (res != 0) {
+ goto error_exit;
+ }
+ res = hdb_handle_get (&schedwrk_instance_database, *handle,
+ (void *)&instance);
+ if (res != 0) {
+ goto error_destroy;
+ }
+
+ totempg_callback_token_create (
+ &instance->callback_handle,
+ TOTEM_CALLBACK_TOKEN_SENT,
+ 1,
+ schedwrk_do,
+ handle);
+
+ instance->schedwrk_fn = schedwrk_fn;
+ instance->context = context;
+ instance->lock = lock;
+
+ hdb_handle_put (&schedwrk_instance_database, *handle);
+
+ return (0);
+
+error_destroy:
+ hdb_handle_destroy (&schedwrk_instance_database, *handle);
+
+error_exit:
+ return (-1);
+}
+
+/*
+ * handle pointer is internally used by totempg_callback_token_create. To make schedwrk work,
+ * handle must be pointer to ether heap or .text or static memory (not stack) which is not
+ * changed by caller.
+ */
+int schedwrk_create (
+ hdb_handle_t *handle,
+ int (schedwrk_fn) (const void *),
+ const void *context)
+{
+ return schedwrk_internal_create (handle, schedwrk_fn, context, 1);
+}
+
+int schedwrk_create_nolock (
+ hdb_handle_t *handle,
+ int (schedwrk_fn) (const void *),
+ const void *context)
+{
+ return schedwrk_internal_create (handle, schedwrk_fn, context, 0);
+}
+
+void schedwrk_destroy (hdb_handle_t handle)
+{
+ hdb_handle_destroy (&schedwrk_instance_database, handle);
+}
diff --git a/exec/schedwrk.h b/exec/schedwrk.h
new file mode 100644
index 0000000..32ea646
--- /dev/null
+++ b/exec/schedwrk.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2009-2010 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Author: Steven Dake (sdake@redhat.com)
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of the MontaVista Software, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef SCHEDWRK_H_DEFINED
+#define SCHEDWRK_H_DEFINED
+
+extern void schedwrk_init (
+ void (*serialize_lock_fn) (void),
+ void (*serialize_unlock_fn) (void));
+
+extern int schedwrk_create (
+ hdb_handle_t *handle,
+ int (schedwrk_fn) (const void *),
+ const void *context);
+
+extern int schedwrk_create_nolock (
+ hdb_handle_t *handle,
+ int (schedwrk_fn) (const void *),
+ const void *context);
+
+extern void schedwrk_destroy (hdb_handle_t handle);
+
+#endif /* SCHEDWRK_H_DEFINED */
diff --git a/exec/service.c b/exec/service.c
new file mode 100644
index 0000000..fdd16d9
--- /dev/null
+++ b/exec/service.c
@@ -0,0 +1,468 @@
+/*
+ * Copyright (c) 2006 MontaVista Software, Inc.
+ * Copyright (c) 2006-2012 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Author: Steven Dake (sdake@redhat.com)
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of the MontaVista Software, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <corosync/swab.h>
+#include <corosync/totem/totem.h>
+
+#include <corosync/corotypes.h>
+#include "util.h"
+#include <corosync/logsys.h>
+#include <corosync/icmap.h>
+
+#include "timer.h"
+#include <corosync/totem/totempg.h>
+#include <corosync/totem/totemip.h>
+#include "main.h"
+#include "service.h"
+
+#include <qb/qbipcs.h>
+#include <qb/qbloop.h>
+
+LOGSYS_DECLARE_SUBSYS ("SERV");
+
+static struct default_service default_services[] = {
+ {
+ .name = "corosync_cmap",
+ .ver = 0,
+ .loader = cmap_get_service_engine_ver0
+ },
+ {
+ .name = "corosync_cfg",
+ .ver = 0,
+ .loader = cfg_get_service_engine_ver0
+ },
+ {
+ .name = "corosync_cpg",
+ .ver = 0,
+ .loader = cpg_get_service_engine_ver0
+ },
+ {
+ .name = "corosync_pload",
+ .ver = 0,
+ .loader = pload_get_service_engine_ver0
+ },
+#ifdef HAVE_MONITORING
+ {
+ .name = "corosync_mon",
+ .ver = 0,
+ .loader = mon_get_service_engine_ver0
+ },
+#endif
+#ifdef HAVE_WATCHDOG
+ {
+ .name = "corosync_wd",
+ .ver = 0,
+ .loader = wd_get_service_engine_ver0
+ },
+#endif
+ {
+ .name = "corosync_quorum",
+ .ver = 0,
+ .loader = vsf_quorum_get_service_engine_ver0
+ },
+};
+
+/*
+ * service exit and unlink schedwrk handler data structure
+ */
+struct seus_handler_data {
+ int service_engine;
+ struct corosync_api_v1 *api;
+};
+
+struct corosync_service_engine *corosync_service[SERVICES_COUNT_MAX];
+
+const char *service_stats_rx[SERVICES_COUNT_MAX][SERVICE_HANDLER_MAXIMUM_COUNT];
+const char *service_stats_tx[SERVICES_COUNT_MAX][SERVICE_HANDLER_MAXIMUM_COUNT];
+
+static void (*service_unlink_all_complete) (void) = NULL;
+
+char *corosync_service_link_and_init (
+ struct corosync_api_v1 *corosync_api,
+ struct default_service *service)
+{
+ struct corosync_service_engine *service_engine;
+ int fn;
+ char *name_sufix;
+ char key_name[ICMAP_KEYNAME_MAXLEN];
+ char *init_result;
+
+ /*
+ * Initialize service
+ */
+ service_engine = service->loader();
+
+ corosync_service[service_engine->id] = service_engine;
+
+ if (service_engine->config_init_fn) {
+ service_engine->config_init_fn (corosync_api);
+ }
+
+ if (service_engine->exec_init_fn) {
+ init_result = service_engine->exec_init_fn (corosync_api);
+ if (init_result) {
+ return (init_result);
+ }
+ }
+
+ /*
+ * Store service in cmap db
+ */
+ snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "internal_configuration.service.%u.name", service_engine->id);
+ icmap_set_string(key_name, service->name);
+
+ snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "internal_configuration.service.%u.ver", service_engine->id);
+ icmap_set_uint32(key_name, service->ver);
+
+ name_sufix = strrchr (service->name, '_');
+ if (name_sufix)
+ name_sufix++;
+ else
+ name_sufix = (char*)service->name;
+
+ snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "runtime.services.%s.service_id", name_sufix);
+ icmap_set_uint16(key_name, service_engine->id);
+
+ for (fn = 0; fn < service_engine->exec_engine_count; fn++) {
+ snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "runtime.services.%s.%d.tx", name_sufix, fn);
+ icmap_set_uint64(key_name, 0);
+ service_stats_tx[service_engine->id][fn] = strdup(key_name);
+
+ snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "runtime.services.%s.%d.rx", name_sufix, fn);
+ icmap_set_uint64(key_name, 0);
+ service_stats_rx[service_engine->id][fn] = strdup(key_name);
+ }
+
+ log_printf (LOGSYS_LEVEL_NOTICE,
+ "Service engine loaded: %s [%d]", service_engine->name, service_engine->id);
+ init_result = (char *)cs_ipcs_service_init(service_engine);
+ if (init_result != NULL) {
+ return (init_result);
+ }
+
+ return NULL;
+}
+
+static int service_priority_max(void)
+{
+ int lpc = 0, max = 0;
+ for(; lpc < SERVICES_COUNT_MAX; lpc++) {
+ if(corosync_service[lpc] != NULL && corosync_service[lpc]->priority > max) {
+ max = corosync_service[lpc]->priority;
+ }
+ }
+ return max;
+}
+
+/*
+ * use the force
+ */
+static unsigned int
+corosync_service_unlink_and_exit_priority (
+ struct corosync_api_v1 *corosync_api,
+ int lowest_priority,
+ int *current_priority,
+ int *current_service_engine)
+{
+ unsigned short service_id;
+ int res;
+
+ for(; *current_priority >= lowest_priority; *current_priority = *current_priority - 1) {
+ for(*current_service_engine = 0;
+ *current_service_engine < SERVICES_COUNT_MAX;
+ *current_service_engine = *current_service_engine + 1) {
+
+ if(corosync_service[*current_service_engine] == NULL ||
+ corosync_service[*current_service_engine]->priority != *current_priority) {
+ continue;
+ }
+
+ /*
+ * find service handle and unload it if possible.
+ *
+ * If the service engine's exec_exit_fn returns -1 indicating
+ * it was busy, this function returns -1 and can be called again
+ * at a later time (usually via the schedwrk api).
+ */
+ service_id = corosync_service[*current_service_engine]->id;
+
+ if (corosync_service[service_id]->exec_exit_fn) {
+ res = corosync_service[service_id]->exec_exit_fn ();
+ if (res == -1) {
+ return (-1);
+ }
+ }
+
+ /*
+ * Exit all ipc connections dependent on this service
+ */
+ cs_ipcs_service_destroy (*current_service_engine);
+
+ log_printf(LOGSYS_LEVEL_NOTICE,
+ "Service engine unloaded: %s",
+ corosync_service[*current_service_engine]->name);
+
+ corosync_service[*current_service_engine] = NULL;
+
+ /*
+ * Call should call this function again
+ */
+ return (1);
+ }
+ }
+ /*
+ * We finish unlink of all services -> no need to call this function again
+ */
+ return (0);
+}
+
+static unsigned int service_unlink_and_exit (
+ struct corosync_api_v1 *corosync_api,
+ const char *service_name,
+ unsigned int service_ver)
+{
+ unsigned short service_id;
+ char *name_sufix;
+ int res;
+ const char *iter_key_name;
+ icmap_iter_t iter;
+ char key_name[ICMAP_KEYNAME_MAXLEN];
+ unsigned int found_service_ver;
+ char *found_service_name;
+ int service_found;
+
+ name_sufix = strrchr (service_name, '_');
+ if (name_sufix)
+ name_sufix++;
+ else
+ name_sufix = (char*)service_name;
+
+
+ service_found = 0;
+ found_service_name = NULL;
+ iter = icmap_iter_init("internal_configuration.service.");
+ while ((iter_key_name = icmap_iter_next(iter, NULL, NULL)) != NULL) {
+ res = sscanf(iter_key_name, "internal_configuration.service.%hu.%s", &service_id, key_name);
+ if (res != 2) {
+ continue;
+ }
+
+ snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "internal_configuration.service.%hu.name", service_id);
+ if (icmap_get_string(key_name, &found_service_name) != CS_OK) {
+ continue;
+ }
+
+ snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "internal_configuration.service.%u.ver", service_id);
+ if (icmap_get_uint32(key_name, &found_service_ver) != CS_OK) {
+ free(found_service_name);
+ continue;
+ }
+
+ if (service_ver == found_service_ver && strcmp(found_service_name, service_name) == 0) {
+ free(found_service_name);
+ service_found = 1;
+ break;
+ }
+ free(found_service_name);
+ }
+ icmap_iter_finalize(iter);
+
+ if (service_found && service_id < SERVICES_COUNT_MAX
+ && corosync_service[service_id] != NULL) {
+
+ if (corosync_service[service_id]->exec_exit_fn) {
+ res = corosync_service[service_id]->exec_exit_fn ();
+ if (res == -1) {
+ return (-1);
+ }
+ }
+
+ log_printf(LOGSYS_LEVEL_NOTICE,
+ "Service engine unloaded: %s",
+ corosync_service[service_id]->name);
+
+ corosync_service[service_id] = NULL;
+
+ cs_ipcs_service_destroy (service_id);
+
+ snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "internal_configuration.service.%u.handle", service_id);
+ icmap_delete(key_name);
+ snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "internal_configuration.service.%u.name", service_id);
+ icmap_delete(key_name);
+ snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "internal_configuration.service.%u.ver", service_id);
+ icmap_delete(key_name);
+ }
+
+ return (0);
+}
+
+/*
+ * Links default services into the executive
+ */
+unsigned int corosync_service_defaults_link_and_init (struct corosync_api_v1 *corosync_api)
+{
+ unsigned int i;
+ char *error;
+
+ for (i = 0;
+ i < sizeof (default_services) / sizeof (struct default_service); i++) {
+
+ default_services[i].loader();
+ error = corosync_service_link_and_init (
+ corosync_api,
+ &default_services[i]);
+ if (error) {
+ log_printf(LOGSYS_LEVEL_ERROR,
+ "Service engine '%s' failed to load for reason '%s'",
+ default_services[i].name,
+ error);
+ corosync_exit_error (COROSYNC_DONE_SERVICE_ENGINE_INIT);
+ }
+ }
+
+ return (0);
+}
+
+static void service_exit_schedwrk_handler (void *data) {
+ int res;
+ static int current_priority = 0;
+ static int current_service_engine = 0;
+ static int called = 0;
+ struct seus_handler_data *cb_data = (struct seus_handler_data *)data;
+ struct corosync_api_v1 *api = (struct corosync_api_v1 *)cb_data->api;
+
+ if (called == 0) {
+ log_printf(LOGSYS_LEVEL_NOTICE,
+ "Unloading all Corosync service engines.");
+ current_priority = service_priority_max ();
+ called = 1;
+ }
+
+ res = corosync_service_unlink_and_exit_priority (
+ api,
+ 0,
+ &current_priority,
+ &current_service_engine);
+ if (res == 0) {
+ service_unlink_all_complete();
+ return;
+ }
+
+ qb_loop_job_add(cs_poll_handle_get(),
+ QB_LOOP_HIGH,
+ data,
+ service_exit_schedwrk_handler);
+}
+
+void corosync_service_unlink_all (
+ struct corosync_api_v1 *api,
+ void (*unlink_all_complete) (void))
+{
+ static int called = 0;
+ static struct seus_handler_data cb_data;
+
+ assert (api);
+
+ service_unlink_all_complete = unlink_all_complete;
+
+ if (called) {
+ return;
+ }
+ if (called == 0) {
+ called = 1;
+ }
+
+ cb_data.api = api;
+
+ qb_loop_job_add(cs_poll_handle_get(),
+ QB_LOOP_HIGH,
+ &cb_data,
+ service_exit_schedwrk_handler);
+}
+
+struct service_unlink_and_exit_data {
+ hdb_handle_t handle;
+ struct corosync_api_v1 *api;
+ const char *name;
+ unsigned int ver;
+};
+
+static void service_unlink_and_exit_schedwrk_handler (void *data)
+{
+ struct service_unlink_and_exit_data *service_unlink_and_exit_data =
+ data;
+ int res;
+
+ res = service_unlink_and_exit (
+ service_unlink_and_exit_data->api,
+ service_unlink_and_exit_data->name,
+ service_unlink_and_exit_data->ver);
+
+ if (res == 0) {
+ free (service_unlink_and_exit_data);
+ } else {
+ qb_loop_job_add(cs_poll_handle_get(),
+ QB_LOOP_HIGH,
+ data,
+ service_unlink_and_exit_schedwrk_handler);
+ }
+}
+
+typedef int (*schedwrk_cast) (const void *);
+
+unsigned int corosync_service_unlink_and_exit (
+ struct corosync_api_v1 *api,
+ const char *service_name,
+ unsigned int service_ver)
+{
+ struct service_unlink_and_exit_data *service_unlink_and_exit_data;
+
+ assert (api);
+ service_unlink_and_exit_data = malloc (sizeof (struct service_unlink_and_exit_data));
+ service_unlink_and_exit_data->api = api;
+ service_unlink_and_exit_data->name = strdup (service_name);
+ service_unlink_and_exit_data->ver = service_ver;
+
+ qb_loop_job_add(cs_poll_handle_get(),
+ QB_LOOP_HIGH,
+ service_unlink_and_exit_data,
+ service_unlink_and_exit_schedwrk_handler);
+ return (0);
+}
diff --git a/exec/service.h b/exec/service.h
new file mode 100644
index 0000000..12fd751
--- /dev/null
+++ b/exec/service.h
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2002-2006 MontaVista Software, Inc.
+ * Copyright (c) 2006-2012 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Author: Steven Dake (sdake@redhat.com)
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of the MontaVista Software, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef COROSYNC_SERVICE_H_DEFINED
+#define COROSYNC_SERVICE_H_DEFINED
+
+#include <corosync/hdb.h>
+
+struct corosync_api_v1;
+
+struct default_service {
+ const char *name;
+ int ver;
+ struct corosync_service_engine *(*loader)(void);
+};
+
+/**
+ * Link and initialize a service
+ */
+char *corosync_service_link_and_init (
+ struct corosync_api_v1 *objdb,
+ struct default_service *service_engine);
+
+/**
+ * Unlink and exit a service
+ */
+extern unsigned int corosync_service_unlink_and_exit (
+ struct corosync_api_v1 *objdb,
+ const char *service_name,
+ unsigned int service_ver);
+
+/**
+ * Unlink and exit all corosync services
+ */
+extern void corosync_service_unlink_all (
+ struct corosync_api_v1 *api,
+ void (*unlink_all_complete) (void));
+
+/**
+ * Load all of the default services
+ */
+extern unsigned int corosync_service_defaults_link_and_init (
+ struct corosync_api_v1 *objdb);
+
+extern struct corosync_service_engine *corosync_service[];
+
+extern const char *service_stats_rx[SERVICES_COUNT_MAX][SERVICE_HANDLER_MAXIMUM_COUNT];
+extern const char *service_stats_tx[SERVICES_COUNT_MAX][SERVICE_HANDLER_MAXIMUM_COUNT];
+
+struct corosync_service_engine *votequorum_get_service_engine_ver0 (void);
+struct corosync_service_engine *vsf_quorum_get_service_engine_ver0 (void);
+struct corosync_service_engine *quorum_get_service_handler_ver0 (void);
+struct corosync_service_engine *pload_get_service_engine_ver0 (void);
+struct corosync_service_engine *cfg_get_service_engine_ver0 (void);
+struct corosync_service_engine *cpg_get_service_engine_ver0 (void);
+struct corosync_service_engine *mon_get_service_engine_ver0 (void);
+struct corosync_service_engine *wd_get_service_engine_ver0 (void);
+struct corosync_service_engine *cmap_get_service_engine_ver0 (void);
+
+#endif /* SERVICE_H_DEFINED */
diff --git a/exec/stats.c b/exec/stats.c
new file mode 100644
index 0000000..d9fd115
--- /dev/null
+++ b/exec/stats.c
@@ -0,0 +1,784 @@
+/*
+ * Copyright (c) 2017-2020 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Authors: Christine Caulfield (ccaulfie@redhat.com)
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of the MontaVista Software, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdint.h>
+#include <stddef.h>
+#include <unistd.h>
+#include <libknet.h>
+
+#include <qb/qblist.h>
+#include <qb/qbipcs.h>
+#include <qb/qbipc_common.h>
+
+#include <corosync/corodefs.h>
+#include <corosync/coroapi.h>
+#include <corosync/logsys.h>
+#include <corosync/icmap.h>
+#include <corosync/totem/totemstats.h>
+
+#include "util.h"
+#include "ipcs_stats.h"
+#include "stats.h"
+
+LOGSYS_DECLARE_SUBSYS ("STATS");
+
+static qb_map_t *stats_map;
+
+/* Structure of an element in the schedmiss array */
+struct schedmiss_entry {
+ uint64_t timestamp;
+ float delay;
+};
+#define MAX_SCHEDMISS_EVENTS 10
+static struct schedmiss_entry schedmiss_event[MAX_SCHEDMISS_EVENTS];
+static unsigned int highest_schedmiss_event;
+
+#define SCHEDMISS_PREFIX "stats.schedmiss"
+
+/* Convert iterator number to text and a stats pointer */
+struct cs_stats_conv {
+ enum {STAT_PG, STAT_SRP, STAT_KNET, STAT_KNET_HANDLE, STAT_IPCSC, STAT_IPCSG, STAT_SCHEDMISS} type;
+ const char *name;
+ const size_t offset;
+ const icmap_value_types_t value_type;
+};
+
+struct cs_stats_conv cs_pg_stats[] = {
+ { STAT_PG, "msg_queue_avail", offsetof(totempg_stats_t, msg_queue_avail), ICMAP_VALUETYPE_UINT32},
+ { STAT_PG, "msg_reserved", offsetof(totempg_stats_t, msg_reserved), ICMAP_VALUETYPE_UINT32},
+};
+struct cs_stats_conv cs_srp_stats[] = {
+ { STAT_SRP, "orf_token_tx", offsetof(totemsrp_stats_t, orf_token_tx), ICMAP_VALUETYPE_UINT64},
+ { STAT_SRP, "orf_token_rx", offsetof(totemsrp_stats_t, orf_token_rx), ICMAP_VALUETYPE_UINT64},
+ { STAT_SRP, "memb_merge_detect_tx", offsetof(totemsrp_stats_t, memb_merge_detect_tx), ICMAP_VALUETYPE_UINT64},
+ { STAT_SRP, "memb_merge_detect_rx", offsetof(totemsrp_stats_t, memb_merge_detect_rx), ICMAP_VALUETYPE_UINT64},
+ { STAT_SRP, "memb_join_tx", offsetof(totemsrp_stats_t, memb_join_tx), ICMAP_VALUETYPE_UINT64},
+ { STAT_SRP, "memb_join_rx", offsetof(totemsrp_stats_t, memb_join_rx), ICMAP_VALUETYPE_UINT64},
+ { STAT_SRP, "mcast_tx", offsetof(totemsrp_stats_t, mcast_tx), ICMAP_VALUETYPE_UINT64},
+ { STAT_SRP, "mcast_retx", offsetof(totemsrp_stats_t, mcast_retx), ICMAP_VALUETYPE_UINT64},
+ { STAT_SRP, "mcast_rx", offsetof(totemsrp_stats_t, mcast_rx), ICMAP_VALUETYPE_UINT64},
+ { STAT_SRP, "memb_commit_token_tx", offsetof(totemsrp_stats_t, memb_commit_token_tx), ICMAP_VALUETYPE_UINT64},
+ { STAT_SRP, "memb_commit_token_rx", offsetof(totemsrp_stats_t, memb_commit_token_rx), ICMAP_VALUETYPE_UINT64},
+ { STAT_SRP, "token_hold_cancel_tx", offsetof(totemsrp_stats_t, token_hold_cancel_tx), ICMAP_VALUETYPE_UINT64},
+ { STAT_SRP, "token_hold_cancel_rx", offsetof(totemsrp_stats_t, token_hold_cancel_rx), ICMAP_VALUETYPE_UINT64},
+ { STAT_SRP, "operational_entered", offsetof(totemsrp_stats_t, operational_entered), ICMAP_VALUETYPE_UINT64},
+ { STAT_SRP, "operational_token_lost", offsetof(totemsrp_stats_t, operational_token_lost), ICMAP_VALUETYPE_UINT64},
+ { STAT_SRP, "gather_entered", offsetof(totemsrp_stats_t, gather_entered), ICMAP_VALUETYPE_UINT64},
+ { STAT_SRP, "gather_token_lost", offsetof(totemsrp_stats_t, gather_token_lost), ICMAP_VALUETYPE_UINT64},
+ { STAT_SRP, "commit_entered", offsetof(totemsrp_stats_t, commit_entered), ICMAP_VALUETYPE_UINT64},
+ { STAT_SRP, "commit_token_lost", offsetof(totemsrp_stats_t, commit_token_lost), ICMAP_VALUETYPE_UINT64},
+ { STAT_SRP, "recovery_entered", offsetof(totemsrp_stats_t, recovery_entered), ICMAP_VALUETYPE_UINT64},
+ { STAT_SRP, "recovery_token_lost", offsetof(totemsrp_stats_t, recovery_token_lost), ICMAP_VALUETYPE_UINT64},
+ { STAT_SRP, "consensus_timeouts", offsetof(totemsrp_stats_t, consensus_timeouts), ICMAP_VALUETYPE_UINT64},
+ { STAT_SRP, "rx_msg_dropped", offsetof(totemsrp_stats_t, rx_msg_dropped), ICMAP_VALUETYPE_UINT64},
+ { STAT_SRP, "time_since_token_last_received", offsetof(totemsrp_stats_t, time_since_token_last_received), ICMAP_VALUETYPE_UINT64},
+ { STAT_SRP, "continuous_gather", offsetof(totemsrp_stats_t, continuous_gather), ICMAP_VALUETYPE_UINT32},
+ { STAT_SRP, "continuous_sendmsg_failures", offsetof(totemsrp_stats_t, continuous_sendmsg_failures), ICMAP_VALUETYPE_UINT32},
+ { STAT_SRP, "firewall_enabled_or_nic_failure", offsetof(totemsrp_stats_t, firewall_enabled_or_nic_failure), ICMAP_VALUETYPE_UINT8},
+ { STAT_SRP, "mtt_rx_token", offsetof(totemsrp_stats_t, mtt_rx_token), ICMAP_VALUETYPE_UINT32},
+ { STAT_SRP, "avg_token_workload", offsetof(totemsrp_stats_t, avg_token_workload), ICMAP_VALUETYPE_UINT32},
+ { STAT_SRP, "avg_backlog_calc", offsetof(totemsrp_stats_t, avg_backlog_calc), ICMAP_VALUETYPE_UINT32},
+};
+
+struct cs_stats_conv cs_knet_stats[] = {
+ { STAT_KNET, "enabled", offsetof(struct knet_link_status, enabled), ICMAP_VALUETYPE_UINT8},
+ { STAT_KNET, "connected", offsetof(struct knet_link_status, connected), ICMAP_VALUETYPE_UINT8},
+ { STAT_KNET, "mtu", offsetof(struct knet_link_status, mtu), ICMAP_VALUETYPE_UINT32},
+ { STAT_KNET, "tx_data_packets", offsetof(struct knet_link_status, stats.tx_data_packets), ICMAP_VALUETYPE_UINT64},
+ { STAT_KNET, "rx_data_packets", offsetof(struct knet_link_status, stats.rx_data_packets), ICMAP_VALUETYPE_UINT64},
+ { STAT_KNET, "tx_data_bytes", offsetof(struct knet_link_status, stats.tx_data_bytes), ICMAP_VALUETYPE_UINT64},
+ { STAT_KNET, "rx_data_bytes", offsetof(struct knet_link_status, stats.rx_data_bytes), ICMAP_VALUETYPE_UINT64},
+ { STAT_KNET, "tx_ping_packets", offsetof(struct knet_link_status, stats.tx_ping_packets), ICMAP_VALUETYPE_UINT64},
+ { STAT_KNET, "rx_ping_packets", offsetof(struct knet_link_status, stats.rx_ping_packets), ICMAP_VALUETYPE_UINT64},
+ { STAT_KNET, "tx_ping_bytes", offsetof(struct knet_link_status, stats.tx_ping_bytes), ICMAP_VALUETYPE_UINT64},
+ { STAT_KNET, "rx_ping_bytes", offsetof(struct knet_link_status, stats.rx_ping_bytes), ICMAP_VALUETYPE_UINT64},
+ { STAT_KNET, "tx_pong_packets", offsetof(struct knet_link_status, stats.tx_pong_packets), ICMAP_VALUETYPE_UINT64},
+ { STAT_KNET, "rx_pong_packets", offsetof(struct knet_link_status, stats.rx_pong_packets), ICMAP_VALUETYPE_UINT64},
+ { STAT_KNET, "tx_pong_bytes", offsetof(struct knet_link_status, stats.tx_pong_bytes), ICMAP_VALUETYPE_UINT64},
+ { STAT_KNET, "rx_pong_bytes", offsetof(struct knet_link_status, stats.rx_pong_bytes), ICMAP_VALUETYPE_UINT64},
+ { STAT_KNET, "tx_pmtu_packets", offsetof(struct knet_link_status, stats.tx_pmtu_packets), ICMAP_VALUETYPE_UINT64},
+ { STAT_KNET, "rx_pmtu_packets", offsetof(struct knet_link_status, stats.rx_pmtu_packets), ICMAP_VALUETYPE_UINT64},
+ { STAT_KNET, "tx_pmtu_bytes", offsetof(struct knet_link_status, stats.tx_pmtu_bytes), ICMAP_VALUETYPE_UINT64},
+ { STAT_KNET, "rx_pmtu_bytes", offsetof(struct knet_link_status, stats.rx_pmtu_bytes), ICMAP_VALUETYPE_UINT64},
+ { STAT_KNET, "tx_total_packets", offsetof(struct knet_link_status, stats.tx_total_packets), ICMAP_VALUETYPE_UINT64},
+ { STAT_KNET, "rx_total_packets", offsetof(struct knet_link_status, stats.rx_total_packets), ICMAP_VALUETYPE_UINT64},
+ { STAT_KNET, "tx_total_bytes", offsetof(struct knet_link_status, stats.tx_total_bytes), ICMAP_VALUETYPE_UINT64},
+ { STAT_KNET, "rx_total_bytes", offsetof(struct knet_link_status, stats.rx_total_bytes), ICMAP_VALUETYPE_UINT64},
+ { STAT_KNET, "tx_total_errors", offsetof(struct knet_link_status, stats.tx_total_errors), ICMAP_VALUETYPE_UINT64},
+ { STAT_KNET, "rx_total_retries", offsetof(struct knet_link_status, stats.tx_total_retries), ICMAP_VALUETYPE_UINT64},
+ { STAT_KNET, "tx_pmtu_errors", offsetof(struct knet_link_status, stats.tx_pmtu_errors), ICMAP_VALUETYPE_UINT32},
+ { STAT_KNET, "tx_pmtu_retries", offsetof(struct knet_link_status, stats.tx_pmtu_retries), ICMAP_VALUETYPE_UINT32},
+ { STAT_KNET, "tx_ping_errors", offsetof(struct knet_link_status, stats.tx_ping_errors), ICMAP_VALUETYPE_UINT32},
+ { STAT_KNET, "tx_ping_retries", offsetof(struct knet_link_status, stats.tx_ping_retries), ICMAP_VALUETYPE_UINT32},
+ { STAT_KNET, "tx_pong_errors", offsetof(struct knet_link_status, stats.tx_pong_errors), ICMAP_VALUETYPE_UINT32},
+ { STAT_KNET, "tx_pong_retries", offsetof(struct knet_link_status, stats.tx_pong_retries), ICMAP_VALUETYPE_UINT32},
+ { STAT_KNET, "tx_data_errors", offsetof(struct knet_link_status, stats.tx_data_errors), ICMAP_VALUETYPE_UINT32},
+ { STAT_KNET, "tx_data_retries", offsetof(struct knet_link_status, stats.tx_data_retries), ICMAP_VALUETYPE_UINT32},
+ { STAT_KNET, "latency_min", offsetof(struct knet_link_status, stats.latency_min), ICMAP_VALUETYPE_UINT32},
+ { STAT_KNET, "latency_max", offsetof(struct knet_link_status, stats.latency_max), ICMAP_VALUETYPE_UINT32},
+ { STAT_KNET, "latency_ave", offsetof(struct knet_link_status, stats.latency_ave), ICMAP_VALUETYPE_UINT32},
+ { STAT_KNET, "latency_samples", offsetof(struct knet_link_status, stats.latency_samples), ICMAP_VALUETYPE_UINT32},
+ { STAT_KNET, "down_count", offsetof(struct knet_link_status, stats.down_count), ICMAP_VALUETYPE_UINT32},
+ { STAT_KNET, "up_count", offsetof(struct knet_link_status, stats.up_count), ICMAP_VALUETYPE_UINT32},
+};
+struct cs_stats_conv cs_knet_handle_stats[] = {
+ { STAT_KNET_HANDLE, "tx_uncompressed_packets", offsetof(struct knet_handle_stats, tx_uncompressed_packets), ICMAP_VALUETYPE_UINT64},
+ { STAT_KNET_HANDLE, "tx_compressed_packets", offsetof(struct knet_handle_stats, tx_compressed_packets), ICMAP_VALUETYPE_UINT64},
+ { STAT_KNET_HANDLE, "tx_compressed_original_bytes", offsetof(struct knet_handle_stats, tx_compressed_original_bytes), ICMAP_VALUETYPE_UINT64},
+ { STAT_KNET_HANDLE, "tx_compressed_size_bytes", offsetof(struct knet_handle_stats, tx_compressed_size_bytes), ICMAP_VALUETYPE_UINT64},
+ { STAT_KNET_HANDLE, "tx_compress_time_min", offsetof(struct knet_handle_stats, tx_compress_time_min), ICMAP_VALUETYPE_UINT64},
+ { STAT_KNET_HANDLE, "tx_compress_time_max", offsetof(struct knet_handle_stats, tx_compress_time_max), ICMAP_VALUETYPE_UINT64},
+ { STAT_KNET_HANDLE, "tx_compress_time_ave", offsetof(struct knet_handle_stats, tx_compress_time_ave), ICMAP_VALUETYPE_UINT64},
+ { STAT_KNET_HANDLE, "rx_compressed_packets", offsetof(struct knet_handle_stats, rx_compressed_packets), ICMAP_VALUETYPE_UINT64},
+ { STAT_KNET_HANDLE, "rx_compressed_original_bytes", offsetof(struct knet_handle_stats, rx_compressed_original_bytes), ICMAP_VALUETYPE_UINT64},
+ { STAT_KNET_HANDLE, "rx_compressed_size_bytes", offsetof(struct knet_handle_stats, rx_compressed_size_bytes), ICMAP_VALUETYPE_UINT64},
+ { STAT_KNET_HANDLE, "rx_compress_time_min", offsetof(struct knet_handle_stats, rx_compress_time_min), ICMAP_VALUETYPE_UINT64},
+ { STAT_KNET_HANDLE, "rx_compress_time_max", offsetof(struct knet_handle_stats, rx_compress_time_max), ICMAP_VALUETYPE_UINT64},
+ { STAT_KNET_HANDLE, "rx_compress_time_ave", offsetof(struct knet_handle_stats, rx_compress_time_ave), ICMAP_VALUETYPE_UINT64},
+ { STAT_KNET_HANDLE, "tx_crypt_time_min", offsetof(struct knet_handle_stats, tx_crypt_time_min), ICMAP_VALUETYPE_UINT64},
+ { STAT_KNET_HANDLE, "tx_crypt_time_max", offsetof(struct knet_handle_stats, tx_crypt_time_max), ICMAP_VALUETYPE_UINT64},
+ { STAT_KNET_HANDLE, "tx_crypt_time_ave", offsetof(struct knet_handle_stats, tx_crypt_time_ave), ICMAP_VALUETYPE_UINT64},
+ { STAT_KNET_HANDLE, "tx_crypt_byte_overhead", offsetof(struct knet_handle_stats, tx_crypt_byte_overhead), ICMAP_VALUETYPE_UINT64},
+ { STAT_KNET_HANDLE, "tx_crypt_packets", offsetof(struct knet_handle_stats, tx_crypt_packets), ICMAP_VALUETYPE_UINT64},
+ { STAT_KNET_HANDLE, "rx_crypt_time_min", offsetof(struct knet_handle_stats, rx_crypt_time_min), ICMAP_VALUETYPE_UINT64},
+ { STAT_KNET_HANDLE, "rx_crypt_time_max", offsetof(struct knet_handle_stats, rx_crypt_time_max), ICMAP_VALUETYPE_UINT64},
+ { STAT_KNET_HANDLE, "rx_crypt_time_ave", offsetof(struct knet_handle_stats, rx_crypt_time_ave), ICMAP_VALUETYPE_UINT64},
+ { STAT_KNET_HANDLE, "rx_crypt_packets", offsetof(struct knet_handle_stats, rx_crypt_packets), ICMAP_VALUETYPE_UINT64},
+};
+
+struct cs_stats_conv cs_ipcs_conn_stats[] = {
+ { STAT_IPCSC, "queueing", offsetof(struct ipcs_conn_stats, cnx.queuing), ICMAP_VALUETYPE_INT32},
+ { STAT_IPCSC, "queued", offsetof(struct ipcs_conn_stats, cnx.queued), ICMAP_VALUETYPE_UINT32},
+ { STAT_IPCSC, "invalid_request", offsetof(struct ipcs_conn_stats, cnx.invalid_request), ICMAP_VALUETYPE_UINT64},
+ { STAT_IPCSC, "overload", offsetof(struct ipcs_conn_stats, cnx.overload), ICMAP_VALUETYPE_UINT64},
+ { STAT_IPCSC, "sent", offsetof(struct ipcs_conn_stats, cnx.sent), ICMAP_VALUETYPE_UINT32},
+ { STAT_IPCSC, "procname", offsetof(struct ipcs_conn_stats, cnx.proc_name), ICMAP_VALUETYPE_STRING},
+ { STAT_IPCSC, "requests", offsetof(struct ipcs_conn_stats, conn.requests), ICMAP_VALUETYPE_UINT64},
+ { STAT_IPCSC, "responses", offsetof(struct ipcs_conn_stats, conn.responses), ICMAP_VALUETYPE_UINT64},
+ { STAT_IPCSC, "dispatched", offsetof(struct ipcs_conn_stats, conn.events), ICMAP_VALUETYPE_UINT64},
+ { STAT_IPCSC, "send_retries", offsetof(struct ipcs_conn_stats, conn.send_retries), ICMAP_VALUETYPE_UINT64},
+ { STAT_IPCSC, "recv_retries", offsetof(struct ipcs_conn_stats, conn.recv_retries), ICMAP_VALUETYPE_UINT64},
+ { STAT_IPCSC, "flow_control", offsetof(struct ipcs_conn_stats, conn.flow_control_state), ICMAP_VALUETYPE_UINT32},
+ { STAT_IPCSC, "flow_control_count", offsetof(struct ipcs_conn_stats, conn.flow_control_count), ICMAP_VALUETYPE_UINT64},
+};
+struct cs_stats_conv cs_ipcs_global_stats[] = {
+ { STAT_IPCSG, "global.active", offsetof(struct ipcs_global_stats, active), ICMAP_VALUETYPE_UINT64},
+ { STAT_IPCSG, "global.closed", offsetof(struct ipcs_global_stats, closed), ICMAP_VALUETYPE_UINT64},
+};
+struct cs_stats_conv cs_schedmiss_stats[] = {
+ { STAT_SCHEDMISS, "timestamp", offsetof(struct schedmiss_entry, timestamp), ICMAP_VALUETYPE_UINT64},
+ { STAT_SCHEDMISS, "delay", offsetof(struct schedmiss_entry, delay), ICMAP_VALUETYPE_FLOAT},
+};
+
+#define NUM_PG_STATS (sizeof(cs_pg_stats) / sizeof(struct cs_stats_conv))
+#define NUM_SRP_STATS (sizeof(cs_srp_stats) / sizeof(struct cs_stats_conv))
+#define NUM_KNET_STATS (sizeof(cs_knet_stats) / sizeof(struct cs_stats_conv))
+#define NUM_KNET_HANDLE_STATS (sizeof(cs_knet_handle_stats) / sizeof(struct cs_stats_conv))
+#define NUM_IPCSC_STATS (sizeof(cs_ipcs_conn_stats) / sizeof(struct cs_stats_conv))
+#define NUM_IPCSG_STATS (sizeof(cs_ipcs_global_stats) / sizeof(struct cs_stats_conv))
+
+/* What goes in the trie */
+struct stats_item {
+ char *key_name;
+ struct cs_stats_conv * cs_conv;
+};
+
+/* One of these per tracker */
+struct cs_stats_tracker
+{
+ char *key_name;
+ void *user_data;
+ int32_t events;
+ icmap_notify_fn_t notify_fn;
+ uint64_t old_value;
+ struct qb_list_head list;
+};
+QB_LIST_DECLARE (stats_tracker_list_head);
+static const struct corosync_api_v1 *api;
+
+static void stats_map_set_value(struct cs_stats_conv *conv,
+ void *stat_array,
+ void *value,
+ size_t *value_len,
+ icmap_value_types_t *type)
+{
+ if (value_len) {
+ *value_len = icmap_get_valuetype_len(conv->value_type);
+ }
+ if (type) {
+ *type = conv->value_type;
+ if ((*type == ICMAP_VALUETYPE_STRING) && value_len && stat_array) {
+ *value_len = strlen((char *)(stat_array) + conv->offset)+1;
+ }
+ }
+ if (value) {
+ assert(value_len != NULL);
+
+ memcpy(value, (char *)(stat_array) + conv->offset, *value_len);
+ }
+}
+
+static void stats_add_entry(const char *key, struct cs_stats_conv *cs_conv)
+{
+ struct stats_item *item = malloc(sizeof(struct stats_item));
+
+ if (item) {
+ item->cs_conv = cs_conv;
+ item->key_name = strdup(key);
+ qb_map_put(stats_map, item->key_name, item);
+ }
+}
+static void stats_rm_entry(const char *key)
+{
+ struct stats_item *item = qb_map_get(stats_map, key);
+
+ if (item) {
+ qb_map_rm(stats_map, item->key_name);
+ /* Structures freed in callback below */
+ }
+}
+
+static void stats_map_free_cb(uint32_t event,
+ char* key, void* old_value,
+ void* value, void* user_data)
+{
+ struct stats_item *item = (struct stats_item *)old_value;
+
+ if (item) {
+ free(item->key_name);
+ free(item);
+ }
+}
+
+cs_error_t stats_map_init(const struct corosync_api_v1 *corosync_api)
+{
+ int i;
+ char param[ICMAP_KEYNAME_MAXLEN];
+ int32_t err;
+
+ api = corosync_api;
+
+ stats_map = qb_trie_create();
+ if (!stats_map) {
+ return CS_ERR_INIT;
+ }
+
+ /* Populate the static portions of the trie */
+ for (i = 0; i<NUM_PG_STATS; i++) {
+ sprintf(param, "stats.pg.%s", cs_pg_stats[i].name);
+ stats_add_entry(param, &cs_pg_stats[i]);
+ }
+ for (i = 0; i<NUM_SRP_STATS; i++) {
+ sprintf(param, "stats.srp.%s", cs_srp_stats[i].name);
+ stats_add_entry(param, &cs_srp_stats[i]);
+ }
+ for (i = 0; i<NUM_IPCSG_STATS; i++) {
+ sprintf(param, "stats.ipcs.%s", cs_ipcs_global_stats[i].name);
+ stats_add_entry(param, &cs_ipcs_global_stats[i]);
+ }
+
+ /* KNET, IPCS & SCHEDMISS stats are added when appropriate */
+
+
+ /* Call us when we can free things */
+ err = qb_map_notify_add(stats_map, NULL, stats_map_free_cb, QB_MAP_NOTIFY_FREE, NULL);
+
+ return (qb_to_cs_error(err));
+}
+
+cs_error_t stats_map_get(const char *key_name,
+ void *value,
+ size_t *value_len,
+ icmap_value_types_t *type)
+{
+ struct cs_stats_conv *statinfo;
+ struct stats_item *item;
+ totempg_stats_t *pg_stats;
+ struct knet_link_status link_status;
+ struct ipcs_conn_stats ipcs_conn_stats;
+ struct ipcs_global_stats ipcs_global_stats;
+ struct knet_handle_stats knet_handle_stats;
+ int res;
+ int nodeid;
+ int link_no;
+ int service_id;
+ uint32_t pid;
+ unsigned int sm_event;
+ char *sm_type;
+ void *conn_ptr;
+
+ item = qb_map_get(stats_map, key_name);
+ if (!item) {
+ return CS_ERR_NOT_EXIST;
+ }
+
+ statinfo = item->cs_conv;
+ switch (statinfo->type) {
+ case STAT_PG:
+ pg_stats = api->totem_get_stats();
+ stats_map_set_value(statinfo, pg_stats, value, value_len, type);
+ break;
+ case STAT_SRP:
+ pg_stats = api->totem_get_stats();
+ stats_map_set_value(statinfo, pg_stats->srp, value, value_len, type);
+ break;
+ case STAT_KNET_HANDLE:
+ res = totemknet_handle_get_stats(&knet_handle_stats);
+ if (res != CS_OK) {
+ return res;
+ }
+ stats_map_set_value(statinfo, &knet_handle_stats, value, value_len, type);
+ break;
+ case STAT_KNET:
+ if (sscanf(key_name, "stats.knet.node%d.link%d", &nodeid, &link_no) != 2) {
+ return CS_ERR_NOT_EXIST;
+ }
+
+ /* Validate node & link IDs */
+ if (nodeid <= 0 || nodeid > KNET_MAX_HOST ||
+ link_no < 0 || link_no > KNET_MAX_LINK) {
+ return CS_ERR_NOT_EXIST;
+ }
+
+ /* Always get the latest stats */
+ res = totemknet_link_get_status((knet_node_id_t)nodeid, (uint8_t)link_no, &link_status);
+ if (res != CS_OK) {
+ return CS_ERR_LIBRARY;
+ }
+ stats_map_set_value(statinfo, &link_status, value, value_len, type);
+ break;
+ case STAT_IPCSC:
+ if (sscanf(key_name, "stats.ipcs.service%d.%d.%p", &service_id, &pid, &conn_ptr) != 3) {
+ return CS_ERR_NOT_EXIST;
+ }
+ res = cs_ipcs_get_conn_stats(service_id, pid, conn_ptr, &ipcs_conn_stats);
+ if (res != CS_OK) {
+ return res;
+ }
+ stats_map_set_value(statinfo, &ipcs_conn_stats, value, value_len, type);
+ break;
+ case STAT_IPCSG:
+ cs_ipcs_get_global_stats(&ipcs_global_stats);
+ stats_map_set_value(statinfo, &ipcs_global_stats, value, value_len, type);
+ break;
+ case STAT_SCHEDMISS:
+ if (sscanf(key_name, SCHEDMISS_PREFIX ".%d", &sm_event) != 1) {
+ return CS_ERR_NOT_EXIST;
+ }
+
+ sm_type = strrchr(key_name, '.');
+ if (sm_type == NULL) {
+ return CS_ERR_NOT_EXIST;
+ }
+ sm_type++;
+
+ if (strcmp(sm_type, "timestamp") == 0) {
+ memcpy(value, &schedmiss_event[sm_event].timestamp, sizeof(uint64_t));
+ *value_len = sizeof(uint64_t);
+ *type = ICMAP_VALUETYPE_UINT64;
+ }
+ if (strcmp(sm_type, "delay") == 0) {
+ memcpy(value, &schedmiss_event[sm_event].delay, sizeof(float));
+ *value_len = sizeof(float);
+ *type = ICMAP_VALUETYPE_FLOAT;
+ }
+ break;
+ default:
+ return CS_ERR_LIBRARY;
+ }
+ return CS_OK;
+}
+
+static void schedmiss_clear_stats(void)
+{
+ int i;
+ char param[ICMAP_KEYNAME_MAXLEN];
+
+ for (i=0; i<MAX_SCHEDMISS_EVENTS; i++) {
+ if (i < highest_schedmiss_event) {
+ sprintf(param, SCHEDMISS_PREFIX ".%i.timestamp", i);
+ stats_rm_entry(param);
+ sprintf(param, SCHEDMISS_PREFIX ".%i.delay", i);
+ stats_rm_entry(param);
+ }
+ schedmiss_event[i].timestamp = (uint64_t)0LL;
+ schedmiss_event[i].delay = 0.0f;
+ }
+ highest_schedmiss_event = 0;
+}
+
+/* Called from main.c */
+void stats_add_schedmiss_event(uint64_t timestamp, float delay)
+{
+ char param[ICMAP_KEYNAME_MAXLEN];
+ int i;
+
+ /* Move 'em all up */
+ for (i=MAX_SCHEDMISS_EVENTS-2; i>=0; i--) {
+ schedmiss_event[i+1].timestamp = schedmiss_event[i].timestamp;
+ schedmiss_event[i+1].delay = schedmiss_event[i].delay;
+ }
+
+ /* New entries are always at the front */
+ schedmiss_event[0].timestamp = timestamp;
+ schedmiss_event[0].delay = delay;
+
+ /* If we've not run off the end then add an entry in the trie for the new 'end' one */
+ if (highest_schedmiss_event < MAX_SCHEDMISS_EVENTS) {
+ sprintf(param, SCHEDMISS_PREFIX ".%i.timestamp", highest_schedmiss_event);
+ stats_add_entry(param, &cs_schedmiss_stats[0]);
+ sprintf(param, SCHEDMISS_PREFIX ".%i.delay", highest_schedmiss_event);
+ stats_add_entry(param, &cs_schedmiss_stats[1]);
+ highest_schedmiss_event++;
+ }
+ /* Notifications get sent by the stats_updater */
+}
+
+#define STATS_CLEAR "stats.clear."
+#define STATS_CLEAR_KNET "stats.clear.knet"
+#define STATS_CLEAR_IPC "stats.clear.ipc"
+#define STATS_CLEAR_TOTEM "stats.clear.totem"
+#define STATS_CLEAR_ALL "stats.clear.all"
+#define STATS_CLEAR_SCHEDMISS "stats.clear.schedmiss"
+
+cs_error_t stats_map_set(const char *key_name,
+ const void *value,
+ size_t value_len,
+ icmap_value_types_t type)
+{
+ int cleared = 0;
+
+ if (strncmp(key_name, STATS_CLEAR_KNET, strlen(STATS_CLEAR_KNET)) == 0) {
+ totempg_stats_clear(TOTEMPG_STATS_CLEAR_TRANSPORT);
+ cleared = 1;
+ }
+ if (strncmp(key_name, STATS_CLEAR_IPC, strlen(STATS_CLEAR_IPC)) == 0) {
+ cs_ipcs_clear_stats();
+ cleared = 1;
+ }
+ if (strncmp(key_name, STATS_CLEAR_TOTEM, strlen(STATS_CLEAR_TOTEM)) == 0) {
+ totempg_stats_clear(TOTEMPG_STATS_CLEAR_TOTEM);
+ cleared = 1;
+ }
+ if (strncmp(key_name, STATS_CLEAR_SCHEDMISS, strlen(STATS_CLEAR_SCHEDMISS)) == 0) {
+ schedmiss_clear_stats();
+ cleared = 1;
+ }
+ if (strncmp(key_name, STATS_CLEAR_ALL, strlen(STATS_CLEAR_ALL)) == 0) {
+ totempg_stats_clear(TOTEMPG_STATS_CLEAR_TRANSPORT | TOTEMPG_STATS_CLEAR_TOTEM);
+ cs_ipcs_clear_stats();
+ schedmiss_clear_stats();
+ cleared = 1;
+ }
+ if (!cleared) {
+ return CS_ERR_NOT_SUPPORTED;
+ }
+ return CS_OK;
+}
+
+cs_error_t stats_map_adjust_int(const char *key_name, int32_t step)
+{
+ return CS_ERR_NOT_SUPPORTED;
+}
+
+cs_error_t stats_map_delete(const char *key_name)
+{
+ return CS_ERR_NOT_SUPPORTED;
+}
+
+int stats_map_is_key_ro(const char *key_name)
+{
+ /* It's all read-only apart from the 'clear' destinations */
+ if (strncmp(key_name, STATS_CLEAR, strlen(STATS_CLEAR)) == 0) {
+ return 0;
+ } else {
+ return 1;
+ }
+}
+
+icmap_iter_t stats_map_iter_init(const char *prefix)
+{
+ return (qb_map_pref_iter_create(stats_map, prefix));
+}
+
+
+const char *stats_map_iter_next(icmap_iter_t iter, size_t *value_len, icmap_value_types_t *type)
+{
+ const char *res;
+ struct stats_item *item;
+
+ res = qb_map_iter_next(iter, (void **)&item);
+ if (res == NULL) {
+ return (res);
+ }
+ stats_map_set_value(item->cs_conv, NULL, NULL, value_len, type);
+
+ return res;
+}
+
+void stats_map_iter_finalize(icmap_iter_t iter)
+{
+ qb_map_iter_free(iter);
+}
+
+
+void stats_trigger_trackers()
+{
+ struct cs_stats_tracker *tracker;
+ struct qb_list_head *iter;
+ cs_error_t res;
+ size_t value_len;
+ icmap_value_types_t type;
+ uint64_t value;
+ struct icmap_notify_value new_val;
+ struct icmap_notify_value old_val;
+
+ qb_list_for_each(iter, &stats_tracker_list_head) {
+
+ tracker = qb_list_entry(iter, struct cs_stats_tracker, list);
+ if (tracker->events & ICMAP_TRACK_PREFIX || !tracker->key_name ) {
+ continue;
+ }
+
+ res = stats_map_get(tracker->key_name,
+ &value, &value_len, &type);
+
+ /* Check if it has changed */
+ if ((res == CS_OK) && (memcmp(&value, &tracker->old_value, value_len) != 0)) {
+
+ old_val.type = new_val.type = type;
+ old_val.len = new_val.len = value_len;
+ old_val.data = new_val.data = &value;
+
+ tracker->notify_fn(ICMAP_TRACK_MODIFY, tracker->key_name,
+ old_val, new_val, tracker->user_data);
+
+ memcpy(&tracker->old_value, &value, value_len);
+ }
+ }
+}
+
+
+/* Callback from libqb when a key is added/removed */
+static void stats_map_notify_fn(uint32_t event, char *key, void *old_value, void *value, void *user_data)
+{
+ struct cs_stats_tracker *tracker = user_data;
+ struct icmap_notify_value new_val;
+ struct icmap_notify_value old_val;
+ char new_value[64];
+
+ if (value == NULL && old_value == NULL) {
+ return ;
+ }
+
+ /* Ignore schedmiss trackers as the values are read from the circular buffer */
+ if (strncmp(key, SCHEDMISS_PREFIX, strlen(SCHEDMISS_PREFIX)) == 0 ) {
+ return ;
+ }
+
+ new_val.data = new_value;
+ if (stats_map_get(key,
+ &new_value,
+ &new_val.len,
+ &new_val.type) != CS_OK) {
+ log_printf(LOGSYS_LEVEL_WARNING, "get value of notified key %s failed", key);
+ return ;
+ }
+
+ /* We don't know what the old value was
+ but as this only tracks ADD & DELETE I'm not worried
+ about it */
+ memcpy(&old_val, &new_val, sizeof(new_val));
+
+ tracker->notify_fn(icmap_qbtt_to_tt(event),
+ key,
+ new_val,
+ old_val,
+ tracker->user_data);
+
+}
+
+cs_error_t stats_map_track_add(const char *key_name,
+ int32_t track_type,
+ icmap_notify_fn_t notify_fn,
+ void *user_data,
+ icmap_track_t *icmap_track)
+{
+ struct cs_stats_tracker *tracker;
+ size_t value_len;
+ icmap_value_types_t type;
+ cs_error_t err;
+
+ /* We can track adding or deleting a key under a prefix */
+ if ((track_type & ICMAP_TRACK_PREFIX) &&
+ (!(track_type & ICMAP_TRACK_DELETE) ||
+ !(track_type & ICMAP_TRACK_ADD))) {
+ return CS_ERR_NOT_SUPPORTED;
+ }
+
+ tracker = malloc(sizeof(struct cs_stats_tracker));
+ if (!tracker) {
+ return CS_ERR_NO_MEMORY;
+ }
+
+ tracker->notify_fn = notify_fn;
+ tracker->user_data = user_data;
+ tracker->events = track_type;
+ if (key_name) {
+ tracker->key_name = strdup(key_name);
+ if (!tracker->key_name) {
+ free(tracker);
+ return CS_ERR_NO_MEMORY;
+ }
+ /* Get initial value */
+ if (stats_map_get(tracker->key_name,
+ &tracker->old_value, &value_len, &type) != CS_OK) {
+ tracker->old_value = 0ULL;
+ }
+ } else {
+ tracker->key_name = NULL;
+ tracker->old_value = 0ULL;
+ }
+
+ /* Add/delete trackers can use the qb_map tracking */
+ if ((track_type & ICMAP_TRACK_ADD) ||
+ (track_type & ICMAP_TRACK_DELETE)) {
+ err = qb_map_notify_add(stats_map, tracker->key_name,
+ stats_map_notify_fn,
+ icmap_tt_to_qbtt(track_type),
+ tracker);
+ if (err != 0) {
+ log_printf(LOGSYS_LEVEL_ERROR, "creating stats tracker %s failed. %d\n", tracker->key_name, err);
+ free(tracker->key_name);
+ free(tracker);
+ return (qb_to_cs_error(err));
+ }
+ }
+
+ qb_list_add (&tracker->list, &stats_tracker_list_head);
+
+ *icmap_track = (icmap_track_t)tracker;
+ return CS_OK;
+}
+
+cs_error_t stats_map_track_delete(icmap_track_t icmap_track)
+{
+ struct cs_stats_tracker *tracker = (struct cs_stats_tracker *)icmap_track;
+ int err;
+
+ if ((tracker->events & ICMAP_TRACK_ADD) ||
+ (tracker->events & ICMAP_TRACK_DELETE)) {
+ err = qb_map_notify_del_2(stats_map,
+ tracker->key_name, stats_map_notify_fn,
+ icmap_tt_to_qbtt(tracker->events), tracker);
+ if (err) {
+ log_printf(LOGSYS_LEVEL_ERROR, "deleting tracker %s failed. %d\n", tracker->key_name, err);
+ }
+ }
+
+ qb_list_del(&tracker->list);
+ free(tracker->key_name);
+ free(tracker);
+
+ return CS_OK;
+}
+
+void *stats_map_track_get_user_data(icmap_track_t icmap_track)
+{
+ struct cs_stats_tracker *tracker = (struct cs_stats_tracker *)icmap_track;
+
+ return tracker->user_data;
+}
+
+/* Called from totemknet to add/remove keys from our map */
+void stats_knet_add_member(knet_node_id_t nodeid, uint8_t link_no)
+{
+ int i;
+ char param[ICMAP_KEYNAME_MAXLEN];
+
+ for (i = 0; i<NUM_KNET_STATS; i++) {
+ sprintf(param, "stats.knet.node%d.link%d.%s", nodeid, link_no, cs_knet_stats[i].name);
+ stats_add_entry(param, &cs_knet_stats[i]);
+ }
+}
+void stats_knet_del_member(knet_node_id_t nodeid, uint8_t link_no)
+{
+ int i;
+ char param[ICMAP_KEYNAME_MAXLEN];
+
+ for (i = 0; i<NUM_KNET_STATS; i++) {
+ sprintf(param, "stats.knet.node%d.link%d.%s", nodeid, link_no, cs_knet_stats[i].name);
+ stats_rm_entry(param);
+ }
+}
+
+/* This is separated out from stats_map_init() because we don't know whether
+ knet is in use until much later in the startup */
+void stats_knet_add_handle(void)
+{
+ int i;
+ char param[ICMAP_KEYNAME_MAXLEN];
+
+ for (i = 0; i<NUM_KNET_HANDLE_STATS; i++) {
+ sprintf(param, "stats.knet.handle.%s", cs_knet_handle_stats[i].name);
+ stats_add_entry(param, &cs_knet_handle_stats[i]);
+ }
+}
+
+/* Called from ipc_glue to add/remove keys from our map */
+void stats_ipcs_add_connection(int service_id, uint32_t pid, void *ptr)
+{
+ int i;
+ char param[ICMAP_KEYNAME_MAXLEN];
+
+ for (i = 0; i<NUM_IPCSC_STATS; i++) {
+ sprintf(param, "stats.ipcs.service%d.%d.%p.%s", service_id, pid, ptr, cs_ipcs_conn_stats[i].name);
+ stats_add_entry(param, &cs_ipcs_conn_stats[i]);
+ }
+}
+void stats_ipcs_del_connection(int service_id, uint32_t pid, void *ptr)
+{
+ int i;
+ char param[ICMAP_KEYNAME_MAXLEN];
+
+ for (i = 0; i<NUM_IPCSC_STATS; i++) {
+ sprintf(param, "stats.ipcs.service%d.%d.%p.%s", service_id, pid, ptr, cs_ipcs_conn_stats[i].name);
+ stats_rm_entry(param);
+ }
+}
diff --git a/exec/stats.h b/exec/stats.h
new file mode 100644
index 0000000..eac9e7c
--- /dev/null
+++ b/exec/stats.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2017 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Authors: Christine Caulfield (ccaulfie@redhat.com)
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of the MontaVista Software, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+cs_error_t stats_map_init(const struct corosync_api_v1 *api);
+
+cs_error_t stats_map_get(const char *key_name,
+ void *value,
+ size_t *value_len,
+ icmap_value_types_t *type);
+
+cs_error_t stats_map_set(const char *key_name,
+ const void *value,
+ size_t value_len,
+ icmap_value_types_t type);
+
+cs_error_t stats_map_adjust_int(const char *key_name, int32_t step);
+
+cs_error_t stats_map_delete(const char *key_name);
+
+int stats_map_is_key_ro(const char *key_name);
+
+icmap_iter_t stats_map_iter_init(const char *prefix);
+const char *stats_map_iter_next(icmap_iter_t iter, size_t *value_len, icmap_value_types_t *type);
+void stats_map_iter_finalize(icmap_iter_t iter);
+
+cs_error_t stats_map_track_add(const char *key_name,
+ int32_t track_type,
+ icmap_notify_fn_t notify_fn,
+ void *user_data,
+ icmap_track_t *icmap_track);
+
+cs_error_t stats_map_track_delete(icmap_track_t icmap_track);
+void *stats_map_track_get_user_data(icmap_track_t icmap_track);
+
+void stats_trigger_trackers(void);
+
+
+void stats_ipcs_add_connection(int service_id, uint32_t pid, void *ptr);
+void stats_ipcs_del_connection(int service_id, uint32_t pid, void *ptr);
+cs_error_t cs_ipcs_get_conn_stats(int service_id, uint32_t pid, void *conn_ptr, struct ipcs_conn_stats *ipcs_stats);
+
+void stats_add_schedmiss_event(uint64_t, float delay);
diff --git a/exec/sync.c b/exec/sync.c
new file mode 100644
index 0000000..962f341
--- /dev/null
+++ b/exec/sync.c
@@ -0,0 +1,549 @@
+/*
+ * Copyright (c) 2009-2012 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Author: Steven Dake (sdake@redhat.com)
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of the MontaVista Software, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <config.h>
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.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 <time.h>
+#include <arpa/inet.h>
+
+#include <corosync/corotypes.h>
+#include <corosync/swab.h>
+#include <corosync/totem/totempg.h>
+#include <corosync/totem/totem.h>
+#include <corosync/logsys.h>
+#include <qb/qbipc_common.h>
+#include "schedwrk.h"
+#include "quorum.h"
+#include "sync.h"
+#include "main.h"
+
+LOGSYS_DECLARE_SUBSYS ("SYNC");
+
+#define MESSAGE_REQ_SYNC_BARRIER 0
+#define MESSAGE_REQ_SYNC_SERVICE_BUILD 1
+
+enum sync_process_state {
+ PROCESS,
+ ACTIVATE
+};
+
+enum sync_state {
+ SYNC_SERVICELIST_BUILD,
+ SYNC_PROCESS,
+ SYNC_BARRIER
+};
+
+struct service_entry {
+ int service_id;
+ void (*sync_init) (
+ const unsigned int *trans_list,
+ size_t trans_list_entries,
+ const unsigned int *member_list,
+ size_t member_list_entries,
+ const struct memb_ring_id *ring_id);
+ void (*sync_abort) (void);
+ int (*sync_process) (void);
+ void (*sync_activate) (void);
+ enum sync_process_state state;
+ char name[128];
+};
+
+struct processor_entry {
+ int nodeid;
+ int received;
+};
+
+struct req_exec_service_build_message {
+ struct qb_ipc_request_header header __attribute__((aligned(8)));
+ struct memb_ring_id ring_id __attribute__((aligned(8)));
+ int service_list_entries __attribute__((aligned(8)));
+ int service_list[128] __attribute__((aligned(8)));
+};
+
+struct req_exec_barrier_message {
+ struct qb_ipc_request_header header __attribute__((aligned(8)));
+ struct memb_ring_id ring_id __attribute__((aligned(8)));
+};
+
+static enum sync_state my_state = SYNC_BARRIER;
+
+static struct memb_ring_id my_ring_id;
+
+static int my_processing_idx = 0;
+
+static hdb_handle_t my_schedwrk_handle;
+
+static struct processor_entry my_processor_list[PROCESSOR_COUNT_MAX];
+
+static unsigned int my_member_list[PROCESSOR_COUNT_MAX];
+
+static unsigned int my_trans_list[PROCESSOR_COUNT_MAX];
+
+static size_t my_member_list_entries = 0;
+
+static size_t my_trans_list_entries = 0;
+
+static int my_processor_list_entries = 0;
+
+static struct service_entry my_service_list[SERVICES_COUNT_MAX];
+
+static int my_service_list_entries = 0;
+
+static void (*sync_synchronization_completed) (void);
+
+static void sync_deliver_fn (
+ unsigned int nodeid,
+ const void *msg,
+ unsigned int msg_len,
+ int endian_conversion_required);
+
+static int schedwrk_processor (const void *context);
+
+static void sync_process_enter (void);
+
+static void sync_process_call_init (void);
+
+static struct totempg_group sync_group = {
+ .group = "sync",
+ .group_len = 4
+};
+
+static void *sync_group_handle;
+
+int (*my_sync_callbacks_retrieve) (
+ int service_id,
+ struct sync_callbacks *callbacks);
+
+int sync_init (
+ int (*sync_callbacks_retrieve) (
+ int service_id,
+ struct sync_callbacks *callbacks),
+ void (*synchronization_completed) (void))
+{
+ unsigned int res;
+
+ res = totempg_groups_initialize (
+ &sync_group_handle,
+ sync_deliver_fn,
+ NULL);
+ if (res == -1) {
+ log_printf (LOGSYS_LEVEL_ERROR,
+ "Couldn't initialize groups interface.");
+ return (-1);
+ }
+
+ res = totempg_groups_join (
+ sync_group_handle,
+ &sync_group,
+ 1);
+ if (res == -1) {
+ log_printf (LOGSYS_LEVEL_ERROR, "Couldn't join group.");
+ return (-1);
+ }
+
+ sync_synchronization_completed = synchronization_completed;
+ my_sync_callbacks_retrieve = sync_callbacks_retrieve;
+
+ return (0);
+}
+
+static void sync_barrier_handler (unsigned int nodeid, const void *msg)
+{
+ const struct req_exec_barrier_message *req_exec_barrier_message = msg;
+ int i;
+ int barrier_reached = 1;
+
+ if (memcmp (&my_ring_id, &req_exec_barrier_message->ring_id,
+ sizeof (struct memb_ring_id)) != 0) {
+
+ log_printf (LOGSYS_LEVEL_DEBUG, "barrier for old ring - discarding");
+ return;
+ }
+ for (i = 0; i < my_processor_list_entries; i++) {
+ if (my_processor_list[i].nodeid == nodeid) {
+ my_processor_list[i].received = 1;
+ }
+ }
+ for (i = 0; i < my_processor_list_entries; i++) {
+ if (my_processor_list[i].received == 0) {
+ barrier_reached = 0;
+ }
+ }
+ if (barrier_reached) {
+ log_printf (LOGSYS_LEVEL_DEBUG, "Committing synchronization for %s",
+ my_service_list[my_processing_idx].name);
+ my_service_list[my_processing_idx].state = ACTIVATE;
+
+ if (my_sync_callbacks_retrieve(my_service_list[my_processing_idx].service_id, NULL) != -1) {
+ my_service_list[my_processing_idx].sync_activate ();
+ }
+
+ my_processing_idx += 1;
+ if (my_service_list_entries == my_processing_idx) {
+ sync_synchronization_completed ();
+ } else {
+ sync_process_enter ();
+ }
+ }
+}
+
+static void dummy_sync_abort (void)
+{
+}
+
+static int dummy_sync_process (void)
+{
+ return (0);
+}
+
+static void dummy_sync_activate (void)
+{
+}
+
+static int service_entry_compare (const void *a, const void *b)
+{
+ const struct service_entry *service_entry_a = a;
+ const struct service_entry *service_entry_b = b;
+
+ return (service_entry_a->service_id > service_entry_b->service_id);
+}
+
+static void sync_service_build_handler (unsigned int nodeid, const void *msg)
+{
+ const struct req_exec_service_build_message *req_exec_service_build_message = msg;
+ int i, j;
+ int barrier_reached = 1;
+ int found;
+ int qsort_trigger = 0;
+
+ if (memcmp (&my_ring_id, &req_exec_service_build_message->ring_id,
+ sizeof (struct memb_ring_id)) != 0) {
+ log_printf (LOGSYS_LEVEL_DEBUG, "service build for old ring - discarding");
+ return;
+ }
+ for (i = 0; i < req_exec_service_build_message->service_list_entries; i++) {
+
+ found = 0;
+ for (j = 0; j < my_service_list_entries; j++) {
+ if (req_exec_service_build_message->service_list[i] ==
+ my_service_list[j].service_id) {
+ found = 1;
+ break;
+ }
+ }
+ if (found == 0) {
+ my_service_list[my_service_list_entries].state = PROCESS;
+ my_service_list[my_service_list_entries].service_id =
+ req_exec_service_build_message->service_list[i];
+ sprintf (my_service_list[my_service_list_entries].name,
+ "Unknown External Service (id = %d)\n",
+ req_exec_service_build_message->service_list[i]);
+ my_service_list[my_service_list_entries].sync_init =
+ NULL;
+ my_service_list[my_service_list_entries].sync_abort =
+ dummy_sync_abort;
+ my_service_list[my_service_list_entries].sync_process =
+ dummy_sync_process;
+ my_service_list[my_service_list_entries].sync_activate =
+ dummy_sync_activate;
+ my_service_list_entries += 1;
+
+ qsort_trigger = 1;
+ }
+ }
+ if (qsort_trigger) {
+ qsort (my_service_list, my_service_list_entries,
+ sizeof (struct service_entry), service_entry_compare);
+ }
+ for (i = 0; i < my_processor_list_entries; i++) {
+ if (my_processor_list[i].nodeid == nodeid) {
+ my_processor_list[i].received = 1;
+ }
+ }
+ for (i = 0; i < my_processor_list_entries; i++) {
+ if (my_processor_list[i].received == 0) {
+ barrier_reached = 0;
+ }
+ }
+ if (barrier_reached) {
+ log_printf (LOGSYS_LEVEL_DEBUG, "enter sync process");
+ sync_process_enter ();
+ }
+}
+
+static void sync_deliver_fn (
+ unsigned int nodeid,
+ const void *msg,
+ unsigned int msg_len,
+ int endian_conversion_required)
+{
+ struct qb_ipc_request_header *header = (struct qb_ipc_request_header *)msg;
+
+ switch (header->id) {
+ case MESSAGE_REQ_SYNC_BARRIER:
+ sync_barrier_handler (nodeid, msg);
+ break;
+ case MESSAGE_REQ_SYNC_SERVICE_BUILD:
+ sync_service_build_handler (nodeid, msg);
+ break;
+ }
+}
+
+static void barrier_message_transmit (void)
+{
+ struct iovec iovec;
+ struct req_exec_barrier_message req_exec_barrier_message;
+
+ memset(&req_exec_barrier_message, 0, sizeof(req_exec_barrier_message));
+
+ req_exec_barrier_message.header.size = sizeof (struct req_exec_barrier_message);
+ req_exec_barrier_message.header.id = MESSAGE_REQ_SYNC_BARRIER;
+
+ memcpy (&req_exec_barrier_message.ring_id, &my_ring_id,
+ sizeof (struct memb_ring_id));
+
+ iovec.iov_base = (char *)&req_exec_barrier_message;
+ iovec.iov_len = sizeof (req_exec_barrier_message);
+
+ (void)totempg_groups_mcast_joined (sync_group_handle,
+ &iovec, 1, TOTEMPG_AGREED);
+}
+
+static void service_build_message_transmit (struct req_exec_service_build_message *service_build_message)
+{
+ struct iovec iovec;
+
+ service_build_message->header.size = sizeof (struct req_exec_service_build_message);
+ service_build_message->header.id = MESSAGE_REQ_SYNC_SERVICE_BUILD;
+
+ memcpy (&service_build_message->ring_id, &my_ring_id,
+ sizeof (struct memb_ring_id));
+
+ iovec.iov_base = (void *)service_build_message;
+ iovec.iov_len = sizeof (struct req_exec_service_build_message);
+
+ (void)totempg_groups_mcast_joined (sync_group_handle,
+ &iovec, 1, TOTEMPG_AGREED);
+}
+
+static void sync_barrier_enter (void)
+{
+ my_state = SYNC_BARRIER;
+ barrier_message_transmit ();
+}
+
+static void sync_process_call_init (void)
+{
+ unsigned int old_trans_list[PROCESSOR_COUNT_MAX];
+ size_t old_trans_list_entries = 0;
+ int o, m;
+ int i;
+
+ memcpy (old_trans_list, my_trans_list, my_trans_list_entries *
+ sizeof (unsigned int));
+ old_trans_list_entries = my_trans_list_entries;
+
+ my_trans_list_entries = 0;
+ for (o = 0; o < old_trans_list_entries; o++) {
+ for (m = 0; m < my_member_list_entries; m++) {
+ if (old_trans_list[o] == my_member_list[m]) {
+ my_trans_list[my_trans_list_entries] = my_member_list[m];
+ my_trans_list_entries++;
+ break;
+ }
+ }
+ }
+
+ for (i = 0; i < my_service_list_entries; i++) {
+ if (my_sync_callbacks_retrieve(my_service_list[i].service_id, NULL) != -1) {
+ my_service_list[i].sync_init (my_trans_list,
+ my_trans_list_entries, my_member_list,
+ my_member_list_entries,
+ &my_ring_id);
+ }
+ }
+}
+
+static void sync_process_enter (void)
+{
+ int i;
+
+ my_state = SYNC_PROCESS;
+
+ /*
+ * No sync services
+ */
+ if (my_service_list_entries == 0) {
+ my_state = SYNC_SERVICELIST_BUILD;
+ sync_synchronization_completed ();
+ return;
+ }
+ for (i = 0; i < my_processor_list_entries; i++) {
+ my_processor_list[i].received = 0;
+ }
+
+ schedwrk_create (&my_schedwrk_handle,
+ schedwrk_processor,
+ NULL);
+}
+
+static void sync_servicelist_build_enter (
+ const unsigned int *member_list,
+ size_t member_list_entries,
+ const struct memb_ring_id *ring_id)
+{
+ struct req_exec_service_build_message service_build;
+ int i;
+ int res;
+ struct sync_callbacks sync_callbacks;
+
+ memset(&service_build, 0, sizeof(service_build));
+
+ my_state = SYNC_SERVICELIST_BUILD;
+ for (i = 0; i < member_list_entries; i++) {
+ my_processor_list[i].nodeid = member_list[i];
+ my_processor_list[i].received = 0;
+ }
+ my_processor_list_entries = member_list_entries;
+
+ memcpy (my_member_list, member_list,
+ member_list_entries * sizeof (unsigned int));
+ my_member_list_entries = member_list_entries;
+
+ my_processing_idx = 0;
+
+ memset(my_service_list, 0, sizeof (struct service_entry) * SERVICES_COUNT_MAX);
+ my_service_list_entries = 0;
+
+ for (i = 0; i < SERVICES_COUNT_MAX; i++) {
+ res = my_sync_callbacks_retrieve (i, &sync_callbacks);
+ if (res == -1) {
+ continue;
+ }
+ if (sync_callbacks.sync_init == NULL) {
+ continue;
+ }
+ my_service_list[my_service_list_entries].state = PROCESS;
+ my_service_list[my_service_list_entries].service_id = i;
+
+ assert(strlen(sync_callbacks.name) < sizeof(my_service_list[my_service_list_entries].name));
+
+ strcpy (my_service_list[my_service_list_entries].name,
+ sync_callbacks.name);
+ my_service_list[my_service_list_entries].sync_init = sync_callbacks.sync_init;
+ my_service_list[my_service_list_entries].sync_process = sync_callbacks.sync_process;
+ my_service_list[my_service_list_entries].sync_abort = sync_callbacks.sync_abort;
+ my_service_list[my_service_list_entries].sync_activate = sync_callbacks.sync_activate;
+ my_service_list_entries += 1;
+ }
+
+ for (i = 0; i < my_service_list_entries; i++) {
+ service_build.service_list[i] =
+ my_service_list[i].service_id;
+ }
+ service_build.service_list_entries = my_service_list_entries;
+
+ service_build_message_transmit (&service_build);
+
+ log_printf (LOGSYS_LEVEL_DEBUG, "call init for locally known services");
+ sync_process_call_init ();
+}
+
+static int schedwrk_processor (const void *context)
+{
+ int res = 0;
+
+ if (my_service_list[my_processing_idx].state == PROCESS) {
+ if (my_sync_callbacks_retrieve(my_service_list[my_processing_idx].service_id, NULL) != -1) {
+ res = my_service_list[my_processing_idx].sync_process ();
+ } else {
+ res = 0;
+ }
+ if (res == 0) {
+ sync_barrier_enter();
+ } else {
+ return (-1);
+ }
+ }
+ return (0);
+}
+
+void sync_start (
+ const unsigned int *member_list,
+ size_t member_list_entries,
+ const struct memb_ring_id *ring_id)
+{
+ ENTER();
+ memcpy (&my_ring_id, ring_id, sizeof (struct memb_ring_id));
+
+ sync_servicelist_build_enter (member_list, member_list_entries,
+ ring_id);
+}
+
+void sync_save_transitional (
+ const unsigned int *member_list,
+ size_t member_list_entries,
+ const struct memb_ring_id *ring_id)
+{
+ ENTER();
+ memcpy (my_trans_list, member_list, member_list_entries *
+ sizeof (unsigned int));
+ my_trans_list_entries = member_list_entries;
+}
+
+void sync_abort (void)
+{
+ ENTER();
+ if (my_state == SYNC_PROCESS) {
+ schedwrk_destroy (my_schedwrk_handle);
+ if (my_sync_callbacks_retrieve(my_service_list[my_processing_idx].service_id, NULL) != -1) {
+ my_service_list[my_processing_idx].sync_abort ();
+ }
+ }
+
+ /* this will cause any "old" barrier messages from causing
+ * problems.
+ */
+ memset (&my_ring_id, 0, sizeof (struct memb_ring_id));
+}
diff --git a/exec/sync.h b/exec/sync.h
new file mode 100644
index 0000000..ee2f076
--- /dev/null
+++ b/exec/sync.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2009-2010 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Author: Steven Dake (sdake@redhat.com)
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of the MontaVista Software, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SYNC_H_DEFINED
+#define SYNC_H_DEFINED
+
+struct sync_callbacks {
+ void (*sync_init) (
+ const unsigned int *trans_list,
+ size_t trans_list_entries,
+ const unsigned int *member_list,
+ size_t member_list_entries,
+ const struct memb_ring_id *ring_id);
+ int (*sync_process) (void);
+ void (*sync_activate) (void);
+ void (*sync_abort) (void);
+ const char *name;
+};
+
+extern int sync_init (
+ int (*sync_callbacks_retrieve) (
+ int service_id,
+ struct sync_callbacks *callbacks),
+ void (*synchronization_completed) (void));
+
+extern void sync_start (
+ const unsigned int *member_list,
+ size_t member_list_entries,
+ const struct memb_ring_id *ring_id);
+
+extern void sync_save_transitional (
+ const unsigned int *member_list,
+ size_t member_list_entries,
+ const struct memb_ring_id *ring_id);
+
+extern void sync_abort (void);
+
+extern void sync_memb_list_determine (const struct memb_ring_id *ring_id);
+
+extern void sync_memb_list_abort (void);
+
+#endif /* SYNC_H_DEFINED */
diff --git a/exec/timer.c b/exec/timer.c
new file mode 100644
index 0000000..27383bd
--- /dev/null
+++ b/exec/timer.c
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2002-2006 MontaVista Software, Inc.
+ * Copyright (c) 2006-2010 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Author: Steven Dake (sdake@redhat.com)
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of the MontaVista Software, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include "timer.h"
+#include "main.h"
+#include <qb/qbdefs.h>
+#include <qb/qbutil.h>
+
+int corosync_timer_add_absolute (
+ unsigned long long nanosec_from_epoch,
+ void *data,
+ void (*timer_fn) (void *data),
+ corosync_timer_handle_t *handle)
+{
+ uint64_t expire_time = nanosec_from_epoch - qb_util_nano_current_get();
+ return qb_loop_timer_add(cs_poll_handle_get(),
+ QB_LOOP_MED,
+ expire_time,
+ data,
+ timer_fn,
+ handle);
+}
+
+int corosync_timer_add_duration (
+ unsigned long long nanosec_duration,
+ void *data,
+ void (*timer_fn) (void *data),
+ corosync_timer_handle_t *handle)
+{
+ return qb_loop_timer_add(cs_poll_handle_get(),
+ QB_LOOP_MED,
+ nanosec_duration,
+ data,
+ timer_fn,
+ handle);
+}
+
+void corosync_timer_delete (
+ corosync_timer_handle_t th)
+{
+ qb_loop_timer_del(cs_poll_handle_get(), th);
+}
+
+unsigned long long corosync_timer_expire_time_get (
+ corosync_timer_handle_t th)
+{
+ uint64_t expire;
+
+ if (th == 0) {
+ return (0);
+ }
+
+ expire = qb_loop_timer_expire_time_get(cs_poll_handle_get(), th);
+
+ return (expire);
+}
+
+unsigned long long cs_timer_time_get (void)
+{
+ return qb_util_nano_from_epoch_get();
+}
+
diff --git a/exec/timer.h b/exec/timer.h
new file mode 100644
index 0000000..9d23868
--- /dev/null
+++ b/exec/timer.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2006-2011 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Author: Steven Dake (sdake@redhat.com)
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of the MontaVista Software, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef TIMER_H_DEFINED
+#define TIMER_H_DEFINED
+
+#include <stdint.h>
+#include <time.h>
+#include <qb/qbloop.h>
+
+#ifndef TIMER_HANDLE_T
+typedef qb_loop_timer_handle corosync_timer_handle_t;
+#define TIMER_HANDLE_T 1
+#endif
+
+extern int corosync_timer_add_duration (
+ unsigned long long nanosec_duration,
+ void *data,
+ void (*timer_fn) (void *data),
+ corosync_timer_handle_t *handle);
+
+extern int corosync_timer_add_absolute (
+ unsigned long long nanoseconds_from_epoch,
+ void *data,
+ void (*timer_fn) (void *data),
+ corosync_timer_handle_t *handle);
+
+extern void corosync_timer_delete (corosync_timer_handle_t handle);
+
+extern unsigned long long corosync_timer_expire_time_get (corosync_timer_handle_t handle);
+
+extern unsigned long long cs_timer_time_get (void);
+
+#endif /* TIMER_H_DEFINED */
diff --git a/exec/totemconfig.c b/exec/totemconfig.c
new file mode 100644
index 0000000..a6394a2
--- /dev/null
+++ b/exec/totemconfig.c
@@ -0,0 +1,2454 @@
+/*
+ * Copyright (c) 2002-2005 MontaVista Software, Inc.
+ * Copyright (c) 2006-2022 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Author: Steven Dake (sdake@redhat.com)
+ * Jan Friesse (jfriesse@redhat.com)
+ * Chrissie Caulfield (ccaulfie@redhat.com)
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of the MontaVista Software, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <unistd.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <ifaddrs.h>
+#include <netdb.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <sys/param.h>
+#include <sys/utsname.h>
+
+#include <corosync/swab.h>
+#include <qb/qblist.h>
+#include <qb/qbdefs.h>
+#include <libknet.h>
+#include <corosync/totem/totem.h>
+#include <corosync/config.h>
+#include <corosync/logsys.h>
+#include <corosync/icmap.h>
+
+#include "util.h"
+#include "totemconfig.h"
+
+#define TOKEN_RETRANSMITS_BEFORE_LOSS_CONST 4
+#define TOKEN_TIMEOUT 3000
+#define TOKEN_WARNING 75
+#define TOKEN_COEFFICIENT 650
+#define JOIN_TIMEOUT 50
+#define MERGE_TIMEOUT 200
+#define DOWNCHECK_TIMEOUT 1000
+#define FAIL_TO_RECV_CONST 2500
+#define SEQNO_UNCHANGED_CONST 30
+#define MINIMUM_TIMEOUT (int)(1000/HZ)*3
+#define MINIMUM_TIMEOUT_HOLD (int)(MINIMUM_TIMEOUT * 0.8 - (1000/HZ))
+#define MAX_NETWORK_DELAY 50
+#define WINDOW_SIZE 50
+#define MAX_MESSAGES 17
+#define MISS_COUNT_CONST 5
+#define BLOCK_UNLISTED_IPS 1
+#define CANCEL_TOKEN_HOLD_ON_RETRANSMIT 0
+/* This constant is not used for knet */
+#define UDP_NETMTU 1500
+
+/* Currently all but PONG_COUNT match the defaults in libknet.h */
+#define KNET_PING_INTERVAL 1000
+#define KNET_PING_TIMEOUT 2000
+#define KNET_PING_PRECISION 2048
+#define KNET_PONG_COUNT 2
+#define KNET_PMTUD_INTERVAL 30
+#define KNET_MTU 0
+#define KNET_DEFAULT_TRANSPORT KNET_TRANSPORT_UDP
+
+#define DEFAULT_PORT 5405
+
+static char error_string_response[768];
+
+static void add_totem_config_notification(struct totem_config *totem_config);
+
+static void *totem_get_param_by_name(struct totem_config *totem_config, const char *param_name)
+{
+ if (strcmp(param_name, "totem.token") == 0)
+ return &totem_config->token_timeout;
+ if (strcmp(param_name, "totem.token_warning") == 0)
+ return &totem_config->token_warning;
+ if (strcmp(param_name, "totem.token_retransmit") == 0)
+ return &totem_config->token_retransmit_timeout;
+ if (strcmp(param_name, "totem.hold") == 0)
+ return &totem_config->token_hold_timeout;
+ if (strcmp(param_name, "totem.token_retransmits_before_loss_const") == 0)
+ return &totem_config->token_retransmits_before_loss_const;
+ if (strcmp(param_name, "totem.join") == 0)
+ return &totem_config->join_timeout;
+ if (strcmp(param_name, "totem.send_join") == 0)
+ return &totem_config->send_join_timeout;
+ if (strcmp(param_name, "totem.consensus") == 0)
+ return &totem_config->consensus_timeout;
+ if (strcmp(param_name, "totem.merge") == 0)
+ return &totem_config->merge_timeout;
+ if (strcmp(param_name, "totem.downcheck") == 0)
+ return &totem_config->downcheck_timeout;
+ if (strcmp(param_name, "totem.fail_recv_const") == 0)
+ return &totem_config->fail_to_recv_const;
+ if (strcmp(param_name, "totem.seqno_unchanged_const") == 0)
+ return &totem_config->seqno_unchanged_const;
+ if (strcmp(param_name, "totem.heartbeat_failures_allowed") == 0)
+ return &totem_config->heartbeat_failures_allowed;
+ if (strcmp(param_name, "totem.max_network_delay") == 0)
+ return &totem_config->max_network_delay;
+ if (strcmp(param_name, "totem.window_size") == 0)
+ return &totem_config->window_size;
+ if (strcmp(param_name, "totem.max_messages") == 0)
+ return &totem_config->max_messages;
+ if (strcmp(param_name, "totem.miss_count_const") == 0)
+ return &totem_config->miss_count_const;
+ if (strcmp(param_name, "totem.knet_pmtud_interval") == 0)
+ return &totem_config->knet_pmtud_interval;
+ if (strcmp(param_name, "totem.knet_mtu") == 0)
+ return &totem_config->knet_mtu;
+ if (strcmp(param_name, "totem.knet_compression_threshold") == 0)
+ return &totem_config->knet_compression_threshold;
+ if (strcmp(param_name, "totem.knet_compression_level") == 0)
+ return &totem_config->knet_compression_level;
+ if (strcmp(param_name, "totem.knet_compression_model") == 0)
+ return totem_config->knet_compression_model;
+ if (strcmp(param_name, "totem.block_unlisted_ips") == 0)
+ return &totem_config->block_unlisted_ips;
+ if (strcmp(param_name, "totem.cancel_token_hold_on_retransmit") == 0)
+ return &totem_config->cancel_token_hold_on_retransmit;
+
+ return NULL;
+}
+
+/*
+ * Read key_name from icmap. If key is not found or key_name == delete_key or if allow_zero is false
+ * and readed value is zero, default value is used and stored into totem_config.
+ */
+static void totem_volatile_config_set_uint32_value (struct totem_config *totem_config, icmap_map_t map,
+ const char *key_name, const char *deleted_key, unsigned int default_value,
+ int allow_zero_value)
+{
+ char runtime_key_name[ICMAP_KEYNAME_MAXLEN];
+
+ if (icmap_get_uint32_r(map, key_name, totem_get_param_by_name(totem_config, key_name)) != CS_OK ||
+ (deleted_key != NULL && strcmp(deleted_key, key_name) == 0) ||
+ (!allow_zero_value && *(uint32_t *)totem_get_param_by_name(totem_config, key_name) == 0)) {
+ *(uint32_t *)totem_get_param_by_name(totem_config, key_name) = default_value;
+ }
+
+ /*
+ * Store totem_config value to cmap runtime section
+ */
+ if (strlen("runtime.config.") + strlen(key_name) >= ICMAP_KEYNAME_MAXLEN) {
+ /*
+ * This shouldn't happen
+ */
+ return ;
+ }
+
+ strcpy(runtime_key_name, "runtime.config.");
+ strcat(runtime_key_name, key_name);
+
+ icmap_set_uint32_r(map, runtime_key_name, *(uint32_t *)totem_get_param_by_name(totem_config, key_name));
+}
+
+static void totem_volatile_config_set_int32_value (struct totem_config *totem_config, icmap_map_t map,
+ const char *key_name, const char *deleted_key, int default_value,
+ int allow_zero_value)
+{
+ char runtime_key_name[ICMAP_KEYNAME_MAXLEN];
+
+ if (icmap_get_int32_r(map, key_name, totem_get_param_by_name(totem_config, key_name)) != CS_OK ||
+ (deleted_key != NULL && strcmp(deleted_key, key_name) == 0) ||
+ (!allow_zero_value && *(int32_t *)totem_get_param_by_name(totem_config, key_name) == 0)) {
+ *(int32_t *)totem_get_param_by_name(totem_config, key_name) = default_value;
+ }
+
+ /*
+ * Store totem_config value to cmap runtime section
+ */
+ if (strlen("runtime.config.") + strlen(key_name) >= ICMAP_KEYNAME_MAXLEN) {
+ /*
+ * This shouldn't happen
+ */
+ return ;
+ }
+
+ strcpy(runtime_key_name, "runtime.config.");
+ strcat(runtime_key_name, key_name);
+
+ icmap_set_int32_r(map, runtime_key_name, *(int32_t *)totem_get_param_by_name(totem_config, key_name));
+}
+
+static void totem_volatile_config_set_string_value (struct totem_config *totem_config, icmap_map_t map,
+ const char *key_name, const char *deleted_key, const char *default_value)
+{
+ char runtime_key_name[ICMAP_KEYNAME_MAXLEN];
+ int res;
+ char *new_config_value;
+ const void *config_value;
+
+ config_value = totem_get_param_by_name(totem_config, key_name);
+
+ res = icmap_get_string_r(map, key_name, (char **)&new_config_value);
+ if (res != CS_OK ||
+ (deleted_key != NULL && strcmp(deleted_key, key_name) == 0)) {
+
+ /* Slightly pointless use of strncpy but it keeps coverity happy */
+ strncpy((char *)config_value, default_value, CONFIG_STRING_LEN_MAX);
+ } else {
+ strncpy((char *)config_value, new_config_value, CONFIG_STRING_LEN_MAX);
+ }
+ if (res == CS_OK) {
+ free(new_config_value);
+ }
+
+ /*
+ * Store totem_config value to cmap runtime section
+ */
+ if (strlen("runtime.config.") + strlen(key_name) >= ICMAP_KEYNAME_MAXLEN) {
+ /*
+ * This shouldn't happen
+ */
+ return ;
+ }
+
+ strcpy(runtime_key_name, "runtime.config.");
+ strcat(runtime_key_name, key_name);
+
+ (void)icmap_set_string_r(map, runtime_key_name, (char *)config_value);
+}
+
+/*
+ * Read string value stored in key_name from icmap, use it as a boolean (yes/no) type, convert it
+ * to integer value (1/0) and store into totem_config.
+ *
+ * If key is not found or key_name == delete_key default value is used
+ * and stored into totem_config.
+ */
+static void totem_volatile_config_set_boolean_value (struct totem_config *totem_config, icmap_map_t map,
+ const char *key_name, const char *deleted_key, unsigned int default_value)
+{
+ char runtime_key_name[ICMAP_KEYNAME_MAXLEN];
+ char *str;
+ int val;
+
+ str = NULL;
+ val = default_value;
+
+ if ((deleted_key != NULL && strcmp(deleted_key, key_name) == 0) ||
+ (icmap_get_string_r(map, key_name, &str) != CS_OK)) {
+ /*
+ * Do nothing. str is NULL (icmap_get_string ether not called or
+ * not changed str).
+ */
+ } else {
+ if (strcmp(str, "yes") == 0) {
+ val = 1;
+ } else if (strcmp(str, "no") == 0) {
+ val = 0;
+ }
+ free(str);
+ }
+
+ /*
+ * Store totem_config value to cmap runtime section
+ */
+ if (strlen("runtime.config.") + strlen(key_name) >= ICMAP_KEYNAME_MAXLEN) {
+ /*
+ * This shouldn't happen
+ */
+ return ;
+ }
+
+ strcpy(runtime_key_name, "runtime.config.");
+ strcat(runtime_key_name, key_name);
+
+ *(uint32_t *)totem_get_param_by_name(totem_config, key_name) = val;
+
+ icmap_set_uint32_r(map, runtime_key_name, val);
+}
+
+/*
+ * Read and validate config values from cmap and store them into totem_config. If key doesn't exists,
+ * default value is stored. deleted_key is name of key beeing processed by delete operation
+ * from cmap. It is considered as non existing even if it can be read. Can be NULL.
+ */
+void totem_volatile_config_read (struct totem_config *totem_config, icmap_map_t temp_map, const char *deleted_key)
+{
+ uint32_t u32;
+
+ totem_volatile_config_set_uint32_value(totem_config, temp_map, "totem.token_retransmits_before_loss_const", deleted_key,
+ TOKEN_RETRANSMITS_BEFORE_LOSS_CONST, 0);
+
+ totem_volatile_config_set_uint32_value(totem_config, temp_map, "totem.token", deleted_key, TOKEN_TIMEOUT, 0);
+
+ totem_volatile_config_set_uint32_value(totem_config, temp_map, "totem.token_warning", deleted_key, TOKEN_WARNING, 1);
+
+ if (totem_config->interfaces[0].member_count > 2) {
+ u32 = TOKEN_COEFFICIENT;
+ icmap_get_uint32_r(temp_map, "totem.token_coefficient", &u32);
+ totem_config->token_timeout += (totem_config->interfaces[0].member_count - 2) * u32;
+
+ /*
+ * Store totem_config value to cmap runtime section
+ */
+ icmap_set_uint32_r(temp_map, "runtime.config.totem.token", totem_config->token_timeout);
+ }
+
+ totem_volatile_config_set_uint32_value(totem_config, temp_map, "totem.max_network_delay", deleted_key, MAX_NETWORK_DELAY, 0);
+
+ totem_volatile_config_set_uint32_value(totem_config, temp_map, "totem.window_size", deleted_key, WINDOW_SIZE, 0);
+
+ totem_volatile_config_set_uint32_value(totem_config, temp_map, "totem.max_messages", deleted_key, MAX_MESSAGES, 0);
+
+ totem_volatile_config_set_uint32_value(totem_config, temp_map, "totem.miss_count_const", deleted_key, MISS_COUNT_CONST, 0);
+ totem_volatile_config_set_uint32_value(totem_config, temp_map, "totem.knet_pmtud_interval", deleted_key, KNET_PMTUD_INTERVAL, 0);
+ totem_volatile_config_set_uint32_value(totem_config, temp_map, "totem.knet_mtu", deleted_key, KNET_MTU, 0);
+
+ totem_volatile_config_set_uint32_value(totem_config, temp_map, "totem.token_retransmit", deleted_key,
+ (int)(totem_config->token_timeout / (totem_config->token_retransmits_before_loss_const + 0.2)), 0);
+
+ totem_volatile_config_set_uint32_value(totem_config, temp_map, "totem.hold", deleted_key,
+ (int)(totem_config->token_retransmit_timeout * 0.8 - (1000/HZ)), 0);
+
+ totem_volatile_config_set_uint32_value(totem_config, temp_map, "totem.join", deleted_key, JOIN_TIMEOUT, 0);
+
+ totem_volatile_config_set_uint32_value(totem_config, temp_map, "totem.consensus", deleted_key,
+ (int)(float)(1.2 * totem_config->token_timeout), 0);
+
+ totem_volatile_config_set_uint32_value(totem_config, temp_map, "totem.merge", deleted_key, MERGE_TIMEOUT, 0);
+
+ totem_volatile_config_set_uint32_value(totem_config, temp_map, "totem.downcheck", deleted_key, DOWNCHECK_TIMEOUT, 0);
+
+ totem_volatile_config_set_uint32_value(totem_config, temp_map, "totem.fail_recv_const", deleted_key, FAIL_TO_RECV_CONST, 0);
+
+ totem_volatile_config_set_uint32_value(totem_config, temp_map, "totem.seqno_unchanged_const", deleted_key,
+ SEQNO_UNCHANGED_CONST, 0);
+
+ totem_volatile_config_set_uint32_value(totem_config, temp_map, "totem.send_join", deleted_key, 0, 1);
+
+ totem_volatile_config_set_uint32_value(totem_config, temp_map, "totem.heartbeat_failures_allowed", deleted_key, 0, 1);
+
+ totem_volatile_config_set_uint32_value(totem_config, temp_map, "totem.knet_compression_threshold", deleted_key, 0, 1);
+
+ totem_volatile_config_set_int32_value(totem_config, temp_map, "totem.knet_compression_level", deleted_key, 0, 1);
+
+ totem_volatile_config_set_string_value(totem_config, temp_map, "totem.knet_compression_model", deleted_key, "none");
+
+ totem_volatile_config_set_boolean_value(totem_config, temp_map, "totem.block_unlisted_ips", deleted_key,
+ BLOCK_UNLISTED_IPS);
+
+ totem_volatile_config_set_boolean_value(totem_config, temp_map, "totem.cancel_token_hold_on_retransmit",
+ deleted_key, CANCEL_TOKEN_HOLD_ON_RETRANSMIT);
+}
+
+int totem_volatile_config_validate (
+ struct totem_config *totem_config,
+ icmap_map_t temp_map,
+ const char **error_string)
+{
+ /* Static just to keep them off the stack */
+ static char local_error_reason[512];
+ static char addr_str_buf[INET6_ADDRSTRLEN];
+ const char *error_reason = local_error_reason;
+ char name_key[ICMAP_KEYNAME_MAXLEN];
+ char *name_str;
+ int i, j, num_configured, members;
+ uint32_t tmp_config_value;
+
+ if (totem_config->max_network_delay < MINIMUM_TIMEOUT) {
+ snprintf (local_error_reason, sizeof(local_error_reason),
+ "The max_network_delay parameter (%d ms) may not be less than (%d ms).",
+ totem_config->max_network_delay, MINIMUM_TIMEOUT);
+ goto parse_error;
+ }
+
+ if (totem_config->token_timeout < MINIMUM_TIMEOUT) {
+ snprintf (local_error_reason, sizeof(local_error_reason),
+ "The token timeout parameter (%d ms) may not be less than (%d ms).",
+ totem_config->token_timeout, MINIMUM_TIMEOUT);
+ goto parse_error;
+ }
+
+ if (totem_config->token_warning > 100 || totem_config->token_warning < 0) {
+ snprintf (local_error_reason, sizeof(local_error_reason),
+ "The token warning parameter (%d%%) must be between 0 (disabled) and 100.",
+ totem_config->token_warning);
+ goto parse_error;
+ }
+
+ if (totem_config->token_retransmit_timeout < MINIMUM_TIMEOUT) {
+ if (icmap_get_uint32_r(temp_map, "totem.token_retransmit", &tmp_config_value) == CS_OK) {
+ snprintf (local_error_reason, sizeof(local_error_reason),
+ "The token retransmit timeout parameter (%d ms) may not be less than (%d ms).",
+ totem_config->token_retransmit_timeout, MINIMUM_TIMEOUT);
+ goto parse_error;
+ } else {
+ snprintf (local_error_reason, sizeof(local_error_reason),
+ "Not appropriate token or token_retransmits_before_loss_const value set");
+ goto parse_error;
+ }
+ }
+
+ if (totem_config->token_hold_timeout < MINIMUM_TIMEOUT_HOLD) {
+ snprintf (local_error_reason, sizeof(local_error_reason),
+ "The token hold timeout parameter (%d ms) may not be less than (%d ms).",
+ totem_config->token_hold_timeout, MINIMUM_TIMEOUT_HOLD);
+ goto parse_error;
+ }
+
+ if (totem_config->join_timeout < MINIMUM_TIMEOUT) {
+ snprintf (local_error_reason, sizeof(local_error_reason),
+ "The join timeout parameter (%d ms) may not be less than (%d ms).",
+ totem_config->join_timeout, MINIMUM_TIMEOUT);
+ goto parse_error;
+ }
+
+ if (totem_config->consensus_timeout < MINIMUM_TIMEOUT) {
+ snprintf (local_error_reason, sizeof(local_error_reason),
+ "The consensus timeout parameter (%d ms) may not be less than (%d ms).",
+ totem_config->consensus_timeout, MINIMUM_TIMEOUT);
+ goto parse_error;
+ }
+
+ if (totem_config->consensus_timeout < totem_config->join_timeout) {
+ snprintf (local_error_reason, sizeof(local_error_reason),
+ "The consensus timeout parameter (%d ms) may not be less than join timeout (%d ms).",
+ totem_config->consensus_timeout, totem_config->join_timeout);
+ goto parse_error;
+ }
+
+ if (totem_config->merge_timeout < MINIMUM_TIMEOUT) {
+ snprintf (local_error_reason, sizeof(local_error_reason),
+ "The merge timeout parameter (%d ms) may not be less than (%d ms).",
+ totem_config->merge_timeout, MINIMUM_TIMEOUT);
+ goto parse_error;
+ }
+
+ if (totem_config->downcheck_timeout < MINIMUM_TIMEOUT) {
+ snprintf (local_error_reason, sizeof(local_error_reason),
+ "The downcheck timeout parameter (%d ms) may not be less than (%d ms).",
+ totem_config->downcheck_timeout, MINIMUM_TIMEOUT);
+ goto parse_error;
+ }
+
+ /* Check that we have nodelist 'name' if there is more than one link */
+ num_configured = 0;
+ members = -1;
+ for (i = 0; i < INTERFACE_MAX; i++) {
+ if (totem_config->interfaces[i].configured) {
+ if (num_configured == 0) {
+ members = totem_config->interfaces[i].member_count;
+ }
+ num_configured++;
+ }
+ }
+
+ if (num_configured > 1) {
+ /*
+ * This assert is here just to make compiler happy
+ */
+ assert(members != -1);
+ for (i=0; i < members; i++) {
+ snprintf(name_key, sizeof(name_key), "nodelist.node.%d.name", i);
+
+ if (icmap_get_string_r(temp_map, name_key, &name_str) != CS_OK) {
+ snprintf (local_error_reason, sizeof(local_error_reason),
+ "for a multi-link configuration, all nodes must have a 'name' attribute");
+ goto parse_error;
+ }
+
+ free(name_str);
+ }
+
+ for (i=0; i < INTERFACE_MAX; i++) {
+ if (!totem_config->interfaces[i].configured) {
+ continue;
+ }
+ if (totem_config->interfaces[i].member_count != members) {
+ snprintf (local_error_reason, sizeof(local_error_reason),
+ "Not all nodes have the same number of links");
+ goto parse_error;
+ }
+ }
+ }
+
+ /* Verify that all nodes on the same link have the same IP family */
+ for (i=0; i < INTERFACE_MAX; i++) {
+ for (j=1; j<totem_config->interfaces[i].member_count; j++) {
+ if (totem_config->interfaces[i].configured) {
+ if (totem_config->interfaces[i].member_list[j].family !=
+ totem_config->interfaces[i].member_list[0].family) {
+ memcpy(addr_str_buf,
+ totemip_print(&(totem_config->interfaces[i].member_list[j])),
+ sizeof(addr_str_buf));
+
+ snprintf (local_error_reason, sizeof(local_error_reason),
+ "Nodes for link %d have different IP families "
+ "(compared %s with %s)", i,
+ addr_str_buf,
+ totemip_print(&(totem_config->interfaces[i].member_list[0])));
+ goto parse_error;
+ }
+ }
+ }
+ }
+
+ return 0;
+
+parse_error:
+ snprintf (error_string_response, sizeof(error_string_response),
+ "parse error in config: %s\n", error_reason);
+ *error_string = error_string_response;
+ return (-1);
+
+}
+
+static int totem_get_crypto(struct totem_config *totem_config, icmap_map_t map, const char **error_string)
+{
+ char *str;
+ const char *tmp_cipher;
+ const char *tmp_hash;
+ const char *tmp_model;
+ char *crypto_model_str;
+ int res = 0;
+
+ tmp_hash = "none";
+ tmp_cipher = "none";
+ tmp_model = "none";
+
+ crypto_model_str = NULL;
+ if (icmap_get_string_r(map, "totem.crypto_model", &crypto_model_str) == CS_OK) {
+ tmp_model = crypto_model_str;
+ } else {
+ tmp_model = "nss";
+ }
+
+ if (icmap_get_string_r(map, "totem.secauth", &str) == CS_OK) {
+ if (strcmp(str, "on") == 0) {
+ tmp_cipher = "aes256";
+ tmp_hash = "sha256";
+ }
+ free(str);
+ }
+
+ if (icmap_get_string_r(map, "totem.crypto_cipher", &str) == CS_OK) {
+ if (strcmp(str, "none") == 0) {
+ tmp_cipher = "none";
+ }
+ if (strcmp(str, "aes256") == 0) {
+ tmp_cipher = "aes256";
+ }
+ if (strcmp(str, "aes192") == 0) {
+ tmp_cipher = "aes192";
+ }
+ if (strcmp(str, "aes128") == 0) {
+ tmp_cipher = "aes128";
+ }
+ free(str);
+ }
+
+ if (icmap_get_string_r(map, "totem.crypto_hash", &str) == CS_OK) {
+ if (strcmp(str, "none") == 0) {
+ tmp_hash = "none";
+ }
+ if (strcmp(str, "md5") == 0) {
+ tmp_hash = "md5";
+ }
+ if (strcmp(str, "sha1") == 0) {
+ tmp_hash = "sha1";
+ }
+ if (strcmp(str, "sha256") == 0) {
+ tmp_hash = "sha256";
+ }
+ if (strcmp(str, "sha384") == 0) {
+ tmp_hash = "sha384";
+ }
+ if (strcmp(str, "sha512") == 0) {
+ tmp_hash = "sha512";
+ }
+ free(str);
+ }
+
+ if ((strcmp(tmp_cipher, "none") != 0) &&
+ (strcmp(tmp_hash, "none") == 0)) {
+ *error_string = "crypto_cipher requires crypto_hash with value other than none";
+ res = -1;
+
+ goto out_free_crypto_model_str;
+ }
+
+ if (strcmp(tmp_model, "none") == 0) {
+ /*
+ * Shouldn't happen because it is handled by coroparse
+ */
+ *error_string = "invalid crypto_model";
+ res = -1;
+
+ goto out_free_crypto_model_str;
+ }
+
+ if (strcmp(tmp_cipher, totem_config->crypto_cipher_type) ||
+ strcmp(tmp_hash, totem_config->crypto_hash_type) ||
+ strcmp(tmp_model, totem_config->crypto_model)) {
+ totem_config->crypto_changed = 1;
+ }
+
+ strncpy(totem_config->crypto_cipher_type, tmp_cipher, CONFIG_STRING_LEN_MAX - 1);
+ totem_config->crypto_cipher_type[CONFIG_STRING_LEN_MAX - 1] = '\0';
+
+ strncpy(totem_config->crypto_hash_type, tmp_hash, CONFIG_STRING_LEN_MAX - 1);
+ totem_config->crypto_hash_type[CONFIG_STRING_LEN_MAX - 1] = '\0';
+
+ strncpy(totem_config->crypto_model, tmp_model, CONFIG_STRING_LEN_MAX - 1);
+ totem_config->crypto_model[CONFIG_STRING_LEN_MAX - 1] = '\0';
+
+out_free_crypto_model_str:
+ free(crypto_model_str);
+
+ return (res);
+}
+
+static int nodelist_byname(icmap_map_t map, const char *find_name, int strip_domain)
+{
+ icmap_iter_t iter;
+ const char *iter_key;
+ char name_str[ICMAP_KEYNAME_MAXLEN];
+ int res = 0;
+ unsigned int node_pos;
+ char *name;
+ unsigned int namelen;
+
+ iter = icmap_iter_init_r(map, "nodelist.node.");
+ while ((iter_key = icmap_iter_next(iter, NULL, NULL)) != NULL) {
+ res = sscanf(iter_key, "nodelist.node.%u.%s", &node_pos, name_str);
+ if (res != 2) {
+ continue;
+ }
+ /* ring0_addr is allowed as a fallback */
+ if (strcmp(name_str, "name") && strcmp(name_str, "ring0_addr")) {
+ continue;
+ }
+ if (icmap_get_string_r(map, iter_key, &name) != CS_OK) {
+ continue;
+ }
+ namelen = strlen(name);
+
+ if (strip_domain) {
+ char *dot;
+ dot = strchr(name, '.');
+ if (dot) {
+ namelen = dot - name;
+ }
+ }
+ if (strncmp(find_name, name, namelen) == 0 &&
+ strlen(find_name) == namelen) {
+ icmap_iter_finalize(iter);
+ return node_pos;
+ }
+ }
+ icmap_iter_finalize(iter);
+ return -1;
+}
+
+/* Compare two addresses - only address part (sin_addr/sin6_addr) is checked */
+static int ipaddr_equal(const struct sockaddr *addr1, const struct sockaddr *addr2)
+{
+ int addrlen = 0;
+ const void *addr1p, *addr2p;
+
+ if (addr1->sa_family != addr2->sa_family)
+ return 0;
+
+ switch (addr1->sa_family) {
+ case AF_INET:
+ addrlen = sizeof(struct in_addr);
+ addr1p = &((struct sockaddr_in *)addr1)->sin_addr;
+ addr2p = &((struct sockaddr_in *)addr2)->sin_addr;
+ break;
+ case AF_INET6:
+ addrlen = sizeof(struct in6_addr);
+ addr1p = &((struct sockaddr_in6 *)addr1)->sin6_addr;
+ addr2p = &((struct sockaddr_in6 *)addr2)->sin6_addr;
+ break;
+ default:
+ assert(0);
+ }
+
+ return (memcmp(addr1p, addr2p, addrlen) == 0);
+}
+
+
+/* Finds the local node and returns its position in the nodelist.
+ * Uses nodelist.local_node_pos as a cache to save effort
+ */
+static int find_local_node(icmap_map_t map, int use_cache)
+{
+ char nodename2[PATH_MAX];
+ char name_str[ICMAP_KEYNAME_MAXLEN];
+ icmap_iter_t iter;
+ const char *iter_key;
+ unsigned int cached_pos;
+ char *dot = NULL;
+ const char *node;
+ struct ifaddrs *ifa, *ifa_list;
+ struct sockaddr *sa;
+ int found = 0;
+ int node_pos = -1;
+ int res;
+ struct utsname utsname;
+
+ /* Check for cached value first */
+ if (use_cache) {
+ if (icmap_get_uint32("nodelist.local_node_pos", &cached_pos) == CS_OK) {
+ return cached_pos;
+ }
+ }
+
+ res = uname(&utsname);
+ if (res < 0) {
+ return -1;
+ }
+ node = utsname.nodename;
+
+ /* 1. Exact match */
+ node_pos = nodelist_byname(map, node, 0);
+ if (node_pos > -1) {
+ found = 1;
+ goto ret_found;
+ }
+
+ /* 2. Try to match with increasingly more
+ * specific versions of it
+ */
+ strcpy(nodename2, node);
+ dot = strrchr(nodename2, '.');
+ while (dot) {
+ *dot = '\0';
+
+ node_pos = nodelist_byname(map, nodename2, 0);
+ if (node_pos > -1) {
+ found = 1;
+ goto ret_found;
+ }
+ dot = strrchr(nodename2, '.');
+ }
+
+ node_pos = nodelist_byname(map, nodename2, 1);
+ if (node_pos > -1) {
+ found = 1;
+ goto ret_found;
+ }
+
+ /*
+ * The corosync.conf name may not be related to uname at all,
+ * they may match a hostname on some network interface.
+ */
+ if (getifaddrs(&ifa_list))
+ return -1;
+
+ for (ifa = ifa_list; ifa; ifa = ifa->ifa_next) {
+ socklen_t salen = 0;
+
+ /* Restore this */
+ strcpy(nodename2, node);
+ sa = ifa->ifa_addr;
+ if (!sa) {
+ continue;
+ }
+ if (sa->sa_family != AF_INET && sa->sa_family != AF_INET6) {
+ continue;
+ }
+
+ if (sa->sa_family == AF_INET) {
+ salen = sizeof(struct sockaddr_in);
+ }
+ if (sa->sa_family == AF_INET6) {
+ salen = sizeof(struct sockaddr_in6);
+ }
+
+ if (getnameinfo(sa, salen,
+ nodename2, sizeof(nodename2),
+ NULL, 0, 0) == 0) {
+
+ node_pos = nodelist_byname(map, nodename2, 0);
+ if (node_pos > -1) {
+ found = 1;
+ goto out;
+ }
+
+ /* Truncate this name and try again */
+ dot = strchr(nodename2, '.');
+ if (dot) {
+ *dot = '\0';
+
+ node_pos = nodelist_byname(map, nodename2, 0);
+ if (node_pos > -1) {
+ found = 1;
+ goto out;
+ }
+ }
+ }
+
+ /* See if it's the IP address that's in corosync.conf */
+ if (getnameinfo(sa, sizeof(*sa),
+ nodename2, sizeof(nodename2),
+ NULL, 0, NI_NUMERICHOST))
+ continue;
+
+ node_pos = nodelist_byname(map, nodename2, 0);
+ if (node_pos > -1) {
+ found = 1;
+ goto out;
+ }
+ }
+
+ out:
+ if (found) {
+ freeifaddrs(ifa_list);
+ goto ret_found;
+ }
+
+ /*
+ * This section covers the usecase where the nodename specified in cluster.conf
+ * is an alias specified in /etc/hosts. For example:
+ * <ipaddr> hostname alias1 alias2
+ * and <clusternode name="alias2">
+ * the above calls use uname and getnameinfo does not return aliases.
+ * here we take the name specified in cluster.conf, resolve it to an address
+ * and then compare against all known local ip addresses.
+ * if we have a match, we found our nodename. In theory this chunk of code
+ * could replace all the checks above, but let's avoid any possible regressions
+ * and use it as last.
+ */
+
+ iter = icmap_iter_init_r(map, "nodelist.node.");
+ while ((iter_key = icmap_iter_next(iter, NULL, NULL)) != NULL) {
+ char *dbnodename = NULL;
+ struct addrinfo hints;
+ struct addrinfo *result = NULL, *rp = NULL;
+
+ res = sscanf(iter_key, "nodelist.node.%u.%s", &node_pos, name_str);
+ if (res != 2) {
+ continue;
+ }
+ /* 'ring0_addr' is allowed as a fallback, but 'name' will be found first
+ * because the names are in alpha order.
+ */
+ if (strcmp(name_str, "name") && strcmp(name_str, "ring0_addr")) {
+ continue;
+ }
+ if (icmap_get_string_r(map, iter_key, &dbnodename) != CS_OK) {
+ continue;
+ }
+
+ memset(&hints, 0, sizeof(struct addrinfo));
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_DGRAM;
+ hints.ai_flags = 0;
+ hints.ai_protocol = IPPROTO_UDP;
+
+ if (getaddrinfo(dbnodename, NULL, &hints, &result)) {
+ continue;
+ }
+
+ for (rp = result; rp != NULL; rp = rp->ai_next) {
+ for (ifa = ifa_list; ifa; ifa = ifa->ifa_next) {
+ if (ifa->ifa_addr &&
+ ipaddr_equal(rp->ai_addr, ifa->ifa_addr)) {
+ freeaddrinfo(result);
+ found = 1;
+ goto out2;
+ }
+ }
+ }
+
+ freeaddrinfo(result);
+ }
+out2:
+ icmap_iter_finalize(iter);
+ freeifaddrs(ifa_list);
+
+ret_found:
+ if (found) {
+ res = icmap_set_uint32_r(map, "nodelist.local_node_pos", node_pos);
+ }
+
+ return node_pos;
+}
+
+static enum totem_ip_version_enum totem_config_get_ip_version(struct totem_config *totem_config)
+{
+ enum totem_ip_version_enum res;
+ char *str;
+
+ res = TOTEM_IP_VERSION_6_4;
+
+ if (totem_config->transport_number == TOTEM_TRANSPORT_UDP) {
+ res = TOTEM_IP_VERSION_4;
+ }
+
+ if (icmap_get_string("totem.ip_version", &str) == CS_OK) {
+ if (strcmp(str, "ipv4") == 0) {
+ res = TOTEM_IP_VERSION_4;
+ }
+ if (strcmp(str, "ipv6") == 0) {
+ res = TOTEM_IP_VERSION_6;
+ }
+ if (strcmp(str, "ipv6-4") == 0) {
+ res = TOTEM_IP_VERSION_6_4;
+ }
+ if (strcmp(str, "ipv4-6") == 0) {
+ res = TOTEM_IP_VERSION_4_6;
+ }
+ free(str);
+ }
+
+ return (res);
+}
+
+static uint16_t generate_cluster_id (const char *cluster_name)
+{
+ int i;
+ int value = 0;
+
+ for (i = 0; i < strlen(cluster_name); i++) {
+ value <<= 1;
+ value += cluster_name[i];
+ }
+
+ return (value & 0xFFFF);
+}
+
+static int get_cluster_mcast_addr (
+ const char *cluster_name,
+ unsigned int linknumber,
+ enum totem_ip_version_enum ip_version,
+ struct totem_ip_address *res)
+{
+ uint16_t clusterid;
+ char addr[INET6_ADDRSTRLEN + 1];
+ int err;
+
+ if (cluster_name == NULL) {
+ return (-1);
+ }
+
+ clusterid = generate_cluster_id(cluster_name) + linknumber;
+ memset (res, 0, sizeof(*res));
+
+ switch (ip_version) {
+ case TOTEM_IP_VERSION_4:
+ case TOTEM_IP_VERSION_4_6:
+ snprintf(addr, sizeof(addr), "239.192.%d.%d", clusterid >> 8, clusterid % 0xFF);
+ break;
+ case TOTEM_IP_VERSION_6:
+ case TOTEM_IP_VERSION_6_4:
+ snprintf(addr, sizeof(addr), "ff15::%x", clusterid);
+ break;
+ default:
+ /*
+ * Unknown family
+ */
+ return (-1);
+ }
+
+ err = totemip_parse (res, addr, ip_version);
+
+ return (err);
+}
+
+static unsigned int generate_nodeid(
+ struct totem_config *totem_config,
+ char *addr)
+{
+ unsigned int nodeid;
+ struct totem_ip_address totemip;
+
+ /* AF_INET hard-coded here because auto-generated nodeids
+ are only for IPv4 */
+ if (totemip_parse(&totemip, addr, TOTEM_IP_VERSION_4) != 0)
+ return -1;
+
+ memcpy (&nodeid, &totemip.addr, sizeof (unsigned int));
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+ nodeid = swab32 (nodeid);
+#endif
+
+ if (totem_config->clear_node_high_bit) {
+ nodeid &= 0x7FFFFFFF;
+ }
+ return nodeid;
+}
+
+static int check_for_duplicate_nodeids(
+ struct totem_config *totem_config,
+ const char **error_string)
+{
+ icmap_iter_t iter;
+ icmap_iter_t subiter;
+ const char *iter_key;
+ int res = 0;
+ int retval = 0;
+ char tmp_key[ICMAP_KEYNAME_MAXLEN];
+ char *ring0_addr=NULL;
+ char *ring0_addr1=NULL;
+ unsigned int node_pos;
+ unsigned int node_pos1;
+ unsigned int last_node_pos = -1;
+ unsigned int nodeid;
+ unsigned int nodeid1;
+ int autogenerated;
+
+ iter = icmap_iter_init("nodelist.node.");
+ while ((iter_key = icmap_iter_next(iter, NULL, NULL)) != NULL) {
+ res = sscanf(iter_key, "nodelist.node.%u.%s", &node_pos, tmp_key);
+ if (res != 2) {
+ continue;
+ }
+
+ /*
+ * This relies on the fact the icmap keys are always returned in order
+ * so all of the keys for a node will be grouped together. We're basically
+ * just running the code below once for each node.
+ */
+ if (last_node_pos == node_pos) {
+ continue;
+ }
+ last_node_pos = node_pos;
+
+ snprintf(tmp_key, ICMAP_KEYNAME_MAXLEN, "nodelist.node.%u.nodeid", node_pos);
+ autogenerated = 0;
+
+ /* Generated nodeids are only allowed for UDP/UDPU so ring0_addr is valid here */
+ if (icmap_get_uint32(tmp_key, &nodeid) != CS_OK) {
+
+ snprintf(tmp_key, ICMAP_KEYNAME_MAXLEN, "nodelist.node.%u.ring0_addr", node_pos);
+ if (icmap_get_string(tmp_key, &ring0_addr) != CS_OK) {
+ continue;
+ }
+
+ /* Generate nodeid so we can check that auto-generated nodeids don't clash either */
+ nodeid = generate_nodeid(totem_config, ring0_addr);
+ if (nodeid == -1) {
+ continue;
+ }
+ autogenerated = 1;
+ }
+
+ node_pos1 = 0;
+ subiter = icmap_iter_init("nodelist.node.");
+ while (((iter_key = icmap_iter_next(subiter, NULL, NULL)) != NULL) && (node_pos1 < node_pos)) {
+ res = sscanf(iter_key, "nodelist.node.%u.%s", &node_pos1, tmp_key);
+ if ((res != 2) || (node_pos1 >= node_pos)) {
+ continue;
+ }
+
+ if (strcmp(tmp_key, "nodeid") != 0) {
+ continue;
+ }
+
+ snprintf(tmp_key, ICMAP_KEYNAME_MAXLEN, "nodelist.node.%u.nodeid", node_pos1);
+ if (icmap_get_uint32(tmp_key, &nodeid1) != CS_OK) {
+
+ snprintf(tmp_key, ICMAP_KEYNAME_MAXLEN, "nodelist.node.%u.ring0_addr", node_pos1);
+ if (icmap_get_string(tmp_key, &ring0_addr1) != CS_OK) {
+ continue;
+ }
+ nodeid1 = generate_nodeid(totem_config, ring0_addr1);
+ if (nodeid1 == -1) {
+ continue;
+ }
+ }
+
+ if (nodeid == nodeid1) {
+ retval = -1;
+ snprintf (error_string_response, sizeof(error_string_response),
+ "Nodeid %u%s%s%s appears twice in corosync.conf", nodeid,
+ autogenerated?"(autogenerated from ":"",
+ autogenerated?ring0_addr:"",
+ autogenerated?")":"");
+ *error_string = error_string_response;
+ break;
+ }
+ }
+ icmap_iter_finalize(subiter);
+ }
+ icmap_iter_finalize(iter);
+ return retval;
+}
+
+
+/*
+ * This needs to be done last of all. It would be nice to do it when reading the
+ * interface params, but the totem params need to have them to be read first. We
+ * need both, so this is a way round that circular dependancy.
+ */
+static void calc_knet_ping_timers(struct totem_config *totem_config)
+{
+ char runtime_key_name[ICMAP_KEYNAME_MAXLEN];
+ int interface;
+
+ for (interface = 0; interface < INTERFACE_MAX; interface++) {
+
+ if (totem_config->interfaces[interface].configured) {
+ if (!totem_config->interfaces[interface].knet_pong_count) {
+ totem_config->interfaces[interface].knet_pong_count = KNET_PONG_COUNT;
+ }
+ if (!totem_config->interfaces[interface].knet_ping_timeout) {
+ totem_config->interfaces[interface].knet_ping_timeout =
+ totem_config->token_timeout / totem_config->interfaces[interface].knet_pong_count;
+ }
+ snprintf(runtime_key_name, sizeof(runtime_key_name),
+ "runtime.config.totem.interface.%d.knet_ping_timeout", interface);
+ icmap_set_uint32(runtime_key_name, totem_config->interfaces[interface].knet_ping_timeout);
+
+ if (!totem_config->interfaces[interface].knet_ping_interval) {
+ totem_config->interfaces[interface].knet_ping_interval =
+ totem_config->token_timeout / (totem_config->interfaces[interface].knet_pong_count * 2);
+ }
+ snprintf(runtime_key_name, sizeof(runtime_key_name),
+ "runtime.config.totem.interface.%d.knet_ping_interval", interface);
+ icmap_set_uint32(runtime_key_name, totem_config->interfaces[interface].knet_ping_interval);
+ }
+ }
+}
+
+/*
+ * Compute difference between two set of totem interface arrays and commit it.
+ * set1 and set2
+ * are changed so for same ring, ip existing in both set1 and set2 are cleared
+ * (set to 0), and ips which are only in set1 or set2 remains untouched.
+ * totempg_node_add/remove is called.
+ */
+static int compute_and_set_totempg_interfaces(struct totem_interface *set1,
+ struct totem_interface *set2)
+{
+ int ring_no, set1_pos, set2_pos;
+ struct totem_ip_address empty_ip_address;
+ int res = 0;
+
+ memset(&empty_ip_address, 0, sizeof(empty_ip_address));
+
+ for (ring_no = 0; ring_no < INTERFACE_MAX; ring_no++) {
+ if (!set1[ring_no].configured && !set2[ring_no].configured) {
+ continue;
+ }
+
+ for (set1_pos = 0; set1_pos < set1[ring_no].member_count; set1_pos++) {
+ for (set2_pos = 0; set2_pos < set2[ring_no].member_count; set2_pos++) {
+ /*
+ * For current ring_no remove all set1 items existing
+ * in set2
+ */
+ if (memcmp(&set1[ring_no].member_list[set1_pos],
+ &set2[ring_no].member_list[set2_pos],
+ sizeof(struct totem_ip_address)) == 0) {
+ memset(&set1[ring_no].member_list[set1_pos], 0,
+ sizeof(struct totem_ip_address));
+ memset(&set2[ring_no].member_list[set2_pos], 0,
+ sizeof(struct totem_ip_address));
+ }
+ }
+ }
+ }
+
+ for (ring_no = 0; ring_no < INTERFACE_MAX; ring_no++) {
+ for (set1_pos = 0; set1_pos < set1[ring_no].member_count; set1_pos++) {
+ /*
+ * All items which remain in set1 and don't exist in set2 any more
+ * have to be removed.
+ */
+ if (memcmp(&set1[ring_no].member_list[set1_pos], &empty_ip_address, sizeof(empty_ip_address)) != 0) {
+ log_printf(LOGSYS_LEVEL_DEBUG,
+ "removing dynamic member %s for ring %u",
+ totemip_print(&set1[ring_no].member_list[set1_pos]),
+ ring_no);
+
+ totempg_member_remove(&set1[ring_no].member_list[set1_pos], ring_no);
+ }
+ }
+ if (!set2[ring_no].configured) {
+ continue;
+ }
+ for (set2_pos = 0; set2_pos < set2[ring_no].member_count; set2_pos++) {
+ /*
+ * All items which remain in set2 and don't exist in set1 are new nodes
+ * and have to be added.
+ */
+ if (memcmp(&set2[ring_no].member_list[set2_pos], &empty_ip_address, sizeof(empty_ip_address)) != 0) {
+ log_printf(LOGSYS_LEVEL_DEBUG,
+ "adding dynamic member %s for ring %u",
+ totemip_print(&set2[ring_no].member_list[set2_pos]),
+ ring_no);
+
+ if (totempg_member_add(&set2[ring_no].member_list[set2_pos], ring_no)) {
+ res = -1;
+ }
+ }
+ }
+ }
+ return res;
+}
+
+/*
+ * Configure parameters for links
+ */
+static void configure_link_params(struct totem_config *totem_config, icmap_map_t map)
+{
+ int i;
+ char tmp_key[ICMAP_KEYNAME_MAXLEN];
+ char *addr_string;
+ int err;
+ int local_node_pos = find_local_node(map, 0);
+
+ for (i = 0; i<INTERFACE_MAX; i++) {
+ if (!totem_config->interfaces[i].configured) {
+ continue;
+ }
+
+ log_printf(LOGSYS_LEVEL_DEBUG, "Configuring link %d params\n", i);
+
+ snprintf(tmp_key, ICMAP_KEYNAME_MAXLEN, "nodelist.node.%u.ring%u_addr", local_node_pos, i);
+ if (icmap_get_string_r(map, tmp_key, &addr_string) != CS_OK) {
+ continue;
+ }
+
+ err = totemip_parse(&totem_config->interfaces[i].local_ip, addr_string, totem_config->ip_version);
+ if (err != 0) {
+ continue;
+ }
+ totem_config->interfaces[i].local_ip.nodeid = totem_config->node_id;
+
+ /* In case this is a new link, fill in the defaults if there was no interface{} section for it */
+ if (!totem_config->interfaces[i].knet_link_priority)
+ totem_config->interfaces[i].knet_link_priority = 1;
+
+ /* knet_ping_interval & knet_ping_timeout are set later once we know all the other params */
+ if (!totem_config->interfaces[i].knet_ping_precision)
+ totem_config->interfaces[i].knet_ping_precision = KNET_PING_PRECISION;
+ if (!totem_config->interfaces[i].knet_pong_count)
+ totem_config->interfaces[i].knet_pong_count = KNET_PONG_COUNT;
+ if (!totem_config->interfaces[i].knet_transport)
+ totem_config->interfaces[i].knet_transport = KNET_TRANSPORT_UDP;
+ if (!totem_config->interfaces[i].ip_port)
+ totem_config->interfaces[i].ip_port = DEFAULT_PORT + i;
+ }
+}
+
+
+static void configure_totem_links(struct totem_config *totem_config, icmap_map_t map)
+{
+ int i;
+
+ for (i = 0; i<INTERFACE_MAX; i++) {
+ if (!totem_config->interfaces[i].configured) {
+ continue;
+ }
+
+ log_printf(LOGSYS_LEVEL_INFO, "Configuring link %d\n", i);
+
+ totempg_iface_set(&totem_config->interfaces[i].local_ip, totem_config->interfaces[i].ip_port, i);
+ }
+}
+
+/* Check for differences in config that can't be done on-the-fly and print an error */
+static int check_things_have_not_changed(struct totem_config *totem_config, const char **error_string)
+{
+ int i,j,k;
+ const char *ip_str;
+ char addr_buf[INET6_ADDRSTRLEN];
+ int changed = 0;
+
+ for (i = 0; i<INTERFACE_MAX; i++) {
+ if (totem_config->interfaces[i].configured &&
+ totem_config->orig_interfaces[i].configured) {
+ if (totem_config->interfaces[i].knet_transport !=
+ totem_config->orig_interfaces[i].knet_transport) {
+ log_printf(LOGSYS_LEVEL_ERROR,
+ "New config has different knet transport for link %d. Internal value was NOT changed.\n", i);
+ changed = 1;
+ }
+
+ /* Check each nodeid in the new configuration and make sure its IP address on this link has not changed */
+ for (j=0; j < totem_config->interfaces[i].member_count; j++) {
+ for (k=0; k < totem_config->orig_interfaces[i].member_count; k++) {
+
+ if (totem_config->interfaces[i].member_list[j].nodeid ==
+ totem_config->orig_interfaces[i].member_list[k].nodeid) {
+
+ /* Found our nodeid - check the IP address */
+ if (memcmp(&totem_config->interfaces[i].member_list[j],
+ &totem_config->orig_interfaces[i].member_list[k],
+ sizeof(struct totem_ip_address))) {
+
+ ip_str = totemip_print(&totem_config->orig_interfaces[i].member_list[k]);
+
+ /* if ip_str is NULL then the old address was invalid and is allowed to change */
+ if (ip_str) {
+ strncpy(addr_buf, ip_str, sizeof(addr_buf));
+ addr_buf[sizeof(addr_buf) - 1] = '\0';
+ log_printf(LOGSYS_LEVEL_ERROR,
+ "new config has different address for link %d (addr changed from %s to %s). Internal value was NOT changed.\n",
+ i, addr_buf, totemip_print(&totem_config->interfaces[i].member_list[j]));
+ changed = 1;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (changed) {
+ snprintf (error_string_response, sizeof(error_string_response),
+ "To reconfigure an interface it must be deleted and recreated. A working interface needs to be available to corosync at all times");
+ *error_string = error_string_response;
+ return -1;
+ }
+ return 0;
+}
+
+
+static int put_nodelist_members_to_config(struct totem_config *totem_config, icmap_map_t map,
+ int reload, const char **error_string)
+{
+ icmap_iter_t iter, iter2;
+ const char *iter_key, *iter_key2;
+ int res = 0;
+ unsigned int node_pos;
+ char tmp_key[ICMAP_KEYNAME_MAXLEN];
+ char tmp_key2[ICMAP_KEYNAME_MAXLEN];
+ char *node_addr_str;
+ int member_count;
+ unsigned int linknumber = 0;
+ int i, j;
+ int last_node_pos = -1;
+
+ /* Clear out nodelist so we can put the new one in if needed */
+ for (i = 0; i < INTERFACE_MAX; i++) {
+ for (j = 0; j < PROCESSOR_COUNT_MAX; j++) {
+ memset(&totem_config->interfaces[i].member_list[j], 0, sizeof(struct totem_ip_address));
+ }
+ totem_config->interfaces[i].member_count = 0;
+ }
+
+ iter = icmap_iter_init_r(map, "nodelist.node.");
+ while ((iter_key = icmap_iter_next(iter, NULL, NULL)) != NULL) {
+ res = sscanf(iter_key, "nodelist.node.%u.%s", &node_pos, tmp_key);
+ if (res != 2) {
+ continue;
+ }
+ /* If it's the same as the last node_pos then skip it */
+ if (node_pos == last_node_pos) {
+ continue;
+ }
+ last_node_pos = node_pos;
+
+ snprintf(tmp_key, ICMAP_KEYNAME_MAXLEN, "nodelist.node.%u.", node_pos);
+ iter2 = icmap_iter_init_r(map, tmp_key);
+ while ((iter_key2 = icmap_iter_next(iter2, NULL, NULL)) != NULL) {
+ unsigned int nodeid;
+ char *str;
+
+ snprintf(tmp_key, ICMAP_KEYNAME_MAXLEN, "nodelist.node.%u.nodeid", node_pos);
+ if (icmap_get_uint32_r(map, tmp_key, &nodeid) != CS_OK) {
+ nodeid = 0;
+ }
+
+ res = sscanf(iter_key2, "nodelist.node.%u.ring%u%s", &node_pos, &linknumber, tmp_key2);
+ if (res != 3 || strcmp(tmp_key2, "_addr") != 0) {
+ continue;
+ }
+ if (linknumber >= INTERFACE_MAX) {
+ snprintf (error_string_response, sizeof(error_string_response),
+ "parse error in config: interface ring number %u is bigger than allowed maximum %u\n",
+ linknumber, INTERFACE_MAX - 1);
+ *error_string = error_string_response;
+
+ icmap_iter_finalize(iter2);
+ icmap_iter_finalize(iter);
+ return (-1);
+ }
+
+ if (icmap_get_string_r(map, iter_key2, &node_addr_str) != CS_OK) {
+ continue;
+ }
+
+ /* Generate nodeids if they are not provided and transport is UDP/U */
+ if (!nodeid &&
+ (totem_config->transport_number == TOTEM_TRANSPORT_UDP ||
+ totem_config->transport_number == TOTEM_TRANSPORT_UDPU)) {
+ snprintf(tmp_key, ICMAP_KEYNAME_MAXLEN, "nodelist.node.%u.ring0_addr", node_pos);
+ if (icmap_get_string_r(map, tmp_key, &str) == CS_OK) {
+ nodeid = generate_nodeid(totem_config, str);
+ if (nodeid == -1) {
+ sprintf(error_string_response,
+ "An IPV6 network requires that a node ID be specified "
+ "for address '%s'.", node_addr_str);
+ *error_string = error_string_response;
+ free(str);
+
+ return (-1);
+ }
+
+ log_printf(LOGSYS_LEVEL_DEBUG,
+ "Generated nodeid = " CS_PRI_NODE_ID " for %s", nodeid, str);
+
+ free(str);
+ /*
+ * Put nodeid back to nodelist to make cfgtool work
+ */
+ snprintf(tmp_key, ICMAP_KEYNAME_MAXLEN, "nodelist.node.%u.nodeid", node_pos);
+ /*
+ * Not critical
+ */
+ (void)icmap_set_uint32_r(map, tmp_key, nodeid);
+ }
+ }
+
+ if (!nodeid && totem_config->transport_number == TOTEM_TRANSPORT_KNET) {
+ sprintf(error_string_response,
+ "Knet requires an explicit nodeid to be specified "
+ "for address '%s'.", node_addr_str);
+ *error_string = error_string_response;
+
+ return (-1);
+ }
+
+ if (totem_config->transport_number == TOTEM_TRANSPORT_KNET && nodeid >= KNET_MAX_HOST) {
+ sprintf(error_string_response,
+ "Knet requires nodeid to be less than %u "
+ "for address '%s'.", KNET_MAX_HOST, node_addr_str);
+ *error_string = error_string_response;
+
+ return (-1);
+ }
+
+ member_count = totem_config->interfaces[linknumber].member_count;
+ res = totemip_parse(&totem_config->interfaces[linknumber].member_list[member_count],
+ node_addr_str, totem_config->ip_version);
+ if (res == 0) {
+ totem_config->interfaces[linknumber].member_list[member_count].nodeid = nodeid;
+ totem_config->interfaces[linknumber].member_count++;
+ totem_config->interfaces[linknumber].configured = 1;
+ } else {
+ sprintf(error_string_response, "failed to parse node address '%s'\n", node_addr_str);
+ *error_string = error_string_response;
+
+ memset(&totem_config->interfaces[linknumber].member_list[member_count], 0,
+ sizeof(struct totem_ip_address));
+
+ free(node_addr_str);
+ icmap_iter_finalize(iter2);
+ icmap_iter_finalize(iter);
+ return -1;
+ }
+
+ free(node_addr_str);
+ }
+
+ icmap_iter_finalize(iter2);
+ }
+
+ icmap_iter_finalize(iter);
+
+ configure_link_params(totem_config, map);
+ if (reload) {
+ log_printf(LOGSYS_LEVEL_DEBUG, "About to reconfigure links from nodelist.\n");
+
+ if (check_things_have_not_changed(totem_config, error_string) == -1) {
+ return -1;
+ }
+ }
+ return 0;
+}
+
+static void config_convert_nodelist_to_interface(icmap_map_t map, struct totem_config *totem_config)
+{
+ int res = 0;
+ int node_pos;
+ char tmp_key[ICMAP_KEYNAME_MAXLEN];
+ char tmp_key2[ICMAP_KEYNAME_MAXLEN];
+ char *node_addr_str;
+ unsigned int linknumber = 0;
+ icmap_iter_t iter;
+ const char *iter_key;
+
+ node_pos = find_local_node(map, 1);
+ if (node_pos > -1) {
+ /*
+ * We found node, so create interface section
+ */
+ snprintf(tmp_key, ICMAP_KEYNAME_MAXLEN, "nodelist.node.%u.", node_pos);
+ iter = icmap_iter_init_r(map, tmp_key);
+ while ((iter_key = icmap_iter_next(iter, NULL, NULL)) != NULL) {
+ res = sscanf(iter_key, "nodelist.node.%u.ring%u%s", &node_pos, &linknumber, tmp_key2);
+ if (res != 3 || strcmp(tmp_key2, "_addr") != 0) {
+ continue ;
+ }
+
+ if (icmap_get_string_r(map, iter_key, &node_addr_str) != CS_OK) {
+ continue;
+ }
+
+ snprintf(tmp_key2, ICMAP_KEYNAME_MAXLEN, "totem.interface.%u.bindnetaddr", linknumber);
+ icmap_set_string_r(map, tmp_key2, node_addr_str);
+ free(node_addr_str);
+ }
+ icmap_iter_finalize(iter);
+ }
+}
+
+static int get_interface_params(struct totem_config *totem_config, icmap_map_t map,
+ const char **error_string, uint64_t *warnings,
+ int reload)
+{
+ int res = 0;
+ unsigned int linknumber = 0;
+ int member_count = 0;
+ int i;
+ icmap_iter_t iter, member_iter;
+ const char *iter_key;
+ const char *member_iter_key;
+ char linknumber_key[ICMAP_KEYNAME_MAXLEN];
+ char tmp_key[ICMAP_KEYNAME_MAXLEN];
+ uint8_t u8;
+ uint32_t u32;
+ char *str;
+ char *cluster_name = NULL;
+ enum totem_ip_version_enum tmp_ip_version = TOTEM_IP_VERSION_4;
+ int ret = 0;
+
+ if (reload) {
+ for (i=0; i<INTERFACE_MAX; i++) {
+ /*
+ * Set back to defaults things that might have been configured and
+ * now have been taken out of corosync.conf. These won't be caught by the
+ * code below which only looks at interface{} sections that actually exist.
+ */
+ totem_config->interfaces[i].configured = 0;
+ totem_config->interfaces[i].knet_ping_timeout = 0;
+ totem_config->interfaces[i].knet_ping_interval = 0;
+ totem_config->interfaces[i].knet_ping_precision = KNET_PING_PRECISION;
+ totem_config->interfaces[i].knet_pong_count = KNET_PONG_COUNT;
+ }
+ }
+ if (icmap_get_string_r(map, "totem.cluster_name", &cluster_name) != CS_OK) {
+ cluster_name = NULL;
+ }
+
+ iter = icmap_iter_init_r(map, "totem.interface.");
+ while ((iter_key = icmap_iter_next(iter, NULL, NULL)) != NULL) {
+ res = sscanf(iter_key, "totem.interface.%[^.].%s", linknumber_key, tmp_key);
+ if (res != 2) {
+ continue;
+ }
+
+ if (strcmp(tmp_key, "bindnetaddr") != 0 && totem_config->transport_number == TOTEM_TRANSPORT_UDP) {
+ continue;
+ }
+
+ member_count = 0;
+ linknumber = atoi(linknumber_key);
+
+ if (linknumber >= INTERFACE_MAX) {
+ snprintf (error_string_response, sizeof(error_string_response),
+ "parse error in config: interface ring number %u is bigger than allowed maximum %u\n",
+ linknumber, INTERFACE_MAX - 1);
+
+ *error_string = error_string_response;
+ ret = -1;
+ goto out;
+ }
+
+ /* These things are only valid for the initial read */
+ if (!reload) {
+ /*
+ * Get the bind net address
+ */
+ snprintf(tmp_key, ICMAP_KEYNAME_MAXLEN, "totem.interface.%u.bindnetaddr", linknumber);
+
+ if (icmap_get_string_r(map, tmp_key, &str) == CS_OK) {
+ res = totemip_parse (&totem_config->interfaces[linknumber].bindnet, str,
+ totem_config->ip_version);
+
+ if (res) {
+ sprintf(error_string_response, "failed to parse bindnet address '%s'\n", str);
+ *error_string = error_string_response;
+ free(str);
+
+ ret = -1;
+ goto out;
+ }
+
+ free(str);
+ }
+
+ /*
+ * Get interface multicast address
+ */
+ snprintf(tmp_key, ICMAP_KEYNAME_MAXLEN, "totem.interface.%u.mcastaddr", linknumber);
+ if (icmap_get_string_r(map, tmp_key, &str) == CS_OK) {
+ res = totemip_parse (&totem_config->interfaces[linknumber].mcast_addr, str,
+ totem_config->ip_version);
+
+ if (res) {
+ sprintf(error_string_response, "failed to parse mcast address '%s'\n", str);
+ *error_string = error_string_response;
+ free(str);
+
+ ret = -1;
+ goto out;
+ }
+
+ free(str);
+ } else if (totem_config->transport_number == TOTEM_TRANSPORT_UDP) {
+ /*
+ * User not specified address -> autogenerate one from cluster_name key
+ * (if available). Return code is intentionally ignored, because
+ * udpu doesn't need mcastaddr and validity of mcastaddr for udp is
+ * checked later anyway.
+ */
+
+ if (totem_config->interfaces[0].bindnet.family == AF_INET) {
+ tmp_ip_version = TOTEM_IP_VERSION_4;
+ } else if (totem_config->interfaces[0].bindnet.family == AF_INET6) {
+ tmp_ip_version = TOTEM_IP_VERSION_6;
+ }
+
+ (void)get_cluster_mcast_addr (cluster_name,
+ linknumber,
+ tmp_ip_version,
+ &totem_config->interfaces[linknumber].mcast_addr);
+ }
+
+ snprintf(tmp_key, ICMAP_KEYNAME_MAXLEN, "totem.interface.%u.broadcast", linknumber);
+ if (icmap_get_string(tmp_key, &str) == CS_OK) {
+ if (strcmp (str, "yes") == 0) {
+ totem_config->broadcast_use = 1;
+ }
+ free(str);
+ }
+ }
+
+ /* These things are only valid for the initial read OR a newly-defined link */
+ if (!reload || (totem_config->interfaces[linknumber].configured == 0)) {
+
+ /*
+ * Get mcast port
+ */
+ snprintf(tmp_key, ICMAP_KEYNAME_MAXLEN, "totem.interface.%u.mcastport", linknumber);
+ if (icmap_get_uint16_r(map, tmp_key, &totem_config->interfaces[linknumber].ip_port) != CS_OK) {
+ if (totem_config->broadcast_use) {
+ totem_config->interfaces[linknumber].ip_port = DEFAULT_PORT + (2 * linknumber);
+ } else {
+ totem_config->interfaces[linknumber].ip_port = DEFAULT_PORT + linknumber;
+ }
+ }
+
+ /*
+ * Get the TTL
+ */
+ totem_config->interfaces[linknumber].ttl = 1;
+
+ snprintf(tmp_key, ICMAP_KEYNAME_MAXLEN, "totem.interface.%u.ttl", linknumber);
+
+ if (icmap_get_uint8_r(map, tmp_key, &u8) == CS_OK) {
+ totem_config->interfaces[linknumber].ttl = u8;
+ }
+
+ totem_config->interfaces[linknumber].knet_transport = KNET_DEFAULT_TRANSPORT;
+ snprintf(tmp_key, ICMAP_KEYNAME_MAXLEN, "totem.interface.%u.knet_transport", linknumber);
+ if (icmap_get_string_r(map, tmp_key, &str) == CS_OK) {
+ if (strcmp(str, "sctp") == 0) {
+ totem_config->interfaces[linknumber].knet_transport = KNET_TRANSPORT_SCTP;
+ }
+ else if (strcmp(str, "udp") == 0) {
+ totem_config->interfaces[linknumber].knet_transport = KNET_TRANSPORT_UDP;
+ }
+ else {
+ *error_string = "Unrecognised knet_transport. expected 'udp' or 'sctp'";
+ ret = -1;
+ goto out;
+ }
+ }
+ }
+ totem_config->interfaces[linknumber].configured = 1;
+
+ /*
+ * Get the knet link params
+ */
+ totem_config->interfaces[linknumber].knet_link_priority = 1;
+ snprintf(tmp_key, ICMAP_KEYNAME_MAXLEN, "totem.interface.%u.knet_link_priority", linknumber);
+
+ if (icmap_get_uint8_r(map, tmp_key, &u8) == CS_OK) {
+ totem_config->interfaces[linknumber].knet_link_priority = u8;
+ }
+
+ totem_config->interfaces[linknumber].knet_ping_interval = 0; /* real default applied later */
+ snprintf(tmp_key, ICMAP_KEYNAME_MAXLEN, "totem.interface.%u.knet_ping_interval", linknumber);
+ if (icmap_get_uint32_r(map, tmp_key, &u32) == CS_OK) {
+ totem_config->interfaces[linknumber].knet_ping_interval = u32;
+ }
+ totem_config->interfaces[linknumber].knet_ping_timeout = 0; /* real default applied later */
+ snprintf(tmp_key, ICMAP_KEYNAME_MAXLEN, "totem.interface.%u.knet_ping_timeout", linknumber);
+ if (icmap_get_uint32_r(map, tmp_key, &u32) == CS_OK) {
+ totem_config->interfaces[linknumber].knet_ping_timeout = u32;
+ }
+ totem_config->interfaces[linknumber].knet_ping_precision = KNET_PING_PRECISION;
+ snprintf(tmp_key, ICMAP_KEYNAME_MAXLEN, "totem.interface.%u.knet_ping_precision", linknumber);
+ if (icmap_get_uint32_r(map, tmp_key, &u32) == CS_OK) {
+ totem_config->interfaces[linknumber].knet_ping_precision = u32;
+ }
+ totem_config->interfaces[linknumber].knet_pong_count = KNET_PONG_COUNT;
+ snprintf(tmp_key, ICMAP_KEYNAME_MAXLEN, "totem.interface.%u.knet_pong_count", linknumber);
+ if (icmap_get_uint32_r(map, tmp_key, &u32) == CS_OK) {
+ totem_config->interfaces[linknumber].knet_pong_count = u32;
+ }
+
+ snprintf(tmp_key, ICMAP_KEYNAME_MAXLEN, "totem.interface.%u.member.", linknumber);
+ member_iter = icmap_iter_init_r(map, tmp_key);
+ while ((member_iter_key = icmap_iter_next(member_iter, NULL, NULL)) != NULL) {
+ if (member_count == 0) {
+ if (icmap_get_string("nodelist.node.0.ring0_addr", &str) == CS_OK) {
+ free(str);
+ *warnings |= TOTEM_CONFIG_WARNING_MEMBERS_IGNORED;
+ break;
+ } else {
+ *warnings |= TOTEM_CONFIG_WARNING_MEMBERS_DEPRECATED;
+ }
+ }
+
+ if (icmap_get_string_r(map, member_iter_key, &str) == CS_OK) {
+ res = totemip_parse (&totem_config->interfaces[linknumber].member_list[member_count++],
+ str, totem_config->ip_version);
+ if (res) {
+ sprintf(error_string_response, "failed to parse node address '%s'\n", str);
+ *error_string = error_string_response;
+
+ icmap_iter_finalize(member_iter);
+ free(str);
+ ret = -1;
+ goto out;
+ }
+
+ free(str);
+ }
+ }
+ icmap_iter_finalize(member_iter);
+
+ totem_config->interfaces[linknumber].member_count = member_count;
+
+ }
+
+out:
+ icmap_iter_finalize(iter);
+ free(cluster_name);
+
+ return (ret);
+}
+
+extern int totem_config_read (
+ struct totem_config *totem_config,
+ const char **error_string,
+ uint64_t *warnings)
+{
+ int res = 0;
+ char *str, *ring0_addr_str;
+ char tmp_key[ICMAP_KEYNAME_MAXLEN];
+ uint16_t u16;
+ int i;
+ int local_node_pos;
+ uint32_t u32;
+
+ *warnings = 0;
+
+ memset (totem_config, 0, sizeof (struct totem_config));
+ totem_config->interfaces = malloc (sizeof (struct totem_interface) * INTERFACE_MAX);
+ if (totem_config->interfaces == 0) {
+ *error_string = "Out of memory trying to allocate ethernet interface storage area";
+ return -1;
+ }
+
+ totem_config->transport_number = TOTEM_TRANSPORT_KNET;
+ if (icmap_get_string("totem.transport", &str) == CS_OK) {
+ if (strcmp (str, "udpu") == 0) {
+ totem_config->transport_number = TOTEM_TRANSPORT_UDPU;
+ } else if (strcmp (str, "udp") == 0) {
+ totem_config->transport_number = TOTEM_TRANSPORT_UDP;
+ } else if (strcmp (str, "knet") == 0) {
+ totem_config->transport_number = TOTEM_TRANSPORT_KNET;
+ } else {
+ *error_string = "Invalid transport type. Should be udpu, udp or knet";
+ free(str);
+ return -1;
+ }
+
+ free(str);
+ }
+
+ memset (totem_config->interfaces, 0,
+ sizeof (struct totem_interface) * INTERFACE_MAX);
+
+ strcpy (totem_config->link_mode, "passive");
+
+ icmap_get_uint32("totem.version", (uint32_t *)&totem_config->version);
+
+ /* initial crypto load */
+ if (totem_get_crypto(totem_config, icmap_get_global_map(), error_string) != 0) {
+ return -1;
+ }
+ if (totem_config_keyread(totem_config, icmap_get_global_map(), error_string) != 0) {
+ return -1;
+ }
+ totem_config->crypto_index = 1;
+ totem_config->crypto_changed = 0;
+
+ if (icmap_get_string("totem.link_mode", &str) == CS_OK) {
+ if (strlen(str) >= TOTEM_LINK_MODE_BYTES) {
+ *error_string = "totem.link_mode is too long";
+ free(str);
+
+ return -1;
+ }
+ strcpy (totem_config->link_mode, str);
+ free(str);
+ }
+
+ if (icmap_get_uint32("totem.nodeid", &u32) == CS_OK) {
+ *warnings |= TOTEM_CONFIG_WARNING_TOTEM_NODEID_SET;
+ }
+
+ totem_config->clear_node_high_bit = 0;
+ if (icmap_get_string("totem.clear_node_high_bit", &str) == CS_OK) {
+ if (strcmp (str, "yes") == 0) {
+ totem_config->clear_node_high_bit = 1;
+ }
+ free(str);
+ }
+
+ icmap_get_uint32("totem.threads", &totem_config->threads);
+
+ icmap_get_uint32("totem.netmtu", &totem_config->net_mtu);
+
+ totem_config->ip_version = totem_config_get_ip_version(totem_config);
+
+ if (icmap_get_string("totem.interface.0.bindnetaddr", &str) != CS_OK) {
+ /*
+ * We were not able to find ring 0 bindnet addr. Try to use nodelist informations
+ */
+ config_convert_nodelist_to_interface(icmap_get_global_map(), totem_config);
+ } else {
+ if (icmap_get_string("nodelist.node.0.ring0_addr", &ring0_addr_str) == CS_OK) {
+ /*
+ * Both bindnetaddr and ring0_addr are set.
+ * Log warning information, and use nodelist instead
+ */
+ *warnings |= TOTEM_CONFIG_BINDNETADDR_NODELIST_SET;
+
+ config_convert_nodelist_to_interface(icmap_get_global_map(), totem_config);
+
+ free(ring0_addr_str);
+ }
+
+ free(str);
+ }
+
+ /*
+ * Broadcast option is global but set in interface section,
+ * so reset before processing interfaces.
+ */
+ totem_config->broadcast_use = 0;
+
+ res = get_interface_params(totem_config, icmap_get_global_map(), error_string, warnings, 0);
+ if (res < 0) {
+ return res;
+ }
+
+ /*
+ * Use broadcast is global, so if set, make sure to fill mcast addr correctly
+ * broadcast is only supported for UDP so just do interface 0;
+ */
+ if (totem_config->broadcast_use) {
+ totemip_parse (&totem_config->interfaces[0].mcast_addr,
+ "255.255.255.255", TOTEM_IP_VERSION_4);
+ }
+
+
+ /*
+ * Store automatically generated items back to icmap only for UDP
+ */
+ if (totem_config->transport_number == TOTEM_TRANSPORT_UDP) {
+ for (i = 0; i < INTERFACE_MAX; i++) {
+ if (!totem_config->interfaces[i].configured) {
+ continue;
+ }
+ snprintf(tmp_key, ICMAP_KEYNAME_MAXLEN, "totem.interface.%u.mcastaddr", i);
+ if (icmap_get_string(tmp_key, &str) == CS_OK) {
+ free(str);
+ } else {
+ str = (char *)totemip_print(&totem_config->interfaces[i].mcast_addr);
+ icmap_set_string(tmp_key, str);
+ }
+
+ snprintf(tmp_key, ICMAP_KEYNAME_MAXLEN, "totem.interface.%u.mcastport", i);
+ if (icmap_get_uint16(tmp_key, &u16) != CS_OK) {
+ icmap_set_uint16(tmp_key, totem_config->interfaces[i].ip_port);
+ }
+ }
+ }
+
+ /*
+ * Check existence of nodelist
+ */
+ if ((icmap_get_string("nodelist.node.0.name", &str) == CS_OK) ||
+ (icmap_get_string("nodelist.node.0.ring0_addr", &str) == CS_OK)) {
+ free(str);
+ /*
+ * find local node
+ */
+ local_node_pos = find_local_node(icmap_get_global_map(), 1);
+ if (local_node_pos != -1) {
+
+ assert(totem_config->node_id == 0);
+
+ snprintf(tmp_key, ICMAP_KEYNAME_MAXLEN, "nodelist.node.%u.nodeid", local_node_pos);
+ (void)icmap_get_uint32(tmp_key, &totem_config->node_id);
+
+
+ if ((totem_config->transport_number == TOTEM_TRANSPORT_KNET) && (!totem_config->node_id)) {
+ *error_string = "Knet requires an explicit nodeid for the local node";
+ return -1;
+ }
+
+ if ((totem_config->transport_number == TOTEM_TRANSPORT_UDP ||
+ totem_config->transport_number == TOTEM_TRANSPORT_UDPU) && (!totem_config->node_id)) {
+
+ snprintf(tmp_key, ICMAP_KEYNAME_MAXLEN, "nodelist.node.%u.ring0_addr", local_node_pos);
+ icmap_get_string(tmp_key, &str);
+
+ totem_config->node_id = generate_nodeid(totem_config, str);
+ if (totem_config->node_id == -1) {
+ *error_string = "An IPV6 network requires that a node ID be specified";
+
+ free(str);
+ return (-1);
+ }
+
+ totem_config->interfaces[0].member_list[local_node_pos].nodeid = totem_config->node_id;
+
+ free(str);
+ }
+
+ /* Users must not change this */
+ icmap_set_ro_access("nodelist.local_node_pos", 0, 1);
+ }
+
+ if (put_nodelist_members_to_config(totem_config, icmap_get_global_map(), 0, error_string)) {
+ return -1;
+ }
+ }
+
+ /*
+ * Get things that might change in the future (and can depend on totem_config->interfaces);
+ */
+ totem_volatile_config_read(totem_config, icmap_get_global_map(), NULL);
+
+ calc_knet_ping_timers(totem_config);
+
+ /* This is now done in the totemknet interface callback */
+ /* configure_totem_links(totem_config, icmap_get_global_map()); */
+
+ add_totem_config_notification(totem_config);
+
+ return 0;
+}
+
+
+int totem_config_validate (
+ struct totem_config *totem_config,
+ const char **error_string)
+{
+ static char local_error_reason[512];
+ char parse_error[512];
+ const char *error_reason = local_error_reason;
+ int i;
+ uint32_t u32;
+ int num_configured = 0;
+ unsigned int interface_max = INTERFACE_MAX;
+
+ for (i = 0; i < INTERFACE_MAX; i++) {
+ if (totem_config->interfaces[i].configured) {
+ num_configured++;
+ }
+ }
+ if (num_configured == 0) {
+ error_reason = "No interfaces defined";
+ goto parse_error;
+ }
+
+ /* Check we found a local node name */
+ if (icmap_get_uint32("nodelist.local_node_pos", &u32) != CS_OK) {
+ error_reason = "No valid name found for local host";
+ goto parse_error;
+ }
+
+ for (i = 0; i < INTERFACE_MAX; i++) {
+ /*
+ * Some error checking of parsed data to make sure its valid
+ */
+
+ struct totem_ip_address null_addr;
+
+ if (!totem_config->interfaces[i].configured) {
+ continue;
+ }
+
+ memset (&null_addr, 0, sizeof (struct totem_ip_address));
+
+ if ((totem_config->transport_number == TOTEM_TRANSPORT_UDP) &&
+ memcmp (&totem_config->interfaces[i].mcast_addr, &null_addr,
+ sizeof (struct totem_ip_address)) == 0) {
+ snprintf (local_error_reason, sizeof(local_error_reason),
+ "No multicast address specified for interface %u", i);
+ goto parse_error;
+ }
+
+ if (totem_config->interfaces[i].ip_port == 0) {
+ snprintf (local_error_reason, sizeof(local_error_reason),
+ "No multicast port specified for interface %u", i);
+ goto parse_error;
+ }
+
+ if (totem_config->interfaces[i].ttl > 255) {
+ snprintf (local_error_reason, sizeof(local_error_reason),
+ "Invalid TTL (should be 0..255) for interface %u", i);
+ goto parse_error;
+ }
+ if (totem_config->transport_number != TOTEM_TRANSPORT_UDP &&
+ totem_config->interfaces[i].ttl != 1) {
+ snprintf (local_error_reason, sizeof(local_error_reason),
+ "Can only set ttl on multicast transport types for interface %u", i);
+ goto parse_error;
+ }
+ if (totem_config->interfaces[i].knet_link_priority > 255) {
+ snprintf (local_error_reason, sizeof(local_error_reason),
+ "Invalid link priority (should be 0..255) for interface %u", i);
+ goto parse_error;
+ }
+ if (totem_config->transport_number != TOTEM_TRANSPORT_KNET &&
+ totem_config->interfaces[i].knet_link_priority != 1) {
+ snprintf (local_error_reason, sizeof(local_error_reason),
+ "Can only set link priority on knet transport type for interface %u", i);
+ goto parse_error;
+ }
+
+ if (totem_config->interfaces[i].mcast_addr.family == AF_INET6 &&
+ totem_config->node_id == 0) {
+ snprintf (local_error_reason, sizeof(local_error_reason),
+ "An IPV6 network requires that a node ID be specified for interface %u", i);
+ goto parse_error;
+ }
+
+ if (totem_config->broadcast_use == 0 && totem_config->transport_number == TOTEM_TRANSPORT_UDP) {
+ if (totem_config->interfaces[i].mcast_addr.family != totem_config->interfaces[i].bindnet.family) {
+ snprintf (local_error_reason, sizeof(local_error_reason),
+ "Multicast address family does not match bind address family for interface %u", i);
+ goto parse_error;
+ }
+
+ if (totemip_is_mcast (&totem_config->interfaces[i].mcast_addr) != 0) {
+ snprintf (local_error_reason, sizeof(local_error_reason),
+ "mcastaddr is not a correct multicast address for interface %u", i);
+ goto parse_error;
+ }
+ }
+ }
+
+ if (totem_config->version != 2) {
+ error_reason = "This totem parser can only parse version 2 configurations.";
+ goto parse_error;
+ }
+
+ if (totem_volatile_config_validate(totem_config, icmap_get_global_map(), error_string) == -1) {
+ return (-1);
+ }
+
+ if (check_for_duplicate_nodeids(totem_config, error_string) == -1) {
+ return (-1);
+ }
+
+ /*
+ * KNET Link values validation
+ */
+ if (strcmp (totem_config->link_mode, "active") &&
+ strcmp (totem_config->link_mode, "rr") &&
+ strcmp (totem_config->link_mode, "passive")) {
+ snprintf (local_error_reason, sizeof(local_error_reason),
+ "The Knet link mode \"%s\" specified is invalid. It must be active, passive or rr.\n", totem_config->link_mode);
+ goto parse_error;
+ }
+
+ /* Only Knet does multiple interfaces */
+ if (totem_config->transport_number != TOTEM_TRANSPORT_KNET) {
+ interface_max = 1;
+ }
+
+ if (interface_max < num_configured) {
+ snprintf (parse_error, sizeof(parse_error),
+ "%d is too many configured interfaces for non-Knet transport.",
+ num_configured);
+ error_reason = parse_error;
+ goto parse_error;
+ }
+
+ /* Only knet allows crypto */
+ if (totem_config->transport_number != TOTEM_TRANSPORT_KNET) {
+ if ((strcmp(totem_config->crypto_cipher_type, "none") != 0) ||
+ (strcmp(totem_config->crypto_hash_type, "none") != 0)) {
+
+ snprintf (parse_error, sizeof(parse_error),
+ "crypto_cipher & crypto_hash are only valid for the Knet transport.");
+ error_reason = parse_error;
+ goto parse_error;
+ }
+ }
+
+ if (totem_config->net_mtu == 0) {
+ if (totem_config->transport_number == TOTEM_TRANSPORT_KNET) {
+ totem_config->net_mtu = KNET_MAX_PACKET_SIZE;
+ }
+ else {
+ totem_config->net_mtu = UDP_NETMTU;
+ }
+ }
+
+ return 0;
+
+parse_error:
+ snprintf (error_string_response, sizeof(error_string_response),
+ "parse error in config: %s\n", error_reason);
+ *error_string = error_string_response;
+ return (-1);
+
+}
+
+static int read_keyfile (
+ const char *key_location,
+ struct totem_config *totem_config,
+ const char **error_string)
+{
+ int fd;
+ int res;
+ int saved_errno;
+ char error_str[100];
+ const char *error_ptr;
+
+ fd = open (key_location, O_RDONLY);
+ if (fd == -1) {
+ error_ptr = qb_strerror_r(errno, error_str, sizeof(error_str));
+ snprintf (error_string_response, sizeof(error_string_response),
+ "Could not open %s: %s\n",
+ key_location, error_ptr);
+ goto parse_error;
+ }
+
+ res = read (fd, totem_config->private_key, TOTEM_PRIVATE_KEY_LEN_MAX);
+ saved_errno = errno;
+ close (fd);
+
+ if (res == -1) {
+ error_ptr = qb_strerror_r (saved_errno, error_str, sizeof(error_str));
+ snprintf (error_string_response, sizeof(error_string_response),
+ "Could not read %s: %s\n",
+ key_location, error_ptr);
+ goto parse_error;
+ }
+
+ if (res < TOTEM_PRIVATE_KEY_LEN_MIN) {
+ snprintf (error_string_response, sizeof(error_string_response),
+ "Could only read %d bits of minimum %u bits from %s.\n",
+ res * 8, TOTEM_PRIVATE_KEY_LEN_MIN * 8, key_location);
+ goto parse_error;
+ }
+
+ totem_config->private_key_len = res;
+
+ return 0;
+
+parse_error:
+ *error_string = error_string_response;
+ return (-1);
+}
+
+int totem_config_keyread (
+ struct totem_config *totem_config,
+ icmap_map_t map,
+ const char **error_string)
+{
+ int got_key = 0;
+ char *key_location = NULL;
+ int res;
+ size_t key_len;
+ char old_key[TOTEM_PRIVATE_KEY_LEN_MAX];
+ size_t old_key_len;
+
+ /* Take a copy so we can see if it has changed */
+ memcpy(old_key, totem_config->private_key, sizeof(totem_config->private_key));
+ old_key_len = totem_config->private_key_len;
+
+ memset (totem_config->private_key, 0, sizeof(totem_config->private_key));
+ totem_config->private_key_len = 0;
+
+ if (strcmp(totem_config->crypto_cipher_type, "none") == 0 &&
+ strcmp(totem_config->crypto_hash_type, "none") == 0) {
+ return (0);
+ }
+
+ /* cmap may store the location of the key file */
+ if (icmap_get_string_r(map, "totem.keyfile", &key_location) == CS_OK) {
+ res = read_keyfile(key_location, totem_config, error_string);
+ free(key_location);
+ if (res) {
+ goto key_error;
+ }
+ got_key = 1;
+ } else { /* Or the key itself may be in the cmap */
+ if (icmap_get_r(map, "totem.key", NULL, &key_len, NULL) == CS_OK) {
+ if (key_len > sizeof(totem_config->private_key)) {
+ sprintf(error_string_response, "key is too long");
+ goto key_error;
+ }
+ if (key_len < TOTEM_PRIVATE_KEY_LEN_MIN) {
+ sprintf(error_string_response, "key is too short");
+ goto key_error;
+ }
+ if (icmap_get_r(map, "totem.key", totem_config->private_key, &key_len, NULL) == CS_OK) {
+ totem_config->private_key_len = key_len;
+ got_key = 1;
+ } else {
+ sprintf(error_string_response, "can't load private key");
+ goto key_error;
+ }
+ }
+ }
+
+ /* In desperation we read the default filename */
+ if (!got_key) {
+ res = read_keyfile(COROSYSCONFDIR "/authkey", totem_config, error_string);
+ if (res)
+ goto key_error;
+ }
+
+ if (old_key_len != totem_config->private_key_len ||
+ memcmp(old_key, totem_config->private_key, sizeof(totem_config->private_key))) {
+ totem_config->crypto_changed = 1;
+ }
+
+ return (0);
+
+key_error:
+ *error_string = error_string_response;
+ return (-1);
+
+}
+
+int totem_reread_crypto_config(struct totem_config *totem_config, icmap_map_t map, const char **error_string)
+{
+ if (totem_get_crypto(totem_config, map, error_string) != 0) {
+ return -1;
+ }
+ if (totem_config_keyread(totem_config, map, error_string) != 0) {
+ return -1;
+ }
+ return 0;
+}
+
+static void debug_dump_totem_config(const struct totem_config *totem_config)
+{
+
+ log_printf(LOGSYS_LEVEL_DEBUG, "Token Timeout (%d ms) retransmit timeout (%d ms)",
+ totem_config->token_timeout, totem_config->token_retransmit_timeout);
+ if (totem_config->token_warning) {
+ uint32_t token_warning_ms = totem_config->token_warning * totem_config->token_timeout / 100;
+ log_printf(LOGSYS_LEVEL_DEBUG, "Token warning every %d ms (%d%% of Token Timeout)",
+ token_warning_ms, totem_config->token_warning);
+ if (token_warning_ms < totem_config->token_retransmit_timeout)
+ log_printf (LOGSYS_LEVEL_DEBUG,
+ "The token warning interval (%d ms) is less than the token retransmit timeout (%d ms) "
+ "which can lead to spurious token warnings. Consider increasing the token_warning parameter.",
+ token_warning_ms, totem_config->token_retransmit_timeout);
+
+ } else
+ log_printf(LOGSYS_LEVEL_DEBUG, "Token warnings disabled");
+ log_printf(LOGSYS_LEVEL_DEBUG, "token hold (%d ms) retransmits before loss (%d retrans)",
+ totem_config->token_hold_timeout, totem_config->token_retransmits_before_loss_const);
+ log_printf(LOGSYS_LEVEL_DEBUG, "join (%d ms) send_join (%d ms) consensus (%d ms) merge (%d ms)",
+ totem_config->join_timeout, totem_config->send_join_timeout, totem_config->consensus_timeout,
+ totem_config->merge_timeout);
+ log_printf(LOGSYS_LEVEL_DEBUG, "downcheck (%d ms) fail to recv const (%d msgs)",
+ totem_config->downcheck_timeout, totem_config->fail_to_recv_const);
+ log_printf(LOGSYS_LEVEL_DEBUG,
+ "seqno unchanged const (%d rotations) Maximum network MTU %d",
+ totem_config->seqno_unchanged_const, totem_config->net_mtu);
+ log_printf(LOGSYS_LEVEL_DEBUG,
+ "window size per rotation (%d messages) maximum messages per rotation (%d messages)",
+ totem_config->window_size, totem_config->max_messages);
+ log_printf(LOGSYS_LEVEL_DEBUG, "missed count const (%d messages)", totem_config->miss_count_const);
+ log_printf(LOGSYS_LEVEL_DEBUG, "heartbeat_failures_allowed (%d)",
+ totem_config->heartbeat_failures_allowed);
+ log_printf(LOGSYS_LEVEL_DEBUG, "max_network_delay (%d ms)", totem_config->max_network_delay);
+}
+
+
+static void totem_change_notify(
+ int32_t event,
+ const char *key_name,
+ struct icmap_notify_value new_val,
+ struct icmap_notify_value old_val,
+ void *user_data)
+{
+ struct totem_config *totem_config = (struct totem_config *)user_data;
+ uint32_t *param;
+ uint8_t reloading;
+ const char *deleted_key = NULL;
+ const char *error_string;
+
+ /*
+ * If a full reload is in progress then don't do anything until it's done and
+ * can reconfigure it all atomically
+ */
+ if (icmap_get_uint8("config.reload_in_progress", &reloading) == CS_OK && reloading)
+ return;
+
+ param = totem_get_param_by_name((struct totem_config *)user_data, key_name);
+ /*
+ * Process change only if changed key is found in totem_config (-> param is not NULL)
+ * or for special key token_coefficient. token_coefficient key is not stored in
+ * totem_config, but it is used for computation of token timeout.
+ */
+ if (!param && strcmp(key_name, "totem.token_coefficient") != 0)
+ return;
+
+ /*
+ * Values other than UINT32 are not supported, or needed (yet)
+ */
+ switch (event) {
+ case ICMAP_TRACK_DELETE:
+ deleted_key = key_name;
+ break;
+ case ICMAP_TRACK_ADD:
+ case ICMAP_TRACK_MODIFY:
+ deleted_key = NULL;
+ break;
+ default:
+ break;
+ }
+
+ totem_volatile_config_read (totem_config, icmap_get_global_map(), deleted_key);
+ log_printf(LOGSYS_LEVEL_DEBUG, "Totem related config key changed. Dumping actual totem config.");
+ debug_dump_totem_config(totem_config);
+ if (totem_volatile_config_validate(totem_config, icmap_get_global_map(), &error_string) == -1) {
+ log_printf (LOGSYS_LEVEL_ERROR, "%s", error_string);
+ /*
+ * TODO: Consider corosync exit and/or load defaults for volatile
+ * values. For now, log error seems to be enough
+ */
+ }
+}
+
+
+int totemconfig_configure_new_params(
+ struct totem_config *totem_config,
+ icmap_map_t map,
+ const char **error_string)
+{
+ uint64_t warnings = 0LL;
+
+ get_interface_params(totem_config, map, error_string, &warnings, 1);
+ if (put_nodelist_members_to_config (totem_config, map, 1, error_string)) {
+ return -1;
+ }
+
+ calc_knet_ping_timers(totem_config);
+
+ log_printf(LOGSYS_LEVEL_DEBUG, "Configuration reloaded. Dumping actual totem config.");
+ debug_dump_totem_config(totem_config);
+
+ /* Reinstate the local_node_pos */
+ (void)find_local_node(map, 0);
+
+ return 0;
+}
+
+int totemconfig_commit_new_params(
+ struct totem_config *totem_config,
+ icmap_map_t map)
+{
+ int res;
+ struct totem_interface *new_interfaces = NULL;
+
+ new_interfaces = malloc (sizeof (struct totem_interface) * INTERFACE_MAX);
+ assert(new_interfaces != NULL);
+ memcpy(new_interfaces, totem_config->interfaces, sizeof (struct totem_interface) * INTERFACE_MAX);
+
+ /* Set link parameters including local_ip */
+ configure_totem_links(totem_config, map);
+
+ /* Add & remove nodes & link properties */
+ res = compute_and_set_totempg_interfaces(totem_config->orig_interfaces, new_interfaces);
+
+ /* Does basic global params (like compression) */
+ totempg_reconfigure();
+
+ free(new_interfaces);
+ return res; /* On a reload this is ignored */
+}
+
+static void add_totem_config_notification(struct totem_config *totem_config)
+{
+ icmap_track_t icmap_track;
+
+ icmap_track_add("totem.",
+ ICMAP_TRACK_ADD | ICMAP_TRACK_DELETE | ICMAP_TRACK_MODIFY | ICMAP_TRACK_PREFIX,
+ totem_change_notify,
+ totem_config,
+ &icmap_track);
+}
diff --git a/exec/totemconfig.h b/exec/totemconfig.h
new file mode 100644
index 0000000..a0b2e10
--- /dev/null
+++ b/exec/totemconfig.h
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2005 MontaVista Software, Inc.
+ * Copyright (c) 2006-2012 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Author: Steven Dake (sdake@redhat.com)
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of the MontaVista Software, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef TOTEMCONFIG_H_DEFINED
+#define TOTEMCONFIG_H_DEFINED
+
+#include <netinet/in.h>
+#include <corosync/corotypes.h>
+#include <qb/qbloop.h>
+#include <corosync/totem/totempg.h>
+
+#include "totemsrp.h"
+
+#define TOTEM_CONFIG_WARNING_MEMBERS_IGNORED (1<<1)
+#define TOTEM_CONFIG_WARNING_MEMBERS_DEPRECATED (1<<2)
+#define TOTEM_CONFIG_WARNING_TOTEM_NODEID_SET (1<<3)
+#define TOTEM_CONFIG_BINDNETADDR_NODELIST_SET (1<<4)
+
+extern int totem_config_read (
+ struct totem_config *totem_config,
+ const char **error_string,
+ uint64_t *warnings);
+
+extern int totem_config_validate (
+ struct totem_config *totem_config,
+ const char **error_string);
+
+extern int totem_config_keyread (
+ struct totem_config *totem_config,
+ icmap_map_t map,
+ const char **error_string);
+
+extern int totem_config_find_local_addr_in_nodelist(
+ struct totem_config *totem_config,
+ const char *ipaddr_key_prefix,
+ unsigned int *node_pos);
+
+extern void totem_volatile_config_read(
+ struct totem_config *totem_config,
+ icmap_map_t temp_map,
+ const char *deleted_key);
+
+extern int totem_reread_crypto_config(
+ struct totem_config *totem_config,
+ icmap_map_t map,
+ const char **error_string);
+
+extern int totem_volatile_config_validate(
+ struct totem_config *totem_config,
+ icmap_map_t temp_map,
+ const char **error_string);
+
+extern int totemconfig_configure_new_params(
+ struct totem_config *totem_config,
+ icmap_map_t map,
+ const char **error_string);
+
+extern int totemconfig_commit_new_params(
+ struct totem_config *totem_config,
+ icmap_map_t map);
+
+#endif /* TOTEMCONFIG_H_DEFINED */
diff --git a/exec/totemip.c b/exec/totemip.c
new file mode 100644
index 0000000..2bf7b08
--- /dev/null
+++ b/exec/totemip.c
@@ -0,0 +1,624 @@
+/*
+ * Copyright (c) 2005-2020 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Author: Patrick Caulfield (pcaulfie@redhat.com)
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of the MontaVista Software, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* IPv4/6 abstraction */
+
+#include <config.h>
+
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <net/if.h>
+#include <string.h>
+#include <stdio.h>
+#include <errno.h>
+#include <assert.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <ifaddrs.h>
+
+#include <corosync/totem/totemip.h>
+#include <corosync/logsys.h>
+#include <corosync/swab.h>
+
+#define LOCALHOST_IPV4 "127.0.0.1"
+#define LOCALHOST_IPV6 "::1"
+
+#define NETLINK_BUFSIZE 16384
+
+#ifdef SO_NOSIGPIPE
+void totemip_nosigpipe(int s)
+{
+ int on = 1;
+ setsockopt(s, SOL_SOCKET, SO_NOSIGPIPE, (void *)&on, sizeof(on));
+}
+#endif
+
+/* Compare two addresses */
+int totemip_equal(const struct totem_ip_address *addr1,
+ const struct totem_ip_address *addr2)
+{
+ int addrlen = 0;
+
+ if (addr1->family != addr2->family)
+ return 0;
+
+ if (addr1->family == AF_INET) {
+ addrlen = sizeof(struct in_addr);
+ }
+ if (addr1->family == AF_INET6) {
+ addrlen = sizeof(struct in6_addr);
+ }
+ assert(addrlen);
+
+ if (memcmp(addr1->addr, addr2->addr, addrlen) == 0)
+ return 1;
+ else
+ return 0;
+
+}
+
+int totemip_sa_equal(const struct totem_ip_address *totem_ip,
+ const struct sockaddr *sa)
+{
+ int res;
+
+ res = 0;
+
+ if (totem_ip->family != sa->sa_family) {
+ return (res);
+ }
+
+ switch (totem_ip->family) {
+ case AF_INET:
+ res = (memcmp(totem_ip->addr,
+ &((const struct sockaddr_in *)sa)->sin_addr, sizeof(struct in_addr)) == 0);
+ break;
+ case AF_INET6:
+ res = (memcmp(totem_ip->addr,
+ &((const struct sockaddr_in6 *)sa)->sin6_addr, sizeof(struct in6_addr)) == 0);
+ break;
+ default:
+ assert(0);
+ }
+
+ return (res);
+}
+
+/* Copy a totem_ip_address */
+void totemip_copy(struct totem_ip_address *addr1,
+ const struct totem_ip_address *addr2)
+{
+ memcpy(addr1, addr2, sizeof(struct totem_ip_address));
+}
+
+/*
+ * Multicast address range is 224.0.0.0 to 239.255.255.255 this
+ * translates to the first 4 bits == 1110 (0xE).
+ * http://en.wikipedia.org/wiki/Multicast_address
+ */
+int32_t totemip_is_mcast(struct totem_ip_address *ip_addr)
+{
+ uint32_t addr = 0;
+
+ memcpy (&addr, ip_addr->addr, sizeof (uint32_t));
+
+ if (ip_addr->family == AF_INET) {
+ addr = ntohl(addr);
+ if ((addr >> 28) != 0xE) {
+ return -1;
+ }
+ }
+ return 0;
+}
+
+/* For sorting etc. params are void * for qsort's benefit */
+int totemip_compare(const void *a, const void *b)
+{
+ int i;
+ const struct totem_ip_address *totemip_a = (const struct totem_ip_address *)a;
+ const struct totem_ip_address *totemip_b = (const struct totem_ip_address *)b;
+ struct in_addr ipv4_a1;
+ struct in_addr ipv4_a2;
+ struct in6_addr ipv6_a1;
+ struct in6_addr ipv6_a2;
+ unsigned short family;
+
+ /*
+ * Use memcpy to align since totem_ip_address is unaligned on various archs
+ */
+ memcpy (&family, &totemip_a->family, sizeof (unsigned short));
+
+ if (family == AF_INET) {
+ memcpy (&ipv4_a1, totemip_a->addr, sizeof (struct in_addr));
+ memcpy (&ipv4_a2, totemip_b->addr, sizeof (struct in_addr));
+ if (ipv4_a1.s_addr == ipv4_a2.s_addr) {
+ return (0);
+ }
+ if (htonl(ipv4_a1.s_addr) < htonl(ipv4_a2.s_addr)) {
+ return -1;
+ } else {
+ return +1;
+ }
+ } else
+ if (family == AF_INET6) {
+ /*
+ * We can only compare 8 bits at time for portability reasons
+ */
+ memcpy (&ipv6_a1, totemip_a->addr, sizeof (struct in6_addr));
+ memcpy (&ipv6_a2, totemip_b->addr, sizeof (struct in6_addr));
+ for (i = 0; i < 16; i++) {
+ int res = ipv6_a1.s6_addr[i] -
+ ipv6_a2.s6_addr[i];
+ if (res) {
+ return res;
+ }
+ }
+ return 0;
+ } else {
+ /*
+ * Family not set, should be!
+ */
+ assert (0);
+ }
+ return 0;
+}
+
+/* Build a localhost totem_ip_address */
+int totemip_localhost(int family, struct totem_ip_address *localhost)
+{
+ const char *addr_text;
+
+ memset (localhost, 0, sizeof (struct totem_ip_address));
+
+ if (family == AF_INET) {
+ addr_text = LOCALHOST_IPV4;
+ if (inet_pton(family, addr_text, (char *)&localhost->nodeid) <= 0) {
+ return -1;
+ }
+ } else {
+ addr_text = LOCALHOST_IPV6;
+ }
+
+ if (inet_pton(family, addr_text, (char *)localhost->addr) <= 0)
+ return -1;
+
+ localhost->family = family;
+
+ return 0;
+}
+
+int totemip_localhost_check(const struct totem_ip_address *addr)
+{
+ struct totem_ip_address localhost;
+
+ if (totemip_localhost(addr->family, &localhost))
+ return 0;
+ return totemip_equal(addr, &localhost);
+}
+
+const char *totemip_sa_print(const struct sockaddr *sa)
+{
+ static char buf[INET6_ADDRSTRLEN];
+
+ buf[0] = 0;
+
+ switch (sa->sa_family) {
+ case AF_INET:
+ inet_ntop(sa->sa_family, &((struct sockaddr_in *)(sa))->sin_addr, buf,
+ INET6_ADDRSTRLEN);
+ break;
+ case AF_INET6:
+ inet_ntop(sa->sa_family, &((struct sockaddr_in6 *)(sa))->sin6_addr, buf,
+ INET6_ADDRSTRLEN);
+ break;
+ default:
+ return (NULL);
+ }
+
+ return (buf);
+}
+
+const char *totemip_print(const struct totem_ip_address *addr)
+{
+ static char buf[INET6_ADDRSTRLEN];
+
+ return (inet_ntop(addr->family, addr->addr, buf, sizeof(buf)));
+}
+
+/* Make a totem_ip_address into a usable sockaddr_storage */
+int totemip_totemip_to_sockaddr_convert(struct totem_ip_address *ip_addr,
+ uint16_t port, struct sockaddr_storage *saddr, int *addrlen)
+{
+ int ret = -1;
+
+ if (ip_addr->family == AF_INET) {
+ struct sockaddr_in *sin = (struct sockaddr_in *)saddr;
+
+ memset(sin, 0, sizeof(struct sockaddr_in));
+#ifdef HAVE_SOCK_SIN_LEN
+ sin->sin_len = sizeof(struct sockaddr_in);
+#endif
+ sin->sin_family = ip_addr->family;
+ sin->sin_port = ntohs(port);
+ memcpy(&sin->sin_addr, ip_addr->addr, sizeof(struct in_addr));
+ *addrlen = sizeof(struct sockaddr_in);
+ ret = 0;
+ }
+
+ if (ip_addr->family == AF_INET6) {
+ struct sockaddr_in6 *sin = (struct sockaddr_in6 *)saddr;
+
+ memset(sin, 0, sizeof(struct sockaddr_in6));
+#ifdef HAVE_SOCK_SIN6_LEN
+ sin->sin6_len = sizeof(struct sockaddr_in6);
+#endif
+ sin->sin6_family = ip_addr->family;
+ sin->sin6_port = ntohs(port);
+ sin->sin6_scope_id = 2;
+ memcpy(&sin->sin6_addr, ip_addr->addr, sizeof(struct in6_addr));
+
+ *addrlen = sizeof(struct sockaddr_in6);
+ ret = 0;
+ }
+
+ return ret;
+}
+
+/*
+ * Converts an address string string into a totem_ip_address. ip_version enum
+ * defines order.
+ */
+int totemip_parse(struct totem_ip_address *totemip, const char *addr,
+ enum totem_ip_version_enum ip_version)
+{
+ struct addrinfo *ainfo;
+ struct addrinfo *ainfo_iter;
+ struct addrinfo *ainfo_ipv4;
+ struct addrinfo *ainfo_ipv6;
+ struct addrinfo *ainfo_final;
+ struct addrinfo ahints;
+ struct sockaddr_in *sa;
+ struct sockaddr_in6 *sa6;
+ int ret;
+ int debug_ip_family;
+ int ai_family;
+
+ memset(&ahints, 0, sizeof(ahints));
+ ahints.ai_socktype = SOCK_DGRAM;
+ ahints.ai_protocol = IPPROTO_UDP;
+
+ ai_family = AF_UNSPEC;
+ debug_ip_family = 0;
+
+ switch (ip_version) {
+ case TOTEM_IP_VERSION_4:
+ ai_family = AF_INET;
+ debug_ip_family = 4;
+ break;
+ case TOTEM_IP_VERSION_6:
+ ai_family = AF_INET6;
+ debug_ip_family = 6;
+ break;
+ case TOTEM_IP_VERSION_6_4:
+ case TOTEM_IP_VERSION_4_6:
+ /*
+ * ai_family and debug_ip_family are already set correctly
+ */
+ break;
+ }
+
+ ahints.ai_family = ai_family;
+
+ ret = getaddrinfo(addr, NULL, &ahints, &ainfo);
+
+ if (ret == 0 && ai_family == AF_UNSPEC) {
+ ainfo_ipv4 = ainfo_ipv6 = NULL;
+
+ /*
+ * Walk thru results and store first AF_INET and AF_INET6
+ */
+ for (ainfo_iter = ainfo; ainfo_iter != NULL; ainfo_iter = ainfo_iter->ai_next) {
+ if (ainfo_iter->ai_family == AF_INET && ainfo_ipv4 == NULL) {
+ ainfo_ipv4 = ainfo_iter;
+ }
+
+ if (ainfo_iter->ai_family == AF_INET6 && ainfo_ipv6 == NULL) {
+ ainfo_ipv6 = ainfo_iter;
+ }
+ }
+
+ if (ip_version == TOTEM_IP_VERSION_6_4) {
+ if (ainfo_ipv6 != NULL) {
+ ainfo_final = ainfo_ipv6;
+ } else {
+ ainfo_final = ainfo_ipv4;
+ }
+ } else {
+ if (ainfo_ipv4 != NULL) {
+ ainfo_final = ainfo_ipv4;
+ } else {
+ ainfo_final = ainfo_ipv6;
+ }
+ }
+ } else if (ret == 0) {
+ ainfo_final = ainfo;
+ } else {
+ ainfo_final = NULL;
+ }
+
+ if (ainfo_final == NULL) {
+ if (ret == 0) {
+ freeaddrinfo(ainfo);
+ }
+
+ if (debug_ip_family == 0) {
+ log_printf(LOGSYS_LEVEL_DEBUG, "totemip_parse: IP address of %s not resolvable",
+ addr);
+ } else {
+ log_printf(LOGSYS_LEVEL_DEBUG, "totemip_parse: IPv%u address of %s not resolvable",
+ debug_ip_family, addr);
+ }
+
+ return (-1);
+ }
+
+ totemip->family = ainfo_final->ai_family;
+ if (ainfo_final->ai_family == AF_INET) {
+ sa = (struct sockaddr_in *)ainfo_final->ai_addr;
+ memcpy(totemip->addr, &sa->sin_addr, sizeof(struct in_addr));
+ debug_ip_family = 4;
+ } else {
+ sa6 = (struct sockaddr_in6 *)ainfo_final->ai_addr;
+ memcpy(totemip->addr, &sa6->sin6_addr, sizeof(struct in6_addr));
+ debug_ip_family = 6;
+ }
+
+ log_printf(LOGSYS_LEVEL_DEBUG, "totemip_parse: IPv%u address of %s resolved as %s",
+ debug_ip_family, addr, totemip_print(totemip));
+
+ freeaddrinfo(ainfo);
+
+ return (0);
+}
+
+/* Make a sockaddr_* into a totem_ip_address */
+int totemip_sockaddr_to_totemip_convert(const struct sockaddr_storage *saddr,
+ struct totem_ip_address *ip_addr)
+{
+ int ret = -1;
+
+ ip_addr->family = saddr->ss_family;
+ ip_addr->nodeid = 0;
+
+ if (saddr->ss_family == AF_INET) {
+ const struct sockaddr_in *sin = (const struct sockaddr_in *)saddr;
+
+ memcpy(ip_addr->addr, &sin->sin_addr, sizeof(struct in_addr));
+ ret = 0;
+ }
+
+ if (saddr->ss_family == AF_INET6) {
+ const struct sockaddr_in6 *sin
+ = (const struct sockaddr_in6 *)saddr;
+
+ memcpy(ip_addr->addr, &sin->sin6_addr, sizeof(struct in6_addr));
+
+ ret = 0;
+ }
+ return ret;
+}
+
+int totemip_getifaddrs(struct qb_list_head *addrs)
+{
+ struct ifaddrs *ifap, *ifa;
+ struct totem_ip_if_address *if_addr;
+
+ if (getifaddrs(&ifap) != 0)
+ return (-1);
+
+ qb_list_init(addrs);
+
+ for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
+ if (ifa->ifa_addr == NULL || ifa->ifa_netmask == NULL)
+ continue ;
+
+ if ((ifa->ifa_addr->sa_family != AF_INET && ifa->ifa_addr->sa_family != AF_INET6) ||
+ (ifa->ifa_netmask->sa_family != AF_INET && ifa->ifa_netmask->sa_family != AF_INET6 &&
+ ifa->ifa_netmask->sa_family != 0))
+ continue ;
+
+ if (ifa->ifa_netmask->sa_family == 0) {
+ ifa->ifa_netmask->sa_family = ifa->ifa_addr->sa_family;
+ }
+
+ if_addr = malloc(sizeof(struct totem_ip_if_address));
+ if (if_addr == NULL) {
+ goto error_free_ifaddrs;
+ }
+
+ qb_list_init(&if_addr->list);
+
+ memset(if_addr, 0, sizeof(struct totem_ip_if_address));
+
+ if_addr->interface_up = ifa->ifa_flags & IFF_UP;
+ if_addr->interface_num = if_nametoindex(ifa->ifa_name);
+ if_addr->name = strdup(ifa->ifa_name);
+ if (if_addr->name == NULL) {
+ goto error_free_addr;
+ }
+
+ if (totemip_sockaddr_to_totemip_convert((const struct sockaddr_storage *)ifa->ifa_addr,
+ &if_addr->ip_addr) == -1) {
+ goto error_free_addr_name;
+ }
+
+ if (totemip_sockaddr_to_totemip_convert((const struct sockaddr_storage *)ifa->ifa_netmask,
+ &if_addr->mask_addr) == -1) {
+ goto error_free_addr_name;
+ }
+
+ qb_list_add_tail(&if_addr->list, addrs);
+ }
+
+ freeifaddrs(ifap);
+
+ return (0);
+
+error_free_addr_name:
+ free(if_addr->name);
+
+error_free_addr:
+ free(if_addr);
+
+error_free_ifaddrs:
+ totemip_freeifaddrs(addrs);
+ freeifaddrs(ifap);
+ return (-1);
+}
+
+void totemip_freeifaddrs(struct qb_list_head *addrs)
+{
+ struct totem_ip_if_address *if_addr;
+ struct qb_list_head *list, *tmp_iter;
+
+ qb_list_for_each_safe(list, tmp_iter, addrs) {
+ if_addr = qb_list_entry(list, struct totem_ip_if_address, list);
+
+ free(if_addr->name);
+ qb_list_del(&if_addr->list);
+ free(if_addr);
+ }
+ qb_list_init(addrs);
+}
+
+int totemip_iface_check(struct totem_ip_address *bindnet,
+ struct totem_ip_address *boundto,
+ int *interface_up,
+ int *interface_num,
+ int mask_high_bit)
+{
+ struct qb_list_head addrs;
+ struct qb_list_head *list;
+ struct totem_ip_if_address *if_addr;
+ struct totem_ip_address bn_netaddr, if_netaddr;
+ socklen_t addr_len;
+ socklen_t si;
+ int res = -1;
+ int exact_match_found = 0;
+ int net_match_found = 0;
+
+ *interface_up = 0;
+ *interface_num = 0;
+
+ if (totemip_getifaddrs(&addrs) == -1) {
+ return (-1);
+ }
+
+ qb_list_for_each(list, &addrs) {
+ if_addr = qb_list_entry(list, struct totem_ip_if_address, list);
+
+ if (bindnet->family != if_addr->ip_addr.family)
+ continue ;
+
+ addr_len = 0;
+
+ switch (bindnet->family) {
+ case AF_INET:
+ addr_len = sizeof(struct in_addr);
+ break;
+ case AF_INET6:
+ addr_len = sizeof(struct in6_addr);
+ break;
+ }
+
+ if (addr_len == 0)
+ continue ;
+
+ totemip_copy(&bn_netaddr, bindnet);
+ totemip_copy(&if_netaddr, &if_addr->ip_addr);
+
+ if (totemip_equal(&bn_netaddr, &if_netaddr)) {
+ exact_match_found = 1;
+ }
+
+ for (si = 0; si < addr_len; si++) {
+ bn_netaddr.addr[si] = bn_netaddr.addr[si] & if_addr->mask_addr.addr[si];
+ if_netaddr.addr[si] = if_netaddr.addr[si] & if_addr->mask_addr.addr[si];
+ }
+
+ if (exact_match_found || (!net_match_found && totemip_equal(&bn_netaddr, &if_netaddr))) {
+ totemip_copy(boundto, &if_addr->ip_addr);
+ boundto->nodeid = bindnet->nodeid;
+ *interface_up = if_addr->interface_up;
+ *interface_num = if_addr->interface_num;
+
+ net_match_found = 1;
+ res = 0;
+
+ if (exact_match_found) {
+ goto finished;
+ }
+ }
+ }
+
+finished:
+ totemip_freeifaddrs(&addrs);
+ return (res);
+}
+
+#define TOTEMIP_UDP_HEADER_SIZE 8
+#define TOTEMIP_IPV4_HEADER_SIZE 20
+#define TOTEMIP_IPV6_HEADER_SIZE 40
+
+size_t totemip_udpip_header_size(int family)
+{
+ size_t header_size;
+
+ header_size = 0;
+
+ switch (family) {
+ case AF_INET:
+ header_size = TOTEMIP_UDP_HEADER_SIZE + TOTEMIP_IPV4_HEADER_SIZE;
+ break;
+ case AF_INET6:
+ header_size = TOTEMIP_UDP_HEADER_SIZE + TOTEMIP_IPV6_HEADER_SIZE;
+ break;
+ }
+
+ return (header_size);
+}
diff --git a/exec/totemknet.c b/exec/totemknet.c
new file mode 100644
index 0000000..f280a09
--- /dev/null
+++ b/exec/totemknet.c
@@ -0,0 +1,2306 @@
+/*
+ * Copyright (c) 2016-2022 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Author: Christine Caulfield (ccaulfie@redhat.com)
+
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of the MontaVista Software, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include <assert.h>
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <sys/un.h>
+#include <sys/ioctl.h>
+#include <sys/param.h>
+#include <netinet/in.h>
+#include <net/ethernet.h>
+#include <arpa/inet.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+#include <pthread.h>
+#include <sched.h>
+#include <time.h>
+#include <sys/time.h>
+#include <sys/poll.h>
+#include <sys/uio.h>
+#include <limits.h>
+
+#include <qb/qbdefs.h>
+#include <qb/qbloop.h>
+#ifdef HAVE_LIBNOZZLE
+#include <libgen.h>
+#include <libnozzle.h>
+#endif
+
+#include <corosync/sq.h>
+#include <corosync/swab.h>
+#include <corosync/logsys.h>
+#include <corosync/icmap.h>
+#include <corosync/totem/totemip.h>
+#include "totemknet.h"
+
+#include "main.h"
+#include "util.h"
+
+#include <libknet.h>
+#include <corosync/totem/totemstats.h>
+
+#ifndef MSG_NOSIGNAL
+#define MSG_NOSIGNAL 0
+#endif
+
+#ifdef HAVE_LIBNOZZLE
+static int setup_nozzle(void *knet_context);
+#endif
+
+/* Should match that used by cfg */
+#define CFG_INTERFACE_STATUS_MAX_LEN 512
+
+struct totemknet_instance {
+ struct crypto_instance *crypto_inst;
+
+ qb_loop_t *poll_handle;
+
+ knet_handle_t knet_handle;
+
+ int link_mode;
+
+ void *context;
+
+ int (*totemknet_deliver_fn) (
+ void *context,
+ const void *msg,
+ unsigned int msg_len,
+ const struct sockaddr_storage *system_from);
+
+ int (*totemknet_iface_change_fn) (
+ void *context,
+ const struct totem_ip_address *iface_address,
+ unsigned int link_no);
+
+ void (*totemknet_mtu_changed) (
+ void *context,
+ int net_mtu);
+
+ void (*totemknet_target_set_completed) (void *context);
+
+ /*
+ * Function and data used to log messages
+ */
+ int totemknet_log_level_security;
+
+ int totemknet_log_level_error;
+
+ int totemknet_log_level_warning;
+
+ int totemknet_log_level_notice;
+
+ int totemknet_log_level_debug;
+
+ int totemknet_subsys_id;
+
+ int knet_subsys_id;
+
+ void (*totemknet_log_printf) (
+ int level,
+ int subsys,
+ const char *function,
+ const char *file,
+ int line,
+ const char *format,
+ ...)__attribute__((format(printf, 6, 7)));
+
+ void *knet_context;
+
+ char iov_buffer[KNET_MAX_PACKET_SIZE];
+
+ char *link_status[INTERFACE_MAX];
+
+ struct totem_ip_address my_ids[INTERFACE_MAX];
+
+ uint16_t ip_port[INTERFACE_MAX];
+
+ int our_nodeid;
+
+ int loopback_link;
+
+ struct totem_config *totem_config;
+
+ struct totem_ip_address token_target;
+
+ qb_loop_timer_handle timer_netif_check_timeout;
+
+ qb_loop_timer_handle timer_merge_detect_timeout;
+
+ int send_merge_detect_message;
+
+ unsigned int merge_detect_messages_sent_before_timeout;
+
+ int logpipes[2];
+ int knet_fd;
+
+ pthread_mutex_t log_mutex;
+#ifdef HAVE_LIBNOZZLE
+ char *nozzle_name;
+ char *nozzle_ipaddr;
+ char *nozzle_prefix;
+ char *nozzle_macaddr;
+ nozzle_t nozzle_handle;
+#endif
+};
+
+/* Awkward. But needed to get stats from knet */
+struct totemknet_instance *global_instance;
+
+struct work_item {
+ const void *msg;
+ unsigned int msg_len;
+ struct totemknet_instance *instance;
+};
+
+int totemknet_member_list_rebind_ip (
+ void *knet_context);
+
+
+static int totemknet_configure_compression (
+ struct totemknet_instance *instance,
+ struct totem_config *totem_config);
+
+static void totemknet_start_merge_detect_timeout(
+ void *knet_context);
+
+static void totemknet_stop_merge_detect_timeout(
+ void *knet_context);
+
+static void log_flush_messages (
+ void *knet_context);
+
+static void totemknet_instance_initialize (struct totemknet_instance *instance)
+{
+ int res;
+
+ memset (instance, 0, sizeof (struct totemknet_instance));
+ res = pthread_mutex_init(&instance->log_mutex, NULL);
+ /*
+ * There is not too much else what can be done.
+ */
+ assert(res == 0);
+}
+
+#define knet_log_printf_lock(level, subsys, function, file, line, format, args...) \
+do { \
+ (void)pthread_mutex_lock(&instance->log_mutex); \
+ instance->totemknet_log_printf ( \
+ level, subsys, function, file, line, \
+ (const char *)format, ##args); \
+ (void)pthread_mutex_unlock(&instance->log_mutex); \
+} while (0);
+
+#define knet_log_printf(level, format, args...) \
+do { \
+ knet_log_printf_lock ( \
+ level, instance->totemknet_subsys_id, \
+ __FUNCTION__, __FILE__, __LINE__, \
+ (const char *)format, ##args); \
+} while (0);
+
+#define libknet_log_printf(level, format, args...) \
+do { \
+ knet_log_printf_lock ( \
+ level, instance->knet_subsys_id, \
+ __FUNCTION__, "libknet.h", __LINE__, \
+ (const char *)format, ##args); \
+} while (0);
+
+#define KNET_LOGSYS_PERROR(err_num, level, fmt, args...) \
+do { \
+ char _error_str[LOGSYS_MAX_PERROR_MSG_LEN]; \
+ const char *_error_ptr = qb_strerror_r(err_num, _error_str, sizeof(_error_str)); \
+ instance->totemknet_log_printf ( \
+ level, instance->totemknet_subsys_id, \
+ __FUNCTION__, __FILE__, __LINE__, \
+ fmt ": %s (%d)", ##args, _error_ptr, err_num); \
+ } while(0)
+
+
+#ifdef HAVE_LIBNOZZLE
+static inline int is_ether_addr_multicast(const uint8_t *addr)
+{
+ return (addr[0] & 0x01);
+}
+static inline int is_ether_addr_zero(const uint8_t *addr)
+{
+ return (!addr[0] && !addr[1] && !addr[2] && !addr[3] && !addr[4] && !addr[5]);
+}
+
+static int ether_host_filter_fn(void *private_data,
+ const unsigned char *outdata,
+ ssize_t outdata_len,
+ uint8_t tx_rx,
+ knet_node_id_t this_host_id,
+ knet_node_id_t src_host_id,
+ int8_t *channel,
+ knet_node_id_t *dst_host_ids,
+ size_t *dst_host_ids_entries)
+{
+ struct ether_header *eth_h = (struct ether_header *)outdata;
+ uint8_t *dst_mac = (uint8_t *)eth_h->ether_dhost;
+ uint16_t dst_host_id;
+
+ if (is_ether_addr_zero(dst_mac))
+ return -1;
+
+ if (is_ether_addr_multicast(dst_mac)) {
+ return 1;
+ }
+
+ memmove(&dst_host_id, &dst_mac[4], 2);
+
+ dst_host_ids[0] = ntohs(dst_host_id);
+ *dst_host_ids_entries = 1;
+
+ return 0;
+}
+#endif
+
+static int dst_host_filter_callback_fn(void *private_data,
+ const unsigned char *outdata,
+ ssize_t outdata_len,
+ uint8_t tx_rx,
+ knet_node_id_t this_host_id,
+ knet_node_id_t src_host_id,
+ int8_t *channel,
+ knet_node_id_t *dst_host_ids,
+ size_t *dst_host_ids_entries)
+{
+ struct totem_message_header *header = (struct totem_message_header *)outdata;
+ int res;
+
+#ifdef HAVE_LIBNOZZLE
+ if (*channel != 0) {
+ return ether_host_filter_fn(private_data,
+ outdata, outdata_len,
+ tx_rx,
+ this_host_id, src_host_id,
+ channel,
+ dst_host_ids,
+ dst_host_ids_entries);
+ }
+#endif
+ if (header->target_nodeid) {
+ dst_host_ids[0] = header->target_nodeid;
+ *dst_host_ids_entries = 1;
+ res = 0; /* unicast message */
+ }
+ else {
+ *dst_host_ids_entries = 0;
+ res = 1; /* multicast message */
+ }
+ return res;
+}
+
+static void socket_error_callback_fn(void *private_data, int datafd, int8_t channel, uint8_t tx_rx, int error, int errorno)
+{
+ struct totemknet_instance *instance = (struct totemknet_instance *)private_data;
+
+ knet_log_printf (LOGSYS_LEVEL_DEBUG, "Knet socket ERROR notification called: txrx=%d, error=%d, errorno=%d", tx_rx, error, errorno);
+ if ((error == -1 && errorno != EAGAIN) || (error == 0)) {
+ knet_handle_remove_datafd(instance->knet_handle, datafd);
+ }
+}
+
+static void host_change_callback_fn(void *private_data, knet_node_id_t host_id, uint8_t reachable, uint8_t remote, uint8_t external)
+{
+ struct totemknet_instance *instance = (struct totemknet_instance *)private_data;
+
+ // TODO: what? if anything.
+ knet_log_printf (LOGSYS_LEVEL_DEBUG, "Knet host change callback. nodeid: " CS_PRI_NODE_ID " reachable: %d", host_id, reachable);
+}
+
+static void pmtu_change_callback_fn(void *private_data, unsigned int data_mtu)
+{
+ struct totemknet_instance *instance = (struct totemknet_instance *)private_data;
+ knet_log_printf (LOGSYS_LEVEL_DEBUG, "Knet pMTU change: %d", data_mtu);
+
+ /* We don't need to tell corosync the actual knet MTU */
+// instance->totemknet_mtu_changed(instance->context, data_mtu);
+}
+
+int totemknet_crypto_set (
+ void *knet_context,
+ const char *cipher_type,
+ const char *hash_type)
+{
+ return (0);
+}
+
+
+static inline void ucast_sendmsg (
+ struct totemknet_instance *instance,
+ struct totem_ip_address *system_to,
+ const void *msg,
+ unsigned int msg_len)
+{
+ int res = 0;
+ struct totem_message_header *header = (struct totem_message_header *)msg;
+ struct msghdr msg_ucast;
+ struct iovec iovec;
+
+ header->target_nodeid = system_to->nodeid;
+
+ iovec.iov_base = (void *)msg;
+ iovec.iov_len = msg_len;
+
+ /*
+ * Build unicast message
+ */
+ memset(&msg_ucast, 0, sizeof(msg_ucast));
+ msg_ucast.msg_iov = (void *)&iovec;
+ msg_ucast.msg_iovlen = 1;
+#ifdef HAVE_MSGHDR_CONTROL
+ msg_ucast.msg_control = 0;
+#endif
+#ifdef HAVE_MSGHDR_CONTROLLEN
+ msg_ucast.msg_controllen = 0;
+#endif
+#ifdef HAVE_MSGHDR_FLAGS
+ msg_ucast.msg_flags = 0;
+#endif
+#ifdef HAVE_MSGHDR_ACCRIGHTS
+ msg_ucast.msg_accrights = NULL;
+#endif
+#ifdef HAVE_MSGHDR_ACCRIGHTSLEN
+ msg_ucast.msg_accrightslen = 0;
+#endif
+
+ /*
+ * Transmit unicast message
+ * An error here is recovered by totemsrp
+ */
+
+ res = sendmsg (instance->knet_fd, &msg_ucast, MSG_NOSIGNAL);
+ if (res < 0) {
+ KNET_LOGSYS_PERROR (errno, instance->totemknet_log_level_debug,
+ "sendmsg(ucast) failed (non-critical)");
+ }
+}
+
+static inline void mcast_sendmsg (
+ struct totemknet_instance *instance,
+ const void *msg,
+ unsigned int msg_len,
+ int only_active)
+{
+ int res;
+ struct totem_message_header *header = (struct totem_message_header *)msg;
+ struct msghdr msg_mcast;
+ struct iovec iovec;
+
+ iovec.iov_base = (void *)msg;
+ iovec.iov_len = msg_len;
+
+ header->target_nodeid = 0;
+
+ /*
+ * Build multicast message
+ */
+ memset(&msg_mcast, 0, sizeof(msg_mcast));
+ msg_mcast.msg_iov = (void *)&iovec;
+ msg_mcast.msg_iovlen = 1;
+#ifdef HAVE_MSGHDR_CONTROL
+ msg_mcast.msg_control = 0;
+#endif
+#ifdef HAVE_MSGHDR_CONTROLLEN
+ msg_mcast.msg_controllen = 0;
+#endif
+#ifdef HAVE_MSGHDR_FLAGS
+ msg_mcast.msg_flags = 0;
+#endif
+#ifdef HAVE_MSGHDR_ACCRIGHTS
+ msg_mcast.msg_accrights = NULL;
+#endif
+#ifdef HAVE_MSGHDR_ACCRIGHTSLEN
+ msg_mcast.msg_accrightslen = 0;
+#endif
+
+
+// log_printf (LOGSYS_LEVEL_DEBUG, "totemknet: mcast_sendmsg. only_active=%d, len=%d", only_active, msg_len);
+
+ res = sendmsg (instance->knet_fd, &msg_mcast, MSG_NOSIGNAL);
+ if (res < msg_len) {
+ knet_log_printf (LOGSYS_LEVEL_DEBUG, "totemknet: mcast_send sendmsg returned %d", res);
+ }
+
+ if (!only_active || instance->send_merge_detect_message) {
+ /*
+ * Current message was sent to all nodes
+ */
+ instance->merge_detect_messages_sent_before_timeout++;
+ instance->send_merge_detect_message = 0;
+ }
+}
+
+static int node_compare(const void *aptr, const void *bptr)
+{
+ uint16_t a,b;
+
+ a = *(uint16_t *)aptr;
+ b = *(uint16_t *)bptr;
+
+ return a > b;
+}
+
+#ifndef OWN_INDEX_NONE
+#define OWN_INDEX_NONE -1
+#endif
+
+int totemknet_nodestatus_get (
+ void *knet_context,
+ unsigned int nodeid,
+ struct totem_node_status *node_status)
+{
+ int i;
+ int res = 0;
+ struct knet_link_status link_status;
+ struct totemknet_instance *instance = (struct totemknet_instance *)knet_context;
+ struct knet_host_status knet_host_status;
+ uint8_t link_list[KNET_MAX_LINK];
+ size_t num_links;
+
+ if (!instance->knet_handle) {
+ return CS_ERR_NOT_EXIST; /* Not using knet */
+ }
+
+ if (!node_status) {
+ return CS_ERR_INVALID_PARAM;
+ }
+
+ res = knet_host_get_status(instance->knet_handle,
+ nodeid,
+ &knet_host_status);
+ if (res) {
+ knet_log_printf (LOGSYS_LEVEL_WARNING, "knet_handle_get_host_status(%d) failed: %d", nodeid, res);
+ return (-1);
+ }
+ node_status->nodeid = nodeid;
+ node_status->reachable = knet_host_status.reachable;
+ node_status->remote = knet_host_status.remote;
+ node_status->external = knet_host_status.external;
+
+#ifdef HAVE_KNET_ONWIRE_VER
+ res = knet_handle_get_onwire_ver(instance->knet_handle,
+ nodeid,
+ &node_status->onwire_min,
+ &node_status->onwire_max,
+ &node_status->onwire_ver);
+ if (res) {
+ knet_log_printf (LOGSYS_LEVEL_WARNING, "knet_handle_get_onwire_ver(%d) failed: %d", nodeid, res);
+ return (-1);
+ }
+#endif
+ /* Get link info */
+ res = knet_link_get_link_list(instance->knet_handle,
+ nodeid, link_list, &num_links);
+ if (res) {
+ knet_log_printf (LOGSYS_LEVEL_WARNING, "knet_link_get_link_list(%d) failed: %d", nodeid, res);
+ return (-1);
+ }
+
+ /* node_status[] has been zeroed for us in totempg.c */
+ for (i=0; i < num_links; i++) {
+ if (!instance->totem_config->interfaces[link_list[i]].configured) {
+ continue;
+ }
+ res = knet_link_get_status(instance->knet_handle,
+ nodeid,
+ link_list[i],
+ &link_status,
+ sizeof(link_status));
+ if (res == 0) {
+ node_status->link_status[link_list[i]].enabled = link_status.enabled;
+ node_status->link_status[link_list[i]].connected = link_status.connected;
+ node_status->link_status[link_list[i]].dynconnected = link_status.dynconnected;
+ node_status->link_status[link_list[i]].mtu = link_status.mtu;
+ memcpy(node_status->link_status[link_list[i]].src_ipaddr, link_status.src_ipaddr, KNET_MAX_HOST_LEN);
+ memcpy(node_status->link_status[link_list[i]].dst_ipaddr, link_status.dst_ipaddr, KNET_MAX_HOST_LEN);
+ } else {
+ knet_log_printf (LOGSYS_LEVEL_WARNING, "knet_link_get_link_status(%d, %d) failed: %d", nodeid, link_list[i], res);
+ }
+ }
+ return res;
+}
+
+
+
+int totemknet_ifaces_get (void *knet_context,
+ char ***status,
+ unsigned int *iface_count)
+{
+ struct totemknet_instance *instance = (struct totemknet_instance *)knet_context;
+ struct knet_link_status link_status;
+ knet_node_id_t host_list[KNET_MAX_HOST];
+ uint8_t link_list[KNET_MAX_LINK];
+ size_t num_hosts;
+ size_t num_links;
+ size_t link_idx;
+ int i,j;
+ char *ptr;
+ int res = 0;
+
+ /*
+ * Don't do the whole 'link_info' bit if the caller just wants
+ * a count of interfaces.
+ */
+ if (status) {
+ int own_idx = OWN_INDEX_NONE;
+
+ res = knet_host_get_host_list(instance->knet_handle,
+ host_list, &num_hosts);
+ if (res) {
+ return (-1);
+ }
+ qsort(host_list, num_hosts, sizeof(uint16_t), node_compare);
+
+ for (j=0; j<num_hosts; j++) {
+ if (host_list[j] == instance->our_nodeid) {
+ own_idx = j;
+ break;
+ }
+ }
+
+ for (i=0; i<INTERFACE_MAX; i++) {
+ memset(instance->link_status[i], 'd', CFG_INTERFACE_STATUS_MAX_LEN-1);
+ if (own_idx != OWN_INDEX_NONE) {
+ instance->link_status[i][own_idx] = 'n';
+ }
+ instance->link_status[i][num_hosts] = '\0';
+ }
+
+ /* This is all a bit "inside-out" because "status" is a set of strings per link
+ * and knet orders things by host
+ */
+ for (j=0; j<num_hosts; j++) {
+ if (own_idx != OWN_INDEX_NONE && j == own_idx) {
+ continue ;
+ }
+
+ res = knet_link_get_link_list(instance->knet_handle,
+ host_list[j], link_list, &num_links);
+ if (res) {
+ return (-1);
+ }
+
+ link_idx = 0;
+ for (i=0; i < num_links; i++) {
+ /*
+ * Skip over links that are unconfigured to corosync. This is basically
+ * link0 if corosync isn't using it for comms, as we will still
+ * have it set up for loopback.
+ */
+ if (!instance->totem_config->interfaces[link_list[i]].configured) {
+ continue;
+ }
+ ptr = instance->link_status[link_idx++];
+
+ res = knet_link_get_status(instance->knet_handle,
+ host_list[j],
+ link_list[i],
+ &link_status,
+ sizeof(link_status));
+ if (res == 0) {
+ ptr[j] = '0' + (link_status.enabled |
+ link_status.connected<<1 |
+ link_status.dynconnected<<2);
+ }
+ else {
+ knet_log_printf (LOGSYS_LEVEL_ERROR,
+ "totemknet_ifaces_get: Cannot get link status: %s", strerror(errno));
+ ptr[j] = '?';
+ }
+ }
+ }
+ *status = instance->link_status;
+ }
+
+ *iface_count = INTERFACE_MAX;
+
+ return (res);
+}
+
+int totemknet_finalize (
+ void *knet_context)
+{
+ struct totemknet_instance *instance = (struct totemknet_instance *)knet_context;
+ int res = 0;
+ int i,j;
+ static knet_node_id_t nodes[KNET_MAX_HOST]; /* static to save stack */
+ uint8_t links[KNET_MAX_LINK];
+ size_t num_nodes;
+ size_t num_links;
+
+ knet_log_printf(LOG_DEBUG, "totemknet: finalize");
+
+ qb_loop_poll_del (instance->poll_handle, instance->logpipes[0]);
+ qb_loop_poll_del (instance->poll_handle, instance->knet_fd);
+
+ /*
+ * Disable forwarding to make knet flush send queue. This ensures that the LEAVE message will be sent.
+ */
+ res = knet_handle_setfwd(instance->knet_handle, 0);
+ if (res) {
+ knet_log_printf (LOGSYS_LEVEL_CRIT, "totemknet: knet_handle_setfwd failed: %s", strerror(errno));
+ }
+
+ res = knet_host_get_host_list(instance->knet_handle, nodes, &num_nodes);
+ if (res) {
+ knet_log_printf (LOGSYS_LEVEL_ERROR, "Cannot get knet node list for shutdown: %s", strerror(errno));
+ /* Crash out anyway */
+ goto finalise_error;
+ }
+
+ /* Tidily shut down all nodes & links. */
+ for (i=0; i<num_nodes; i++) {
+
+ res = knet_link_get_link_list(instance->knet_handle, nodes[i], links, &num_links);
+ if (res) {
+ knet_log_printf (LOGSYS_LEVEL_ERROR, "Cannot get knet link list for node " CS_PRI_NODE_ID ": %s", nodes[i], strerror(errno));
+ goto finalise_error;
+ }
+ for (j=0; j<num_links; j++) {
+ res = knet_link_set_enable(instance->knet_handle, nodes[i], links[j], 0);
+ if (res) {
+ knet_log_printf (LOGSYS_LEVEL_ERROR, "totemknet: knet_link_set_enable(node " CS_PRI_NODE_ID ", link %d) failed: %s", nodes[i], links[j], strerror(errno));
+ }
+ res = knet_link_clear_config(instance->knet_handle, nodes[i], links[j]);
+ if (res) {
+ knet_log_printf (LOGSYS_LEVEL_ERROR, "totemknet: knet_link_clear_config(node " CS_PRI_NODE_ID ", link %d) failed: %s", nodes[i], links[j], strerror(errno));
+ }
+ }
+ res = knet_host_remove(instance->knet_handle, nodes[i]);
+ if (res) {
+ knet_log_printf (LOGSYS_LEVEL_ERROR, "totemknet: knet_host_remove(node " CS_PRI_NODE_ID ") failed: %s", nodes[i], strerror(errno));
+ }
+ }
+
+finalise_error:
+ res = knet_handle_free(instance->knet_handle);
+ if (res) {
+ knet_log_printf (LOGSYS_LEVEL_CRIT, "totemknet: knet_handle_free failed: %s", strerror(errno));
+ }
+
+ totemknet_stop_merge_detect_timeout(instance);
+
+ log_flush_messages(instance);
+
+ /*
+ * Error is deliberately ignored
+ */
+ (void)pthread_mutex_destroy(&instance->log_mutex);
+
+ return (res);
+}
+
+static int log_deliver_fn (
+ int fd,
+ int revents,
+ void *data)
+{
+ struct totemknet_instance *instance = (struct totemknet_instance *)data;
+ char buffer[sizeof(struct knet_log_msg)*4];
+ char *bufptr = buffer;
+ int done = 0;
+ int len;
+
+ len = read(fd, buffer, sizeof(buffer));
+ while (done < len) {
+ struct knet_log_msg *msg = (struct knet_log_msg *)bufptr;
+ switch (msg->msglevel) {
+ case KNET_LOG_ERR:
+ libknet_log_printf (LOGSYS_LEVEL_ERROR, "%s: %s",
+ knet_log_get_subsystem_name(msg->subsystem),
+ msg->msg);
+ break;
+ case KNET_LOG_WARN:
+ libknet_log_printf (LOGSYS_LEVEL_WARNING, "%s: %s",
+ knet_log_get_subsystem_name(msg->subsystem),
+ msg->msg);
+ break;
+ case KNET_LOG_INFO:
+ libknet_log_printf (LOGSYS_LEVEL_INFO, "%s: %s",
+ knet_log_get_subsystem_name(msg->subsystem),
+ msg->msg);
+ break;
+ case KNET_LOG_DEBUG:
+ libknet_log_printf (LOGSYS_LEVEL_DEBUG, "%s: %s",
+ knet_log_get_subsystem_name(msg->subsystem),
+ msg->msg);
+ break;
+#ifdef KNET_LOG_TRACE
+ case KNET_LOG_TRACE:
+ libknet_log_printf (LOGSYS_LEVEL_TRACE, "%s: %s",
+ knet_log_get_subsystem_name(msg->subsystem),
+ msg->msg);
+ break;
+#endif
+ }
+ bufptr += sizeof(struct knet_log_msg);
+ done += sizeof(struct knet_log_msg);
+ }
+ return 0;
+}
+
+static int data_deliver_fn (
+ int fd,
+ int revents,
+ void *data)
+{
+ struct totemknet_instance *instance = (struct totemknet_instance *)data;
+ struct msghdr msg_hdr;
+ struct iovec iov_recv;
+ struct sockaddr_storage system_from;
+ ssize_t msg_len;
+ int truncated_packet;
+
+ iov_recv.iov_base = instance->iov_buffer;
+ iov_recv.iov_len = KNET_MAX_PACKET_SIZE;
+
+ msg_hdr.msg_name = &system_from;
+ msg_hdr.msg_namelen = sizeof (struct sockaddr_storage);
+ msg_hdr.msg_iov = &iov_recv;
+ msg_hdr.msg_iovlen = 1;
+#ifdef HAVE_MSGHDR_CONTROL
+ msg_hdr.msg_control = 0;
+#endif
+#ifdef HAVE_MSGHDR_CONTROLLEN
+ msg_hdr.msg_controllen = 0;
+#endif
+#ifdef HAVE_MSGHDR_FLAGS
+ msg_hdr.msg_flags = 0;
+#endif
+#ifdef HAVE_MSGHDR_ACCRIGHTS
+ msg_hdr.msg_accrights = NULL;
+#endif
+#ifdef HAVE_MSGHDR_ACCRIGHTSLEN
+ msg_hdr.msg_accrightslen = 0;
+#endif
+
+ msg_len = recvmsg (fd, &msg_hdr, MSG_NOSIGNAL | MSG_DONTWAIT);
+ if (msg_len <= 0) {
+ return (0);
+ }
+
+ truncated_packet = 0;
+
+#ifdef HAVE_MSGHDR_FLAGS
+ if (msg_hdr.msg_flags & MSG_TRUNC) {
+ truncated_packet = 1;
+ }
+#else
+ /*
+ * We don't have MSGHDR_FLAGS, but we can (hopefully) safely make assumption that
+ * if bytes_received == KNET_MAX_PACKET_SIZE then packet is truncated
+ */
+ if (bytes_received == KNET_MAX_PACKET_SIZE) {
+ truncated_packet = 1;
+ }
+#endif
+
+ if (truncated_packet) {
+ knet_log_printf(instance->totemknet_log_level_error,
+ "Received too big message. This may be because something bad is happening"
+ "on the network (attack?), or you tried join more nodes than corosync is"
+ "compiled with (%u) or bug in the code (bad estimation of "
+ "the KNET_MAX_PACKET_SIZE). Dropping packet.", PROCESSOR_COUNT_MAX);
+ return (0);
+ }
+
+ /*
+ * Handle incoming message
+ */
+ instance->totemknet_deliver_fn (
+ instance->context,
+ instance->iov_buffer,
+ msg_len,
+ &system_from);
+
+ return (0);
+}
+
+static void timer_function_netif_check_timeout (
+ void *data)
+{
+ struct totemknet_instance *instance = (struct totemknet_instance *)data;
+ int i;
+ int res = 0;
+
+ for (i=0; i < INTERFACE_MAX; i++) {
+ if (!instance->totem_config->interfaces[i].configured) {
+ continue;
+ }
+ res = instance->totemknet_iface_change_fn (instance->context,
+ &instance->my_ids[i],
+ i);
+ }
+ if (res != 0) {
+ /* This is only called at startup, so we can quit here.
+ Refresh takes a different path */
+ corosync_exit_error(COROSYNC_DONE_MAINCONFIGREAD);
+ }
+}
+
+static void knet_set_access_list_config(struct totemknet_instance *instance)
+{
+#ifdef HAVE_KNET_ACCESS_LIST
+ uint32_t value;
+ cs_error_t err;
+
+ value = instance->totem_config->block_unlisted_ips;
+ knet_log_printf (LOGSYS_LEVEL_DEBUG, "knet_enable access list: %d", value);
+
+ err = knet_handle_enable_access_lists(instance->knet_handle, value);
+ if (err) {
+ KNET_LOGSYS_PERROR(errno, LOGSYS_LEVEL_WARNING, "knet_handle_enable_access_lists failed");
+ }
+#endif
+}
+
+void totemknet_configure_log_level()
+{
+ int logsys_log_mode;
+ int knet_log_mode = KNET_LOG_INFO;
+ uint8_t s;
+ int err;
+
+ if (!global_instance || !global_instance->knet_handle) {
+ return;
+ }
+
+ /* Reconfigure logging level */
+ logsys_log_mode = logsys_config_debug_get("KNET");
+
+ switch (logsys_log_mode) {
+ case LOGSYS_DEBUG_OFF:
+ knet_log_mode = KNET_LOG_INFO;
+ break;
+ case LOGSYS_DEBUG_ON:
+ knet_log_mode = KNET_LOG_DEBUG;
+ break;
+ case LOGSYS_DEBUG_TRACE:
+#ifdef KNET_LOG_TRACE
+ knet_log_mode = KNET_LOG_TRACE;
+#else
+ knet_log_mode = KNET_LOG_DEBUG;
+#endif
+ break;
+ }
+ log_printf (LOGSYS_LEVEL_DEBUG, "totemknet setting log level %s", knet_log_get_loglevel_name(knet_log_mode));
+ err = 0;
+ for (s = 0; s<KNET_MAX_SUBSYSTEMS; s++) {
+ err = knet_log_set_loglevel(global_instance->knet_handle, s, knet_log_mode);
+ }
+
+ /* If one fails, they all fail. no point in issuing KNET_MAX_SUBSYSTEMS errors */
+ if (err) {
+ log_printf (LOGSYS_LEVEL_ERROR, "totemknet failed to set log level: %s", strerror(errno));
+ }
+}
+
+
+/* NOTE: this relies on the fact that totem_reload_notify() is called first */
+static void totemknet_refresh_config(
+ int32_t event,
+ const char *key_name,
+ struct icmap_notify_value new_val,
+ struct icmap_notify_value old_val,
+ void *user_data)
+{
+ uint8_t reloading;
+ int after_reload;
+ uint32_t link_no;
+ size_t num_nodes;
+ knet_node_id_t host_ids[KNET_MAX_HOST];
+ int i;
+ int err;
+ struct totemknet_instance *instance = (struct totemknet_instance *)user_data;
+
+ ENTER();
+
+ /*
+ * If a full reload is in progress then don't do anything until it's done and
+ * can reconfigure it all atomically
+ */
+ if (icmap_get_uint8("config.totemconfig_reload_in_progress", &reloading) == CS_OK && reloading) {
+ return;
+ }
+
+ after_reload = (strcmp(key_name, "config.totemconfig_reload_in_progress") == 0);
+
+ knet_set_access_list_config(instance);
+
+ if (strcmp(key_name, "totem.knet_pmtud_interval") == 0 || after_reload) {
+ knet_log_printf (LOGSYS_LEVEL_DEBUG, "knet_pmtud_interval now %u",
+ instance->totem_config->knet_pmtud_interval);
+ err = knet_handle_pmtud_setfreq(instance->knet_handle, instance->totem_config->knet_pmtud_interval);
+ if (err) {
+ KNET_LOGSYS_PERROR(errno, LOGSYS_LEVEL_WARNING, "knet_handle_pmtud_setfreq failed");
+ }
+ }
+
+ if (strcmp(key_name, "totem.knet_mtu") == 0 || after_reload) {
+ knet_log_printf (LOGSYS_LEVEL_DEBUG, "knet_mtu now %u", instance->totem_config->knet_mtu);
+ err = knet_handle_pmtud_set(instance->knet_handle, instance->totem_config->knet_mtu);
+ if (err) {
+ KNET_LOGSYS_PERROR(errno, LOGSYS_LEVEL_WARNING, "knet_handle_pmtud failed");
+ }
+ }
+
+ /* Configure link parameters for each node */
+ err = knet_host_get_host_list(instance->knet_handle, host_ids, &num_nodes);
+ if (err != 0) {
+ KNET_LOGSYS_PERROR(errno, LOGSYS_LEVEL_ERROR, "knet_host_get_host_list failed");
+ }
+
+ for (i=0; i<num_nodes; i++) {
+ for (link_no = 0; link_no < INTERFACE_MAX; link_no++) {
+ if (host_ids[i] == instance->our_nodeid || !instance->totem_config->interfaces[link_no].configured) {
+ continue;
+ }
+
+ err = knet_link_set_ping_timers(instance->knet_handle, host_ids[i], link_no,
+ instance->totem_config->interfaces[link_no].knet_ping_interval,
+ instance->totem_config->interfaces[link_no].knet_ping_timeout,
+ instance->totem_config->interfaces[link_no].knet_ping_precision);
+ if (err) {
+ KNET_LOGSYS_PERROR(errno, LOGSYS_LEVEL_ERROR, "knet_link_set_ping_timers for node " CS_PRI_NODE_ID " link %d failed", host_ids[i], link_no);
+ }
+ err = knet_link_set_pong_count(instance->knet_handle, host_ids[i], link_no,
+ instance->totem_config->interfaces[link_no].knet_pong_count);
+ if (err) {
+ KNET_LOGSYS_PERROR(errno, LOGSYS_LEVEL_ERROR, "knet_link_set_pong_count for node " CS_PRI_NODE_ID " link %d failed",host_ids[i], link_no);
+ }
+ err = knet_link_set_priority(instance->knet_handle, host_ids[i], link_no,
+ instance->totem_config->interfaces[link_no].knet_link_priority);
+ if (err) {
+ KNET_LOGSYS_PERROR(errno, LOGSYS_LEVEL_ERROR, "knet_link_set_priority for node " CS_PRI_NODE_ID " link %d failed", host_ids[i], link_no);
+ }
+
+ }
+ }
+
+ /* Log levels get reconfigured from logconfig.c as that happens last in the reload */
+ LEAVE();
+}
+
+static void totemknet_add_config_notifications(struct totemknet_instance *instance)
+{
+ icmap_track_t icmap_track_totem = NULL;
+ icmap_track_t icmap_track_reload = NULL;
+
+ ENTER();
+
+ icmap_track_add("totem.",
+ ICMAP_TRACK_ADD | ICMAP_TRACK_DELETE | ICMAP_TRACK_MODIFY | ICMAP_TRACK_PREFIX,
+ totemknet_refresh_config,
+ instance,
+ &icmap_track_totem);
+
+ icmap_track_add("config.totemconfig_reload_in_progress",
+ ICMAP_TRACK_ADD | ICMAP_TRACK_MODIFY,
+ totemknet_refresh_config,
+ instance,
+ &icmap_track_reload);
+
+ LEAVE();
+}
+
+static int totemknet_is_crypto_enabled(const struct totemknet_instance *instance)
+{
+
+ return (!(strcmp(instance->totem_config->crypto_cipher_type, "none") == 0 &&
+ strcmp(instance->totem_config->crypto_hash_type, "none") == 0));
+
+}
+
+static int totemknet_set_knet_crypto(struct totemknet_instance *instance)
+{
+ struct knet_handle_crypto_cfg crypto_cfg;
+ int res;
+
+ /* These have already been validated */
+ memcpy(crypto_cfg.crypto_model, instance->totem_config->crypto_model, sizeof(crypto_cfg.crypto_model));
+ memcpy(crypto_cfg.crypto_cipher_type, instance->totem_config->crypto_cipher_type, sizeof(crypto_cfg.crypto_model));
+ memcpy(crypto_cfg.crypto_hash_type, instance->totem_config->crypto_hash_type, sizeof(crypto_cfg.crypto_model));
+ memcpy(crypto_cfg.private_key, instance->totem_config->private_key, instance->totem_config->private_key_len);
+ crypto_cfg.private_key_len = instance->totem_config->private_key_len;
+
+#ifdef HAVE_KNET_CRYPTO_RECONF
+
+ knet_log_printf(LOGSYS_LEVEL_DEBUG, "Configuring crypto %s/%s/%s on index %d",
+ crypto_cfg.crypto_model,
+ crypto_cfg.crypto_cipher_type,
+ crypto_cfg.crypto_hash_type,
+ instance->totem_config->crypto_index
+ );
+
+ /* If crypto is being disabled we need to explicitly allow cleartext traffic in knet */
+ if (!totemknet_is_crypto_enabled(instance)) {
+ res = knet_handle_crypto_rx_clear_traffic(instance->knet_handle, KNET_CRYPTO_RX_ALLOW_CLEAR_TRAFFIC);
+ if (res) {
+ knet_log_printf(LOGSYS_LEVEL_ERROR, "knet_handle_crypto_rx_clear_traffic(ALLOW) failed %s", strerror(errno));
+ }
+ }
+
+ /* use_config will be called later when all nodes are synced */
+ res = knet_handle_crypto_set_config(instance->knet_handle, &crypto_cfg, instance->totem_config->crypto_index);
+ if (res == -1) {
+ knet_log_printf(LOGSYS_LEVEL_ERROR, "knet_handle_crypto_set_config (index %d) failed: %s", instance->totem_config->crypto_index, strerror(errno));
+ goto exit_error;
+ }
+ if (res == -2) {
+ knet_log_printf(LOGSYS_LEVEL_ERROR, "knet_handle_crypto_set_config (index %d) failed: -2", instance->totem_config->crypto_index);
+ goto exit_error;
+ }
+#else
+ knet_log_printf(LOGSYS_LEVEL_DEBUG, "Configuring crypto %s/%s/%s",
+ crypto_cfg.crypto_model,
+ crypto_cfg.crypto_cipher_type,
+ crypto_cfg.crypto_hash_type
+ );
+
+ res = knet_handle_crypto(instance->knet_handle, &crypto_cfg);
+ if (res == -1) {
+ knet_log_printf(LOGSYS_LEVEL_ERROR, "knet_handle_crypto failed: %s", strerror(errno));
+ goto exit_error;
+ }
+ if (res == -2) {
+ knet_log_printf(LOGSYS_LEVEL_ERROR, "knet_handle_crypto failed: -2");
+ goto exit_error;
+ }
+#endif
+
+
+exit_error:
+ return res;
+}
+
+/*
+ * Create an instance
+ */
+int totemknet_initialize (
+ qb_loop_t *poll_handle,
+ void **knet_context,
+ struct totem_config *totem_config,
+ totemsrp_stats_t *stats,
+ void *context,
+
+ int (*deliver_fn) (
+ void *context,
+ const void *msg,
+ unsigned int msg_len,
+ const struct sockaddr_storage *system_from),
+
+ int (*iface_change_fn) (
+ void *context,
+ const struct totem_ip_address *iface_address,
+ unsigned int link_no),
+
+ void (*mtu_changed) (
+ void *context,
+ int net_mtu),
+
+ void (*target_set_completed) (
+ void *context))
+{
+ struct totemknet_instance *instance;
+ char *tmp_str;
+ int8_t channel=0;
+ int allow_knet_handle_fallback=0;
+ int res;
+ int i;
+
+ instance = malloc (sizeof (struct totemknet_instance));
+ if (instance == NULL) {
+ return (-1);
+ }
+
+ totemknet_instance_initialize (instance);
+
+ instance->totem_config = totem_config;
+
+ /*
+ * Configure logging
+ */
+ instance->totemknet_log_level_security = 1; //totem_config->totem_logging_configuration.log_level_security;
+ instance->totemknet_log_level_error = totem_config->totem_logging_configuration.log_level_error;
+ instance->totemknet_log_level_warning = totem_config->totem_logging_configuration.log_level_warning;
+ instance->totemknet_log_level_notice = totem_config->totem_logging_configuration.log_level_notice;
+ instance->totemknet_log_level_debug = totem_config->totem_logging_configuration.log_level_debug;
+ instance->totemknet_subsys_id = totem_config->totem_logging_configuration.log_subsys_id;
+ instance->totemknet_log_printf = totem_config->totem_logging_configuration.log_printf;
+
+ instance->knet_subsys_id = _logsys_subsys_create("KNET", "libknet.h");
+
+ /*
+ * Initialize local variables for totemknet
+ */
+
+ instance->our_nodeid = instance->totem_config->node_id;
+
+ for (i=0; i< INTERFACE_MAX; i++) {
+ totemip_copy(&instance->my_ids[i], &totem_config->interfaces[i].bindnet);
+ instance->my_ids[i].nodeid = instance->our_nodeid;
+ instance->ip_port[i] = totem_config->interfaces[i].ip_port;
+
+ /* Needed for totemsrp */
+ totem_config->interfaces[i].boundto.nodeid = instance->our_nodeid;
+ }
+
+ instance->poll_handle = poll_handle;
+
+ instance->context = context;
+ instance->totemknet_deliver_fn = deliver_fn;
+
+ instance->totemknet_iface_change_fn = iface_change_fn;
+
+ instance->totemknet_mtu_changed = mtu_changed;
+
+ instance->totemknet_target_set_completed = target_set_completed;
+
+ instance->loopback_link = 0;
+
+ res = pipe(instance->logpipes);
+ if (res == -1) {
+ KNET_LOGSYS_PERROR(errno, LOGSYS_LEVEL_CRIT, "failed to create pipe for instance->logpipes");
+ goto exit_error;
+ }
+ if (fcntl(instance->logpipes[0], F_SETFL, O_NONBLOCK) == -1 ||
+ fcntl(instance->logpipes[1], F_SETFL, O_NONBLOCK) == -1) {
+ KNET_LOGSYS_PERROR(errno, LOGSYS_LEVEL_CRIT, "failed to set O_NONBLOCK flag for instance->logpipes");
+ goto exit_error;
+ }
+
+ if (icmap_get_string("system.allow_knet_handle_fallback", &tmp_str) == CS_OK) {
+ if (strcmp(tmp_str, "yes") == 0) {
+ allow_knet_handle_fallback = 1;
+ }
+ free(tmp_str);
+ }
+
+#if defined(KNET_API_VER) && (KNET_API_VER == 2)
+ instance->knet_handle = knet_handle_new(instance->totem_config->node_id, instance->logpipes[1], KNET_LOG_DEBUG, KNET_HANDLE_FLAG_PRIVILEGED);
+#else
+ instance->knet_handle = knet_handle_new(instance->totem_config->node_id, instance->logpipes[1], KNET_LOG_DEBUG);
+#endif
+
+ if (allow_knet_handle_fallback && !instance->knet_handle && errno == ENAMETOOLONG) {
+ KNET_LOGSYS_PERROR(errno, LOGSYS_LEVEL_WARNING, "knet_handle_new failed, trying unprivileged");
+#if defined(KNET_API_VER) && (KNET_API_VER == 2)
+ instance->knet_handle = knet_handle_new(instance->totem_config->node_id, instance->logpipes[1], KNET_LOG_DEBUG, 0);
+#else
+ instance->knet_handle = knet_handle_new_ex(instance->totem_config->node_id, instance->logpipes[1], KNET_LOG_DEBUG, 0);
+#endif
+ }
+
+ if (!instance->knet_handle) {
+ KNET_LOGSYS_PERROR(errno, LOGSYS_LEVEL_CRIT, "knet_handle_new failed");
+ goto exit_error;
+ }
+
+ knet_set_access_list_config(instance);
+
+ res = knet_handle_pmtud_setfreq(instance->knet_handle, instance->totem_config->knet_pmtud_interval);
+ if (res) {
+ KNET_LOGSYS_PERROR(errno, LOGSYS_LEVEL_WARNING, "knet_handle_pmtud_setfreq failed");
+ }
+ res = knet_handle_pmtud_set(instance->knet_handle, instance->totem_config->knet_mtu);
+ if (res) {
+ KNET_LOGSYS_PERROR(errno, LOGSYS_LEVEL_WARNING, "knet_handle_pmtud_set failed");
+ }
+ res = knet_handle_enable_filter(instance->knet_handle, instance, dst_host_filter_callback_fn);
+ if (res) {
+ KNET_LOGSYS_PERROR(errno, LOGSYS_LEVEL_WARNING, "knet_handle_enable_filter failed");
+ }
+ res = knet_handle_enable_sock_notify(instance->knet_handle, instance, socket_error_callback_fn);
+ if (res) {
+ KNET_LOGSYS_PERROR(errno, LOGSYS_LEVEL_WARNING, "knet_handle_enable_sock_notify failed");
+ }
+ res = knet_host_enable_status_change_notify(instance->knet_handle, instance, host_change_callback_fn);
+ if (res) {
+ KNET_LOGSYS_PERROR(errno, LOGSYS_LEVEL_WARNING, "knet_host_enable_status_change_notify failed");
+ }
+ res = knet_handle_enable_pmtud_notify(instance->knet_handle, instance, pmtu_change_callback_fn);
+ if (res) {
+ KNET_LOGSYS_PERROR(errno, LOGSYS_LEVEL_WARNING, "knet_handle_enable_pmtud_notify failed");
+ }
+ global_instance = instance;
+
+ /* Setup knet logging level */
+ totemknet_configure_log_level();
+
+ /* Get an fd into knet */
+ instance->knet_fd = 0;
+ res = knet_handle_add_datafd(instance->knet_handle, &instance->knet_fd, &channel);
+ if (res) {
+ knet_log_printf(LOG_DEBUG, "knet_handle_add_datafd failed: %s", strerror(errno));
+ goto exit_error;
+ }
+
+ /* Enable crypto if requested */
+#ifdef HAVE_KNET_CRYPTO_RECONF
+ if (totemknet_is_crypto_enabled(instance)) {
+ res = totemknet_set_knet_crypto(instance);
+ if (res == 0) {
+ res = knet_handle_crypto_use_config(instance->knet_handle, totem_config->crypto_index);
+ if (res) {
+ knet_log_printf(LOG_DEBUG, "knet_handle_crypto_use_config failed: %s", strerror(errno));
+ goto exit_error;
+ }
+ } else {
+ knet_log_printf(LOG_DEBUG, "Failed to set up knet crypto");
+ goto exit_error;
+ }
+ res = knet_handle_crypto_rx_clear_traffic(instance->knet_handle, KNET_CRYPTO_RX_DISALLOW_CLEAR_TRAFFIC);
+ if (res) {
+ knet_log_printf(LOG_DEBUG, "knet_handle_crypto_rx_clear_traffic (DISALLOW) failed: %s", strerror(errno));
+ goto exit_error;
+ }
+
+ } else {
+ res = knet_handle_crypto_rx_clear_traffic(instance->knet_handle, KNET_CRYPTO_RX_ALLOW_CLEAR_TRAFFIC);
+ if (res) {
+ knet_log_printf(LOG_DEBUG, "knet_handle_crypto_rx_clear_traffic (ALLOW) failed: %s", strerror(errno));
+ goto exit_error;
+ }
+ }
+#else
+ if (totemknet_is_crypto_enabled(instance)) {
+ res = totemknet_set_knet_crypto(instance);
+ if (res) {
+ knet_log_printf(LOG_DEBUG, "Failed to set up knet crypto");
+ goto exit_error;
+ }
+ }
+#endif
+
+ /* Set up compression */
+ if (strcmp(totem_config->knet_compression_model, "none") != 0) {
+ /* Not fatal, but will log */
+ (void)totemknet_configure_compression(instance, totem_config);
+ }
+
+ knet_handle_setfwd(instance->knet_handle, 1);
+
+ instance->link_mode = KNET_LINK_POLICY_PASSIVE;
+ if (strcmp(instance->totem_config->link_mode, "active")==0) {
+ instance->link_mode = KNET_LINK_POLICY_ACTIVE;
+ }
+ if (strcmp(instance->totem_config->link_mode, "rr")==0) {
+ instance->link_mode = KNET_LINK_POLICY_RR;
+ }
+
+ for (i=0; i<INTERFACE_MAX; i++) {
+ instance->link_status[i] = malloc(CFG_INTERFACE_STATUS_MAX_LEN);
+ if (!instance->link_status[i]) {
+ goto exit_error;
+ }
+ }
+
+ qb_loop_poll_add (instance->poll_handle,
+ QB_LOOP_MED,
+ instance->logpipes[0],
+ POLLIN, instance, log_deliver_fn);
+
+ qb_loop_poll_add (instance->poll_handle,
+ QB_LOOP_HIGH,
+ instance->knet_fd,
+ POLLIN, instance, data_deliver_fn);
+
+ /*
+ * Upper layer isn't ready to receive message because it hasn't
+ * initialized yet. Add short timer to check the interfaces.
+ */
+ qb_loop_timer_add (instance->poll_handle,
+ QB_LOOP_MED,
+ 100*QB_TIME_NS_IN_MSEC,
+ (void *)instance,
+ timer_function_netif_check_timeout,
+ &instance->timer_netif_check_timeout);
+
+ totemknet_start_merge_detect_timeout(instance);
+
+ /* Start listening for config changes */
+ totemknet_add_config_notifications(instance);
+
+ /* Add stats keys to icmap */
+ stats_knet_add_handle();
+
+ knet_log_printf (LOGSYS_LEVEL_INFO, "totemknet initialized");
+ *knet_context = instance;
+
+ return (0);
+
+exit_error:
+ log_flush_messages(instance);
+ free(instance);
+ return (-1);
+}
+
+void *totemknet_buffer_alloc (void)
+{
+ /* Need to have space for a message AND a struct mcast in case of encapsulated messages */
+ return malloc(KNET_MAX_PACKET_SIZE + 512);
+}
+
+void totemknet_buffer_release (void *ptr)
+{
+ return free (ptr);
+}
+
+int totemknet_processor_count_set (
+ void *knet_context,
+ int processor_count)
+{
+ return (0);
+}
+
+int totemknet_recv_flush (void *knet_context)
+{
+ return (0);
+}
+
+int totemknet_send_flush (void *knet_context)
+{
+ return (0);
+}
+
+int totemknet_token_send (
+ void *knet_context,
+ const void *msg,
+ unsigned int msg_len)
+{
+ struct totemknet_instance *instance = (struct totemknet_instance *)knet_context;
+ int res = 0;
+
+ ucast_sendmsg (instance, &instance->token_target, msg, msg_len);
+
+ return (res);
+}
+int totemknet_mcast_flush_send (
+ void *knet_context,
+ const void *msg,
+ unsigned int msg_len)
+{
+ struct totemknet_instance *instance = (struct totemknet_instance *)knet_context;
+ int res = 0;
+
+ mcast_sendmsg (instance, msg, msg_len, 0);
+
+ return (res);
+}
+
+int totemknet_mcast_noflush_send (
+ void *knet_context,
+ const void *msg,
+ unsigned int msg_len)
+{
+ struct totemknet_instance *instance = (struct totemknet_instance *)knet_context;
+ int res = 0;
+
+ mcast_sendmsg (instance, msg, msg_len, 1);
+
+ return (res);
+}
+
+
+extern int totemknet_iface_check (void *knet_context)
+{
+ struct totemknet_instance *instance = (struct totemknet_instance *)knet_context;
+ int res = 0;
+
+ knet_log_printf(LOG_DEBUG, "totemknet: iface_check");
+
+ return (res);
+}
+
+extern void totemknet_net_mtu_adjust (void *knet_context, struct totem_config *totem_config)
+{
+ struct totemknet_instance *instance = (struct totemknet_instance *)knet_context;
+
+ knet_log_printf(LOG_DEBUG, "totemknet: Returning MTU of %d", totem_config->net_mtu);
+}
+
+int totemknet_token_target_set (
+ void *knet_context,
+ unsigned int nodeid)
+{
+ struct totemknet_instance *instance = (struct totemknet_instance *)knet_context;
+ int res = 0;
+
+ instance->token_target.nodeid = nodeid;
+
+ instance->totemknet_target_set_completed (instance->context);
+
+ return (res);
+}
+
+extern int totemknet_recv_mcast_empty (
+ void *knet_context)
+{
+ struct totemknet_instance *instance = (struct totemknet_instance *)knet_context;
+ unsigned int res;
+ struct sockaddr_storage system_from;
+ struct msghdr msg_hdr;
+ struct iovec iov_recv;
+ struct pollfd ufd;
+ int nfds;
+ int msg_processed = 0;
+
+ iov_recv.iov_base = instance->iov_buffer;
+ iov_recv.iov_len = KNET_MAX_PACKET_SIZE;
+
+ msg_hdr.msg_name = &system_from;
+ msg_hdr.msg_namelen = sizeof (struct sockaddr_storage);
+ msg_hdr.msg_iov = &iov_recv;
+ msg_hdr.msg_iovlen = 1;
+#ifdef HAVE_MSGHDR_CONTROL
+ msg_hdr.msg_control = 0;
+#endif
+#ifdef HAVE_MSGHDR_CONTROLLEN
+ msg_hdr.msg_controllen = 0;
+#endif
+#ifdef HAVE_MSGHDR_FLAGS
+ msg_hdr.msg_flags = 0;
+#endif
+#ifdef HAVE_MSGHDR_ACCRIGHTS
+ msg_msg_hdr.msg_accrights = NULL;
+#endif
+#ifdef HAVE_MSGHDR_ACCRIGHTSLEN
+ msg_msg_hdr.msg_accrightslen = 0;
+#endif
+
+ do {
+ ufd.fd = instance->knet_fd;
+ ufd.events = POLLIN;
+ nfds = poll (&ufd, 1, 0);
+ if (nfds == 1 && ufd.revents & POLLIN) {
+ res = recvmsg (instance->knet_fd, &msg_hdr, MSG_NOSIGNAL | MSG_DONTWAIT);
+ if (res != -1) {
+ msg_processed = 1;
+ } else {
+ msg_processed = -1;
+ }
+ }
+ } while (nfds == 1);
+
+ return (msg_processed);
+}
+
+int totemknet_iface_set (void *knet_context,
+ const struct totem_ip_address *local_addr,
+ unsigned short ip_port,
+ unsigned int iface_no)
+{
+ struct totemknet_instance *instance = (struct totemknet_instance *)knet_context;
+
+ totemip_copy(&instance->my_ids[iface_no], local_addr);
+
+ knet_log_printf(LOG_INFO, "Configured link number %d: local addr: %s, port=%d", iface_no, totemip_print(local_addr), ip_port);
+
+ instance->ip_port[iface_no] = ip_port;
+
+ return 0;
+}
+
+
+int totemknet_member_add (
+ void *knet_context,
+ const struct totem_ip_address *local,
+ const struct totem_ip_address *member,
+ int link_no)
+{
+ struct totemknet_instance *instance = (struct totemknet_instance *)knet_context;
+ int err;
+ int port = instance->ip_port[link_no];
+ struct sockaddr_storage remote_ss;
+ struct sockaddr_storage local_ss;
+ int addrlen;
+ int i;
+ int host_found = 0;
+ knet_node_id_t host_ids[KNET_MAX_HOST];
+ size_t num_host_ids;
+
+ /* Only create 1 loopback link and use link 0 */
+ if (member->nodeid == instance->our_nodeid) {
+ if (!instance->loopback_link) {
+ link_no = 0;
+ instance->loopback_link = 1;
+ } else {
+ /* Already done */
+ return 0;
+ }
+ }
+
+ knet_log_printf (LOGSYS_LEVEL_DEBUG, "knet: member_add: " CS_PRI_NODE_ID " (%s), link=%d", member->nodeid, totemip_print(member), link_no);
+ knet_log_printf (LOGSYS_LEVEL_DEBUG, "knet: local: " CS_PRI_NODE_ID " (%s)", local->nodeid, totemip_print(local));
+
+
+ /* Only add the host if it doesn't already exist in knet */
+ err = knet_host_get_host_list(instance->knet_handle, host_ids, &num_host_ids);
+ if (err) {
+ KNET_LOGSYS_PERROR(errno, LOGSYS_LEVEL_ERROR, "knet_host_get_host_list");
+ return -1;
+ }
+ for (i=0; i<num_host_ids; i++) {
+ if (host_ids[i] == member->nodeid) {
+ host_found = 1;
+ }
+ }
+
+ if (!host_found) {
+ err = knet_host_add(instance->knet_handle, member->nodeid);
+ if (err != 0 && errno != EEXIST) {
+ KNET_LOGSYS_PERROR(errno, LOGSYS_LEVEL_ERROR, "knet_host_add");
+ return -1;
+ }
+ } else {
+ knet_log_printf (LOGSYS_LEVEL_DEBUG, "nodeid " CS_PRI_NODE_ID " already added", member->nodeid);
+ }
+
+
+ if (err == 0) {
+ if (knet_host_set_policy(instance->knet_handle, member->nodeid, instance->link_mode)) {
+ KNET_LOGSYS_PERROR(errno, LOGSYS_LEVEL_ERROR, "knet_set_policy failed");
+ return -1;
+ }
+ }
+
+ memset(&local_ss, 0, sizeof(local_ss));
+ memset(&remote_ss, 0, sizeof(remote_ss));
+ /* Casts to remove const */
+ totemip_totemip_to_sockaddr_convert((struct totem_ip_address *)member, port, &remote_ss, &addrlen);
+ totemip_totemip_to_sockaddr_convert((struct totem_ip_address *)local, port, &local_ss, &addrlen);
+
+ if (member->nodeid == instance->our_nodeid) {
+ knet_log_printf (LOGSYS_LEVEL_DEBUG, "knet: loopback link is %d\n", link_no);
+
+ err = knet_link_set_config(instance->knet_handle, member->nodeid, link_no,
+ KNET_TRANSPORT_LOOPBACK,
+ &local_ss, &remote_ss, KNET_LINK_FLAG_TRAFFICHIPRIO);
+ }
+ else {
+ err = knet_link_set_config(instance->knet_handle, member->nodeid, link_no,
+ instance->totem_config->interfaces[link_no].knet_transport,
+ &local_ss, &remote_ss, KNET_LINK_FLAG_TRAFFICHIPRIO);
+ }
+ if (err) {
+ KNET_LOGSYS_PERROR(errno, LOGSYS_LEVEL_ERROR, "knet_link_set_config failed");
+ return -1;
+ }
+
+ knet_log_printf (LOGSYS_LEVEL_DEBUG, "knet: member_add: Setting link prio to %d",
+ instance->totem_config->interfaces[link_no].knet_link_priority);
+
+ err = knet_link_set_priority(instance->knet_handle, member->nodeid, link_no,
+ instance->totem_config->interfaces[link_no].knet_link_priority);
+ if (err) {
+ KNET_LOGSYS_PERROR(errno, LOGSYS_LEVEL_ERROR, "knet_link_set_priority for nodeid " CS_PRI_NODE_ID ", link %d failed", member->nodeid, link_no);
+ }
+
+ /*
+ * Ping timeouts may be 0 here for a newly added interface (on a reload),
+ * so we leave this till later, it will get done in totemknet_refresh_config.
+ * For the initial startup, we are all preset and ready to go from here.
+ */
+ if (instance->totem_config->interfaces[link_no].knet_ping_interval != 0) {
+ err = knet_link_set_ping_timers(instance->knet_handle, member->nodeid, link_no,
+ instance->totem_config->interfaces[link_no].knet_ping_interval,
+ instance->totem_config->interfaces[link_no].knet_ping_timeout,
+ instance->totem_config->interfaces[link_no].knet_ping_precision);
+ if (err) {
+ /* Flush logs before reporting this error so that the knet message prints before ours */
+ int saved_errno = errno;
+ log_flush_messages(instance);
+ errno = saved_errno;
+ KNET_LOGSYS_PERROR(errno, LOGSYS_LEVEL_ERROR, "knet_link_set_ping_timers for nodeid " CS_PRI_NODE_ID ", link %d failed", member->nodeid, link_no);
+ return -1;
+ }
+ err = knet_link_set_pong_count(instance->knet_handle, member->nodeid, link_no,
+ instance->totem_config->interfaces[link_no].knet_pong_count);
+ if (err) {
+ /* Flush logs before reporting this error so that the knet message prints before ours */
+ int saved_errno = errno;
+ log_flush_messages(instance);
+ errno = saved_errno;
+ KNET_LOGSYS_PERROR(errno, LOGSYS_LEVEL_ERROR, "knet_link_set_pong_count for nodeid " CS_PRI_NODE_ID ", link %d failed", member->nodeid, link_no);
+ return -1;
+ }
+ }
+
+ err = knet_link_set_enable(instance->knet_handle, member->nodeid, link_no, 1);
+ if (err) {
+ KNET_LOGSYS_PERROR(errno, LOGSYS_LEVEL_ERROR, "knet_link_set_enable for nodeid " CS_PRI_NODE_ID ", link %d failed", member->nodeid, link_no);
+ return -1;
+ }
+
+ /* register stats */
+ stats_knet_add_member(member->nodeid, link_no);
+ return (0);
+}
+
+int totemknet_member_remove (
+ void *knet_context,
+ const struct totem_ip_address *token_target,
+ int link_no)
+{
+ struct totemknet_instance *instance = (struct totemknet_instance *)knet_context;
+ int res;
+ uint8_t link_list[KNET_MAX_LINK];
+ size_t num_links;
+
+ knet_log_printf (LOGSYS_LEVEL_DEBUG, "knet: member_remove: " CS_PRI_NODE_ID ", link=%d", token_target->nodeid, link_no);
+
+ /* Don't remove the link with the loopback on it until we shut down */
+ if (token_target->nodeid == instance->our_nodeid) {
+ return 0;
+ }
+
+ /* Tidy stats */
+ stats_knet_del_member(token_target->nodeid, link_no);
+
+ /* Remove the link first */
+ res = knet_link_set_enable(instance->knet_handle, token_target->nodeid, link_no, 0);
+ if (res != 0) {
+ KNET_LOGSYS_PERROR(errno, LOGSYS_LEVEL_ERROR, "knet_link_set enable(off) for nodeid " CS_PRI_NODE_ID ", link %d failed", token_target->nodeid, link_no);
+ return res;
+ }
+
+ res = knet_link_clear_config(instance->knet_handle, token_target->nodeid, link_no);
+ if (res != 0) {
+ KNET_LOGSYS_PERROR(errno, LOGSYS_LEVEL_ERROR, "knet_link_clear_config for nodeid " CS_PRI_NODE_ID ", link %d failed", token_target->nodeid, link_no);
+ return res;
+ }
+
+ /* If this is the last link, then remove the node */
+ res = knet_link_get_link_list(instance->knet_handle,
+ token_target->nodeid, link_list, &num_links);
+ if (res) {
+ return (0); /* not really failure */
+ }
+
+ if (num_links == 0) {
+ res = knet_host_remove(instance->knet_handle, token_target->nodeid);
+ }
+ return res;
+}
+
+int totemknet_member_list_rebind_ip (
+ void *knet_context)
+{
+ return (0);
+}
+
+
+static int totemknet_configure_compression (
+ struct totemknet_instance *instance,
+ struct totem_config *totem_config)
+{
+ struct knet_handle_compress_cfg compress_cfg;
+ int res = 0;
+
+ assert(strlen(totem_config->knet_compression_model) < sizeof(compress_cfg.compress_model));
+ strcpy(compress_cfg.compress_model, totem_config->knet_compression_model);
+
+ compress_cfg.compress_threshold = totem_config->knet_compression_threshold;
+ compress_cfg.compress_level = totem_config->knet_compression_level;
+
+ res = knet_handle_compress(instance->knet_handle, &compress_cfg);
+ if (res) {
+ KNET_LOGSYS_PERROR(errno, LOGSYS_LEVEL_ERROR, "knet_handle_compress failed");
+ }
+ return res;
+}
+
+int totemknet_reconfigure (
+ void *knet_context,
+ struct totem_config *totem_config)
+{
+ struct totemknet_instance *instance = (struct totemknet_instance *)knet_context;
+ int res = 0;
+
+ (void)totemknet_configure_compression(instance, totem_config);
+
+#ifdef HAVE_LIBNOZZLE
+ /* Set up nozzle device(s). Return code is ignored, because inability
+ * configure nozzle is not fatal problem, errors are logged and
+ * there is not much else we can do */
+ (void)setup_nozzle(instance);
+#endif
+
+ if (totem_config->crypto_changed) {
+ /* Flip crypto_index */
+ totem_config->crypto_index = 3-totem_config->crypto_index;
+ res = totemknet_set_knet_crypto(instance);
+
+ knet_log_printf(LOG_INFO, "kronosnet crypto reconfigured on index %d: %s/%s/%s", totem_config->crypto_index,
+ totem_config->crypto_model,
+ totem_config->crypto_cipher_type,
+ totem_config->crypto_hash_type);
+ }
+ return (res);
+}
+
+
+int totemknet_crypto_reconfigure_phase (
+ void *knet_context,
+ struct totem_config *totem_config,
+ cfg_message_crypto_reconfig_phase_t phase)
+{
+#ifdef HAVE_KNET_CRYPTO_RECONF
+ int res;
+ int config_to_use;
+ int config_to_clear;
+ struct knet_handle_crypto_cfg crypto_cfg;
+ struct totemknet_instance *instance = (struct totemknet_instance *)knet_context;
+
+ knet_log_printf(LOGSYS_LEVEL_DEBUG, "totemknet_crypto_reconfigure_phase %d, index=%d\n", phase, totem_config->crypto_index);
+
+ switch (phase) {
+ case CRYPTO_RECONFIG_PHASE_ACTIVATE:
+ config_to_use = totem_config->crypto_index;
+ if (!totemknet_is_crypto_enabled(instance)) {
+ config_to_use = 0; /* we are clearing it */
+ }
+
+ /* Enable the new config on this node */
+ res = knet_handle_crypto_use_config(instance->knet_handle, config_to_use);
+ if (res == -1) {
+ knet_log_printf(LOGSYS_LEVEL_ERROR, "knet_handle_crypto_use_config %d failed: %s", config_to_use, strerror(errno));
+ }
+ break;
+
+ case CRYPTO_RECONFIG_PHASE_CLEANUP:
+ /*
+ * All nodes should now have the new config. clear the old one out
+ * OR disable crypto entirely if that's what the new config insists on.
+ */
+ config_to_clear = 3-totem_config->crypto_index;
+ knet_log_printf(LOGSYS_LEVEL_DEBUG, "Clearing old knet crypto config %d\n", config_to_clear);
+
+ strcpy(crypto_cfg.crypto_model, "none");
+ strcpy(crypto_cfg.crypto_cipher_type, "none");
+ strcpy(crypto_cfg.crypto_hash_type, "none");
+ res = knet_handle_crypto_set_config(instance->knet_handle, &crypto_cfg, config_to_clear);
+ if (res == -1) {
+ knet_log_printf(LOGSYS_LEVEL_ERROR, "knet_handle_crypto_set_config to clear index %d failed: %s", config_to_clear, strerror(errno));
+ }
+ if (res == -2) {
+ knet_log_printf(LOGSYS_LEVEL_ERROR, "knet_handle_crypto_set_config to clear index %d failed: -2", config_to_clear);
+ }
+
+ /* If crypto is enabled then disable all cleartext reception */
+ if (totemknet_is_crypto_enabled(instance)) {
+ res = knet_handle_crypto_rx_clear_traffic(instance->knet_handle, KNET_CRYPTO_RX_DISALLOW_CLEAR_TRAFFIC);
+ if (res) {
+ knet_log_printf(LOGSYS_LEVEL_ERROR, "knet_handle_crypto_rx_clear_traffic(DISALLOW) failed %s", strerror(errno));
+ }
+ }
+ }
+#endif
+ return 0;
+}
+
+void totemknet_stats_clear (
+ void *knet_context)
+{
+ struct totemknet_instance *instance = (struct totemknet_instance *)knet_context;
+
+ (void) knet_handle_clear_stats(instance->knet_handle, KNET_CLEARSTATS_HANDLE_AND_LINK);
+}
+
+/* For the stats module */
+int totemknet_link_get_status (
+ knet_node_id_t node, uint8_t link_no,
+ struct knet_link_status *status)
+{
+ int res;
+ int ret = CS_OK;
+
+ /* We are probably not using knet */
+ if (!global_instance) {
+ return CS_ERR_NOT_EXIST;
+ }
+
+ if (link_no >= INTERFACE_MAX) {
+ return CS_ERR_NOT_EXIST; /* Invalid link number */
+ }
+
+ res = knet_link_get_status(global_instance->knet_handle, node, link_no, status, sizeof(struct knet_link_status));
+ if (res) {
+ switch (errno) {
+ case EINVAL:
+ ret = CS_ERR_INVALID_PARAM;
+ break;
+ case EBUSY:
+ ret = CS_ERR_BUSY;
+ break;
+ case EDEADLK:
+ ret = CS_ERR_TRY_AGAIN;
+ break;
+ default:
+ ret = CS_ERR_LIBRARY;
+ break;
+ }
+ }
+
+ return (ret);
+}
+
+int totemknet_handle_get_stats (
+ struct knet_handle_stats *stats)
+{
+ int res;
+
+ /* We are probably not using knet */
+ if (!global_instance) {
+ return CS_ERR_NOT_EXIST;
+ }
+
+ res = knet_handle_get_stats(global_instance->knet_handle, stats, sizeof(struct knet_handle_stats));
+ if (res != 0) {
+ return (qb_to_cs_error(-errno));
+ }
+
+ return CS_OK;
+}
+
+static void timer_function_merge_detect_timeout (
+ void *data)
+{
+ struct totemknet_instance *instance = (struct totemknet_instance *)data;
+
+ if (instance->merge_detect_messages_sent_before_timeout == 0) {
+ instance->send_merge_detect_message = 1;
+ }
+
+ instance->merge_detect_messages_sent_before_timeout = 0;
+
+ totemknet_start_merge_detect_timeout(instance);
+}
+
+static void totemknet_start_merge_detect_timeout(
+ void *knet_context)
+{
+ struct totemknet_instance *instance = (struct totemknet_instance *)knet_context;
+
+ qb_loop_timer_add(instance->poll_handle,
+ QB_LOOP_MED,
+ instance->totem_config->merge_timeout * 2 * QB_TIME_NS_IN_MSEC,
+ (void *)instance,
+ timer_function_merge_detect_timeout,
+ &instance->timer_merge_detect_timeout);
+
+}
+
+static void totemknet_stop_merge_detect_timeout(
+ void *knet_context)
+{
+ struct totemknet_instance *instance = (struct totemknet_instance *)knet_context;
+
+ qb_loop_timer_del(instance->poll_handle,
+ instance->timer_merge_detect_timeout);
+}
+
+static void log_flush_messages (void *knet_context)
+{
+ struct pollfd pfd;
+ struct totemknet_instance *instance = (struct totemknet_instance *)knet_context;
+ int cont;
+
+ cont = 1;
+
+ while (cont) {
+ pfd.fd = instance->logpipes[0];
+ pfd.events = POLLIN;
+ pfd.revents = 0;
+
+ if ((poll(&pfd, 1, 0) > 0) &&
+ (pfd.revents & POLLIN) &&
+ (log_deliver_fn(instance->logpipes[0], POLLIN, instance) == 0)) {
+ cont = 1;
+ } else {
+ cont = 0;
+ }
+ }
+}
+
+
+#ifdef HAVE_LIBNOZZLE
+#define NOZZLE_NAME "nozzle.name"
+#define NOZZLE_IPADDR "nozzle.ipaddr"
+#define NOZZLE_PREFIX "nozzle.ipprefix"
+#define NOZZLE_MACADDR "nozzle.macaddr"
+
+#define NOZZLE_CHANNEL 1
+
+
+static char *get_nozzle_script_dir(void *knet_context)
+{
+ struct totemknet_instance *instance = (struct totemknet_instance *)knet_context;
+ char filename[PATH_MAX + FILENAME_MAX + 1];
+ static char updown_dirname[PATH_MAX + FILENAME_MAX + 1];
+ int res;
+ const char *dirname_res;
+
+ /*
+ * Build script directory based on corosync.conf file location
+ */
+ res = snprintf(filename, sizeof(filename), "%s",
+ corosync_get_config_file());
+ if (res >= sizeof(filename)) {
+ knet_log_printf (LOGSYS_LEVEL_DEBUG, "nozzle up/down path too long");
+ return NULL;
+ }
+
+ dirname_res = dirname(filename);
+
+ res = snprintf(updown_dirname, sizeof(updown_dirname), "%s/%s",
+ dirname_res, "updown.d");
+ if (res >= sizeof(updown_dirname)) {
+ knet_log_printf (LOGSYS_LEVEL_DEBUG, "nozzle up/down path too long");
+ return NULL;
+ }
+ return updown_dirname;
+}
+
+/*
+ * Deliberately doesn't return the status as caller doesn't care.
+ * The result will be logged though
+ */
+static void run_nozzle_script(struct totemknet_instance *instance, int type, const char *typename)
+{
+ int res;
+ char *exec_string;
+
+ res = nozzle_run_updown(instance->nozzle_handle, type, &exec_string);
+ if (res == -1 && errno != ENOENT) {
+ knet_log_printf (LOGSYS_LEVEL_INFO, "exec nozzle %s script failed: %s", typename, strerror(errno));
+ } else if (res == -2) {
+ knet_log_printf (LOGSYS_LEVEL_INFO, "nozzle %s script failed", typename);
+ knet_log_printf (LOGSYS_LEVEL_INFO, "%s", exec_string);
+ }
+}
+
+/*
+ * Reparse IP address to add in our node ID
+ * IPv6 addresses must end in '::'
+ * IPv4 addresses must just be valid
+ * '/xx' lengths are optional for IPv6, mandatory for IPv4
+ *
+ * Returns the modified IP address as a string to pass into libnozzle
+ */
+static int reparse_nozzle_ip_address(struct totemknet_instance *instance,
+ const char *input_addr,
+ const char *prefix, int nodeid,
+ char *output_addr, size_t output_len)
+{
+ char *coloncolon;
+ int bits;
+ int max_prefix = 64;
+ uint32_t nodeid_mask;
+ uint32_t addr_mask;
+ uint32_t masked_nodeid;
+ struct in_addr *addr;
+ struct totem_ip_address totemip;
+
+ coloncolon = strstr(input_addr, "::");
+ if (!coloncolon) {
+ max_prefix = 30;
+ }
+
+ bits = atoi(prefix);
+ if (bits < 8 || bits > max_prefix) {
+ knet_log_printf(LOGSYS_LEVEL_ERROR, "nozzle IP address prefix must be >= 8 and <= %d (got %d)", max_prefix, bits);
+ return -1;
+ }
+
+ /* IPv6 is easy */
+ if (coloncolon) {
+ memcpy(output_addr, input_addr, coloncolon-input_addr);
+ sprintf(output_addr + (coloncolon-input_addr), "::%x", nodeid);
+ return 0;
+ }
+
+ /* For IPv4 we need to parse the address into binary, mask off the required bits,
+ * add in the masked_nodeid and 'print' it out again
+ */
+ nodeid_mask = UINT32_MAX & ((1<<(32 - bits)) - 1);
+ addr_mask = UINT32_MAX ^ nodeid_mask;
+ masked_nodeid = nodeid & nodeid_mask;
+
+ if (totemip_parse(&totemip, input_addr, AF_INET)) {
+ knet_log_printf(LOGSYS_LEVEL_ERROR, "Failed to parse IPv4 nozzle IP address");
+ return -1;
+ }
+ addr = (struct in_addr *)&totemip.addr;
+ addr->s_addr &= htonl(addr_mask);
+ addr->s_addr |= htonl(masked_nodeid);
+
+ inet_ntop(AF_INET, addr, output_addr, output_len);
+ return 0;
+}
+
+static int create_nozzle_device(void *knet_context, const char *name,
+ const char *ipaddr, const char *prefix,
+ const char *macaddr)
+{
+ struct totemknet_instance *instance = (struct totemknet_instance *)knet_context;
+ char device_name[IFNAMSIZ+1];
+ size_t size = IFNAMSIZ;
+ int8_t channel = NOZZLE_CHANNEL;
+ nozzle_t nozzle_dev;
+ int nozzle_fd;
+ int res;
+ char *updown_dir;
+ char parsed_ipaddr[INET6_ADDRSTRLEN];
+ char mac[19];
+
+ memset(device_name, 0, size);
+ memset(&mac, 0, sizeof(mac));
+ strncpy(device_name, name, size);
+
+ updown_dir = get_nozzle_script_dir(knet_context);
+ knet_log_printf (LOGSYS_LEVEL_INFO, "nozzle script dir is %s", updown_dir);
+
+ nozzle_dev = nozzle_open(device_name, size, updown_dir);
+ if (!nozzle_dev) {
+ knet_log_printf (LOGSYS_LEVEL_ERROR, "Unable to init nozzle device %s: %s", device_name, strerror(errno));
+ return -1;
+ }
+ instance->nozzle_handle = nozzle_dev;
+
+ if (nozzle_set_mac(nozzle_dev, macaddr) < 0) {
+ knet_log_printf (LOGSYS_LEVEL_ERROR, "Unable to add set nozzle MAC to %s: %s", mac, strerror(errno));
+ goto out_clean;
+ }
+
+ if (reparse_nozzle_ip_address(instance, ipaddr, prefix, instance->our_nodeid, parsed_ipaddr, sizeof(parsed_ipaddr))) {
+ /* Prints its own errors */
+ goto out_clean;
+ }
+ knet_log_printf (LOGSYS_LEVEL_INFO, "Local nozzle IP address is %s / %d", parsed_ipaddr, atoi(prefix));
+ if (nozzle_add_ip(nozzle_dev, parsed_ipaddr, prefix) < 0) {
+ knet_log_printf (LOGSYS_LEVEL_ERROR, "Unable to add set nozzle IP addr to %s/%s: %s", parsed_ipaddr, prefix, strerror(errno));
+ goto out_clean;
+ }
+
+ nozzle_fd = nozzle_get_fd(nozzle_dev);
+ knet_log_printf (LOGSYS_LEVEL_INFO, "Opened '%s' on fd %d", device_name, nozzle_fd);
+
+ res = knet_handle_add_datafd(instance->knet_handle, &nozzle_fd, &channel);
+ if (res != 0) {
+ knet_log_printf (LOGSYS_LEVEL_ERROR, "Unable to add nozzle FD to knet: %s", strerror(errno));
+ goto out_clean;
+ }
+
+ run_nozzle_script(instance, NOZZLE_PREUP, "pre-up");
+
+ res = nozzle_set_up(nozzle_dev);
+ if (res != 0) {
+ knet_log_printf (LOGSYS_LEVEL_ERROR, "Unable to set nozzle interface UP: %s", strerror(errno));
+ goto out_clean;
+ }
+ run_nozzle_script(instance, NOZZLE_UP, "up");
+
+ return 0;
+
+out_clean:
+ nozzle_close(nozzle_dev);
+ return -1;
+}
+
+static int remove_nozzle_device(void *knet_context)
+{
+ struct totemknet_instance *instance = (struct totemknet_instance *)knet_context;
+ int res;
+ int datafd;
+
+ res = knet_handle_get_datafd(instance->knet_handle, NOZZLE_CHANNEL, &datafd);
+ if (res != 0) {
+ knet_log_printf (LOGSYS_LEVEL_ERROR, "Can't find datafd for channel %d: %s", NOZZLE_CHANNEL, strerror(errno));
+ return -1;
+ }
+
+ res = knet_handle_remove_datafd(instance->knet_handle, datafd);
+ if (res != 0) {
+ knet_log_printf (LOGSYS_LEVEL_ERROR, "Can't remove datafd for nozzle channel %d: %s", NOZZLE_CHANNEL, strerror(errno));
+ return -1;
+ }
+
+ run_nozzle_script(instance, NOZZLE_DOWN, "pre-down");
+ res = nozzle_set_down(instance->nozzle_handle);
+ if (res != 0) {
+ knet_log_printf (LOGSYS_LEVEL_ERROR, "Can't set nozzle device down: %s", strerror(errno));
+ return -1;
+ }
+ run_nozzle_script(instance, NOZZLE_POSTDOWN, "post-down");
+
+ res = nozzle_close(instance->nozzle_handle);
+ if (res != 0) {
+ knet_log_printf (LOGSYS_LEVEL_ERROR, "Can't close nozzle device: %s", strerror(errno));
+ return -1;
+ }
+ knet_log_printf (LOGSYS_LEVEL_INFO, "Removed nozzle device");
+ return 0;
+}
+
+static void free_nozzle(struct totemknet_instance *instance)
+{
+ free(instance->nozzle_name);
+ free(instance->nozzle_ipaddr);
+ free(instance->nozzle_prefix);
+ free(instance->nozzle_macaddr);
+
+ instance->nozzle_name = instance->nozzle_ipaddr = instance->nozzle_prefix =
+ instance->nozzle_macaddr = NULL;
+}
+
+static int setup_nozzle(void *knet_context)
+{
+ struct totemknet_instance *instance = (struct totemknet_instance *)knet_context;
+ char *ipaddr_str = NULL;
+ char *name_str = NULL;
+ char *prefix_str = NULL;
+ char *macaddr_str = NULL;
+ char mac[32];
+ int name_res;
+ int macaddr_res;
+ int res = -1;
+
+ /*
+ * Return value ignored on purpose. icmap_get_string changes
+ * ipaddr_str/prefix_str only on success.
+ */
+ (void)icmap_get_string(NOZZLE_IPADDR, &ipaddr_str);
+ (void)icmap_get_string(NOZZLE_PREFIX, &prefix_str);
+ macaddr_res = icmap_get_string(NOZZLE_MACADDR, &macaddr_str);
+ name_res = icmap_get_string(NOZZLE_NAME, &name_str);
+
+ /* Is is being removed? */
+ if (name_res == CS_ERR_NOT_EXIST && instance->nozzle_handle) {
+ remove_nozzle_device(instance);
+ free_nozzle(instance);
+ goto out_free;
+ }
+
+ if (!name_str) {
+ /* no nozzle */
+ goto out_free;
+ }
+
+ if (!ipaddr_str) {
+ knet_log_printf (LOGSYS_LEVEL_ERROR, "No IP address supplied for Nozzle device");
+ goto out_free;
+ }
+
+ if (!prefix_str) {
+ knet_log_printf (LOGSYS_LEVEL_ERROR, "No prefix supplied for Nozzle IP address");
+ goto out_free;
+ }
+
+ if (macaddr_str && strlen(macaddr_str) != 17) {
+ knet_log_printf (LOGSYS_LEVEL_ERROR, "macaddr for nozzle device is not in the correct format '%s'", macaddr_str);
+ goto out_free;
+ }
+ if (!macaddr_str) {
+ macaddr_str = (char*)"54:54:01:00:00:00";
+ }
+
+ if (instance->nozzle_name &&
+ (strcmp(name_str, instance->nozzle_name) == 0) &&
+ (strcmp(ipaddr_str, instance->nozzle_ipaddr) == 0) &&
+ (strcmp(prefix_str, instance->nozzle_prefix) == 0) &&
+ (instance->nozzle_macaddr == NULL ||
+ strcmp(macaddr_str, instance->nozzle_macaddr) == 0)) {
+ /* Nothing has changed */
+ knet_log_printf (LOGSYS_LEVEL_DEBUG, "Nozzle device info not changed");
+ goto out_free;
+ }
+
+ /* Add nodeid into MAC address */
+ memcpy(mac, macaddr_str, 12);
+ snprintf(mac+12, sizeof(mac) - 13, "%02x:%02x",
+ instance->our_nodeid >> 8,
+ instance->our_nodeid & 0xFF);
+ knet_log_printf (LOGSYS_LEVEL_INFO, "Local nozzle MAC address is %s", mac);
+
+ if (name_res == CS_OK && name_str) {
+ /* Reconfigure */
+ if (instance->nozzle_name) {
+ remove_nozzle_device(instance);
+ free_nozzle(instance);
+ }
+
+ res = create_nozzle_device(knet_context, name_str, ipaddr_str, prefix_str,
+ mac);
+
+ instance->nozzle_name = strdup(name_str);
+ instance->nozzle_ipaddr = strdup(ipaddr_str);
+ instance->nozzle_prefix = strdup(prefix_str);
+ instance->nozzle_macaddr = strdup(macaddr_str);
+ if (!instance->nozzle_name || !instance->nozzle_ipaddr ||
+ !instance->nozzle_prefix) {
+ knet_log_printf (LOGSYS_LEVEL_ERROR, "strdup failed in nozzle allocation");
+ /*
+ * This 'free' will cause a complete reconfigure of the device next time we reload
+ * but will also let the the current device keep working until then.
+ * remove_nozzle() only needs the, statically-allocated, nozzle_handle
+ */
+ free_nozzle(instance);
+ }
+ }
+
+out_free:
+ free(name_str);
+ free(ipaddr_str);
+ free(prefix_str);
+ if (macaddr_res == CS_OK) {
+ free(macaddr_str);
+ }
+
+ return res;
+}
+#endif // HAVE_LIBNOZZLE
diff --git a/exec/totemknet.h b/exec/totemknet.h
new file mode 100644
index 0000000..4d4f61e
--- /dev/null
+++ b/exec/totemknet.h
@@ -0,0 +1,159 @@
+/*
+ * Copyright (c) 2005 MontaVista Software, Inc.
+ * Copyright (c) 2006-2011 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Author: Steven Dake (sdake@redhat.com)
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of the MontaVista Software, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef TOTEMKNET_H_DEFINED
+#define TOTEMKNET_H_DEFINED
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <qb/qbloop.h>
+
+#include <corosync/totem/totem.h>
+
+/**
+ * Create an instance
+ */
+extern int totemknet_initialize (
+ qb_loop_t *poll_handle,
+ void **knet_context,
+ struct totem_config *totem_config,
+ totemsrp_stats_t *stats,
+ void *context,
+
+ int (*deliver_fn) (
+ void *context,
+ const void *msg,
+ unsigned int msg_len,
+ const struct sockaddr_storage *system_from),
+
+ int (*iface_change_fn) (
+ void *context,
+ const struct totem_ip_address *iface_address,
+ unsigned int ring_no),
+
+ void (*mtu_changed) (
+ void *context,
+ int net_mtu),
+
+ void (*target_set_completed) (
+ void *context));
+
+extern void *totemknet_buffer_alloc (void);
+
+extern void totemknet_buffer_release (void *ptr);
+
+extern int totemknet_processor_count_set (
+ void *knet_context,
+ int processor_count);
+
+extern int totemknet_token_send (
+ void *knet_context,
+ const void *msg,
+ unsigned int msg_len);
+
+extern int totemknet_mcast_flush_send (
+ void *knet_context,
+ const void *msg,
+ unsigned int msg_len);
+
+extern int totemknet_mcast_noflush_send (
+ void *knet_context,
+ const void *msg,
+ unsigned int msg_len);
+
+extern int totemknet_recv_flush (void *knet_context);
+
+extern int totemknet_send_flush (void *knet_context);
+
+extern int totemknet_iface_check (void *knet_context);
+
+extern int totemknet_finalize (void *knet_context);
+
+extern void totemknet_net_mtu_adjust (void *knet_context, struct totem_config *totem_config);
+
+extern int totemknet_nodestatus_get (void *knet_context, unsigned int nodeid,
+ struct totem_node_status *node_status);
+
+extern int totemknet_ifaces_get (void *net_context,
+ char ***status,
+ unsigned int *iface_count);
+
+extern int totemknet_iface_set (void *net_context,
+ const struct totem_ip_address *local_addr,
+ unsigned short ip_port,
+ unsigned int iface_no);
+
+extern int totemknet_token_target_set (
+ void *knet_context,
+ unsigned int nodeid);
+
+extern int totemknet_crypto_set (
+ void *knet_context,
+ const char *cipher_type,
+ const char *hash_type);
+
+extern int totemknet_recv_mcast_empty (
+ void *knet_context);
+
+extern int totemknet_member_add (
+ void *knet_context,
+ const struct totem_ip_address *local,
+ const struct totem_ip_address *member,
+ int ring_no);
+
+extern int totemknet_member_remove (
+ void *knet_context,
+ const struct totem_ip_address *member,
+ int ring_no);
+
+extern int totemknet_member_set_active (
+ void *knet_context,
+ const struct totem_ip_address *member_ip,
+ int active);
+
+extern int totemknet_reconfigure (
+ void *knet_context,
+ struct totem_config *totem_config);
+
+extern int totemknet_crypto_reconfigure_phase (
+ void *knet_context,
+ struct totem_config *totem_config,
+ cfg_message_crypto_reconfig_phase_t phase);
+
+extern void totemknet_stats_clear (
+ void *knet_context);
+
+extern void totemknet_configure_log_level (void);
+
+#endif /* TOTEMKNET_H_DEFINED */
diff --git a/exec/totemnet.c b/exec/totemnet.c
new file mode 100644
index 0000000..58992e6
--- /dev/null
+++ b/exec/totemnet.c
@@ -0,0 +1,628 @@
+/*
+ * Copyright (c) 2005 MontaVista Software, Inc.
+ * Copyright (c) 2006-2018 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Author: Steven Dake (sdake@redhat.com)
+
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of the MontaVista Software, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include <assert.h>
+
+#include <totemudp.h>
+#include <totemudpu.h>
+#include <totemknet.h>
+#include <totemnet.h>
+#include <qb/qbloop.h>
+
+#define LOGSYS_UTILS_ONLY 1
+#include <corosync/logsys.h>
+
+struct transport {
+ const char *name;
+
+ int (*initialize) (
+ qb_loop_t *loop_pt,
+ void **transport_instance,
+ struct totem_config *totem_config,
+ totemsrp_stats_t *stats,
+ void *context,
+
+ int (*deliver_fn) (
+ void *context,
+ const void *msg,
+ unsigned int msg_len,
+ const struct sockaddr_storage *system_from),
+
+ int (*iface_change_fn) (
+ void *context,
+ const struct totem_ip_address *iface_address,
+ unsigned int ring_no),
+
+ void (*mtu_changed) (
+ void *context,
+ int net_mtu),
+
+ void (*target_set_completed) (
+ void *context));
+
+ void *(*buffer_alloc) (void);
+
+ void (*buffer_release) (void *ptr);
+
+ int (*processor_count_set) (
+ void *transport_context,
+ int processor_count);
+
+ int (*token_send) (
+ void *transport_context,
+ const void *msg,
+ unsigned int msg_len);
+
+ int (*mcast_flush_send) (
+ void *transport_context,
+ const void *msg,
+ unsigned int msg_len);
+
+
+ int (*mcast_noflush_send) (
+ void *transport_context,
+ const void *msg,
+ unsigned int msg_len);
+
+ int (*recv_flush) (void *transport_context);
+
+ int (*send_flush) (void *transport_context);
+
+ int (*iface_check) (void *transport_context);
+
+ int (*finalize) (void *transport_context);
+
+ void (*net_mtu_adjust) (void *transport_context, struct totem_config *totem_config);
+
+ const char *(*iface_print) (void *transport_context);
+
+ int (*ifaces_get) (
+ void *transport_context,
+ char ***status,
+ unsigned int *iface_count);
+
+ int (*nodestatus_get) (
+ void *transport_context,
+ unsigned int nodeid,
+ struct totem_node_status *node_status);
+
+ int (*token_target_set) (
+ void *transport_context,
+ unsigned int nodeid);
+
+ int (*crypto_set) (
+ void *transport_context,
+ const char *cipher_type,
+ const char *hash_type);
+
+ int (*recv_mcast_empty) (
+ void *transport_context);
+
+ int (*iface_set) (
+ void *transport_context,
+ const struct totem_ip_address *local,
+ unsigned short ip_port,
+ unsigned int ring_no);
+
+ int (*member_add) (
+ void *transport_context,
+ const struct totem_ip_address *local,
+ const struct totem_ip_address *member,
+ int ring_no);
+
+ int (*member_remove) (
+ void *transport_context,
+ const struct totem_ip_address *member,
+ int ring_no);
+
+ int (*member_set_active) (
+ void *transport_context,
+ const struct totem_ip_address *member,
+ int active);
+
+ int (*reconfigure) (
+ void *net_context,
+ struct totem_config *totem_config);
+
+ int (*crypto_reconfigure_phase) (
+ void *net_context,
+ struct totem_config *totem_config,
+ cfg_message_crypto_reconfig_phase_t phase);
+
+ void (*stats_clear) (
+ void *net_context);
+};
+
+struct transport transport_entries[] = {
+ {
+ .name = "UDP/IP Multicast",
+ .initialize = totemudp_initialize,
+ .buffer_alloc = totemudp_buffer_alloc,
+ .buffer_release = totemudp_buffer_release,
+ .processor_count_set = totemudp_processor_count_set,
+ .token_send = totemudp_token_send,
+ .mcast_flush_send = totemudp_mcast_flush_send,
+ .mcast_noflush_send = totemudp_mcast_noflush_send,
+ .recv_flush = totemudp_recv_flush,
+ .send_flush = totemudp_send_flush,
+ .iface_set = totemudp_iface_set,
+ .iface_check = totemudp_iface_check,
+ .finalize = totemudp_finalize,
+ .net_mtu_adjust = totemudp_net_mtu_adjust,
+ .ifaces_get = totemudp_ifaces_get,
+ .nodestatus_get = totemudp_nodestatus_get,
+ .token_target_set = totemudp_token_target_set,
+ .crypto_set = totemudp_crypto_set,
+ .recv_mcast_empty = totemudp_recv_mcast_empty,
+ .member_add = totemudp_member_add,
+ .member_remove = totemudp_member_remove,
+ .reconfigure = totemudp_reconfigure,
+ .crypto_reconfigure_phase = NULL
+ },
+ {
+ .name = "UDP/IP Unicast",
+ .initialize = totemudpu_initialize,
+ .buffer_alloc = totemudpu_buffer_alloc,
+ .buffer_release = totemudpu_buffer_release,
+ .processor_count_set = totemudpu_processor_count_set,
+ .token_send = totemudpu_token_send,
+ .mcast_flush_send = totemudpu_mcast_flush_send,
+ .mcast_noflush_send = totemudpu_mcast_noflush_send,
+ .recv_flush = totemudpu_recv_flush,
+ .send_flush = totemudpu_send_flush,
+ .iface_set = totemudpu_iface_set,
+ .iface_check = totemudpu_iface_check,
+ .finalize = totemudpu_finalize,
+ .net_mtu_adjust = totemudpu_net_mtu_adjust,
+ .ifaces_get = totemudpu_ifaces_get,
+ .nodestatus_get = totemudpu_nodestatus_get,
+ .token_target_set = totemudpu_token_target_set,
+ .crypto_set = totemudpu_crypto_set,
+ .recv_mcast_empty = totemudpu_recv_mcast_empty,
+ .member_add = totemudpu_member_add,
+ .member_remove = totemudpu_member_remove,
+ .reconfigure = totemudpu_reconfigure,
+ .crypto_reconfigure_phase = NULL
+ },
+ {
+ .name = "Kronosnet",
+ .initialize = totemknet_initialize,
+ .buffer_alloc = totemknet_buffer_alloc,
+ .buffer_release = totemknet_buffer_release,
+ .processor_count_set = totemknet_processor_count_set,
+ .token_send = totemknet_token_send,
+ .mcast_flush_send = totemknet_mcast_flush_send,
+ .mcast_noflush_send = totemknet_mcast_noflush_send,
+ .recv_flush = totemknet_recv_flush,
+ .send_flush = totemknet_send_flush,
+ .iface_set = totemknet_iface_set,
+ .iface_check = totemknet_iface_check,
+ .finalize = totemknet_finalize,
+ .net_mtu_adjust = totemknet_net_mtu_adjust,
+ .ifaces_get = totemknet_ifaces_get,
+ .nodestatus_get = totemknet_nodestatus_get,
+ .token_target_set = totemknet_token_target_set,
+ .crypto_set = totemknet_crypto_set,
+ .recv_mcast_empty = totemknet_recv_mcast_empty,
+ .member_add = totemknet_member_add,
+ .member_remove = totemknet_member_remove,
+ .reconfigure = totemknet_reconfigure,
+ .crypto_reconfigure_phase = totemknet_crypto_reconfigure_phase,
+ .stats_clear = totemknet_stats_clear
+ }
+};
+
+struct totemnet_instance {
+ void *transport_context;
+
+ struct transport *transport;
+ void (*totemnet_log_printf) (
+ int level,
+ int subsys,
+ const char *function,
+ const char *file,
+ int line,
+ const char *format,
+ ...)__attribute__((format(printf, 6, 7)));
+
+ int totemnet_subsys_id;
+};
+
+#define log_printf(level, format, args...) \
+do { \
+ instance->totemnet_log_printf ( \
+ level, \
+ instance->totemnet_subsys_id, \
+ __FUNCTION__, __FILE__, __LINE__, \
+ (const char *)format, ##args); \
+} while (0);
+
+static void totemnet_instance_initialize (
+ struct totemnet_instance *instance,
+ struct totem_config *config)
+{
+ int transport;
+
+ instance->totemnet_log_printf = config->totem_logging_configuration.log_printf;
+ instance->totemnet_subsys_id = config->totem_logging_configuration.log_subsys_id;
+
+
+ transport = config->transport_number;
+
+ log_printf (LOGSYS_LEVEL_NOTICE,
+ "Initializing transport (%s).", transport_entries[transport].name);
+
+ instance->transport = &transport_entries[transport];
+}
+
+int totemnet_crypto_set (
+ void *net_context,
+ const char *cipher_type,
+ const char *hash_type)
+{
+ struct totemnet_instance *instance = (struct totemnet_instance *)net_context;
+ int res = 0;
+
+ res = instance->transport->crypto_set (instance->transport_context,
+ cipher_type, hash_type);
+
+ return res;
+}
+
+int totemnet_finalize (
+ void *net_context)
+{
+ struct totemnet_instance *instance = (struct totemnet_instance *)net_context;
+ int res = 0;
+
+ res = instance->transport->finalize (instance->transport_context);
+
+ return (res);
+}
+
+int totemnet_initialize (
+ qb_loop_t *loop_pt,
+ void **net_context,
+ struct totem_config *totem_config,
+ totemsrp_stats_t *stats,
+ void *context,
+
+ int (*deliver_fn) (
+ void *context,
+ const void *msg,
+ unsigned int msg_len,
+ const struct sockaddr_storage *system_from),
+
+ int (*iface_change_fn) (
+ void *context,
+ const struct totem_ip_address *iface_address,
+ unsigned int ring_no),
+
+ void (*mtu_changed) (
+ void *context,
+ int net_mtu),
+
+ void (*target_set_completed) (
+ void *context))
+{
+ struct totemnet_instance *instance;
+ unsigned int res;
+
+ instance = malloc (sizeof (struct totemnet_instance));
+ if (instance == NULL) {
+ return (-1);
+ }
+ totemnet_instance_initialize (instance, totem_config);
+
+ res = instance->transport->initialize (loop_pt,
+ &instance->transport_context, totem_config, stats,
+ context, deliver_fn, iface_change_fn, mtu_changed, target_set_completed);
+
+ if (res == -1) {
+ goto error_destroy;
+ }
+
+ *net_context = instance;
+ return (0);
+
+error_destroy:
+ free (instance);
+ return (-1);
+}
+
+void *totemnet_buffer_alloc (void *net_context)
+{
+ struct totemnet_instance *instance = net_context;
+ assert (instance != NULL);
+ assert (instance->transport != NULL);
+ return instance->transport->buffer_alloc();
+}
+
+void totemnet_buffer_release (void *net_context, void *ptr)
+{
+ struct totemnet_instance *instance = net_context;
+ assert (instance != NULL);
+ assert (instance->transport != NULL);
+ instance->transport->buffer_release (ptr);
+}
+
+int totemnet_processor_count_set (
+ void *net_context,
+ int processor_count)
+{
+ struct totemnet_instance *instance = (struct totemnet_instance *)net_context;
+ int res = 0;
+
+ res = instance->transport->processor_count_set (instance->transport_context, processor_count);
+ return (res);
+}
+
+int totemnet_recv_flush (void *net_context)
+{
+ struct totemnet_instance *instance = (struct totemnet_instance *)net_context;
+ int res = 0;
+
+ res = instance->transport->recv_flush (instance->transport_context);
+
+ return (res);
+}
+
+int totemnet_send_flush (void *net_context)
+{
+ struct totemnet_instance *instance = (struct totemnet_instance *)net_context;
+ int res = 0;
+
+ res = instance->transport->send_flush (instance->transport_context);
+
+ return (res);
+}
+
+int totemnet_token_send (
+ void *net_context,
+ const void *msg,
+ unsigned int msg_len)
+{
+ struct totemnet_instance *instance = (struct totemnet_instance *)net_context;
+ int res = 0;
+
+ res = instance->transport->token_send (instance->transport_context, msg, msg_len);
+
+ return (res);
+}
+int totemnet_mcast_flush_send (
+ void *net_context,
+ const void *msg,
+ unsigned int msg_len)
+{
+ struct totemnet_instance *instance = (struct totemnet_instance *)net_context;
+ int res = 0;
+
+ res = instance->transport->mcast_flush_send (instance->transport_context, msg, msg_len);
+
+ return (res);
+}
+
+int totemnet_mcast_noflush_send (
+ void *net_context,
+ const void *msg,
+ unsigned int msg_len)
+{
+ struct totemnet_instance *instance = (struct totemnet_instance *)net_context;
+ int res = 0;
+
+ res = instance->transport->mcast_noflush_send (instance->transport_context, msg, msg_len);
+
+ return (res);
+}
+
+extern int totemnet_iface_check (void *net_context)
+{
+ struct totemnet_instance *instance = (struct totemnet_instance *)net_context;
+ int res = 0;
+
+ res = instance->transport->iface_check (instance->transport_context);
+
+ return (res);
+}
+
+extern int totemnet_net_mtu_adjust (void *net_context, struct totem_config *totem_config)
+{
+ struct totemnet_instance *instance = (struct totemnet_instance *)net_context;
+ int res = 0;
+
+ instance->transport->net_mtu_adjust (instance->transport_context, totem_config);
+ return (res);
+}
+
+int totemnet_iface_set (void *net_context,
+ const struct totem_ip_address *interface_addr,
+ unsigned short ip_port,
+ unsigned int iface_no)
+{
+ struct totemnet_instance *instance = (struct totemnet_instance *)net_context;
+ int res;
+
+ res = instance->transport->iface_set (instance->transport_context, interface_addr, ip_port, iface_no);
+
+ return (res);
+}
+
+extern int totemnet_nodestatus_get (
+ void *net_context,
+ unsigned int nodeid,
+ struct totem_node_status *node_status)
+{
+ struct totemnet_instance *instance = (struct totemnet_instance *)net_context;
+ unsigned int res;
+
+ res = instance->transport->nodestatus_get (instance->transport_context, nodeid, node_status);
+
+ return (res);
+}
+
+int totemnet_ifaces_get (
+ void *net_context,
+ char ***status,
+ unsigned int *iface_count)
+{
+ struct totemnet_instance *instance = (struct totemnet_instance *)net_context;
+ unsigned int res;
+
+ res = instance->transport->ifaces_get (instance->transport_context, status, iface_count);
+
+ return (res);
+}
+
+int totemnet_token_target_set (
+ void *net_context,
+ unsigned int nodeid)
+{
+ struct totemnet_instance *instance = (struct totemnet_instance *)net_context;
+ unsigned int res;
+
+ res = instance->transport->token_target_set (instance->transport_context, nodeid);
+
+ return (res);
+}
+
+extern int totemnet_recv_mcast_empty (
+ void *net_context)
+{
+ struct totemnet_instance *instance = (struct totemnet_instance *)net_context;
+ unsigned int res;
+
+ res = instance->transport->recv_mcast_empty (instance->transport_context);
+
+ return (res);
+}
+
+extern int totemnet_member_add (
+ void *net_context,
+ const struct totem_ip_address *local,
+ const struct totem_ip_address *member,
+ int ring_no)
+{
+ struct totemnet_instance *instance = (struct totemnet_instance *)net_context;
+ unsigned int res = 0;
+
+ if (instance->transport->member_add) {
+ res = instance->transport->member_add (
+ instance->transport_context,
+ local,
+ member,
+ ring_no);
+ }
+
+ return (res);
+}
+
+extern int totemnet_member_remove (
+ void *net_context,
+ const struct totem_ip_address *member,
+ int ring_no)
+{
+ struct totemnet_instance *instance = (struct totemnet_instance *)net_context;
+ unsigned int res = 0;
+
+ if (instance->transport->member_remove) {
+ res = instance->transport->member_remove (
+ instance->transport_context,
+ member,
+ ring_no);
+ }
+
+ return (res);
+}
+
+int totemnet_member_set_active (
+ void *net_context,
+ const struct totem_ip_address *member,
+ int active)
+{
+ struct totemnet_instance *instance = (struct totemnet_instance *)net_context;
+ unsigned int res = 0;
+
+ if (instance->transport->member_set_active) {
+ res = instance->transport->member_set_active (
+ instance->transport_context,
+ member,
+ active);
+ }
+
+ return (res);
+}
+
+int totemnet_reconfigure (
+ void *net_context,
+ struct totem_config *totem_config)
+{
+ struct totemnet_instance *instance = (struct totemnet_instance *)net_context;
+ unsigned int res = 0;
+
+ res = instance->transport->reconfigure (
+ instance->transport_context,
+ totem_config);
+
+ return (res);
+}
+
+int totemnet_crypto_reconfigure_phase (
+ void *net_context,
+ struct totem_config *totem_config,
+ cfg_message_crypto_reconfig_phase_t phase)
+{
+ struct totemnet_instance *instance = (struct totemnet_instance *)net_context;
+ unsigned int res = 0;
+
+ if (instance->transport->crypto_reconfigure_phase) {
+ res = instance->transport->crypto_reconfigure_phase (
+ instance->transport_context,
+ totem_config, phase);
+ }
+ return (res);
+}
+
+void totemnet_stats_clear (
+ void *net_context)
+{
+ struct totemnet_instance *instance = (struct totemnet_instance *)net_context;
+
+ if (instance->transport->stats_clear) {
+ instance->transport->stats_clear (
+ instance->transport_context);
+ }
+}
diff --git a/exec/totemnet.h b/exec/totemnet.h
new file mode 100644
index 0000000..e71d9e0
--- /dev/null
+++ b/exec/totemnet.h
@@ -0,0 +1,166 @@
+/*
+ * Copyright (c) 2005 MontaVista Software, Inc.
+ * Copyright (c) 2006-2007, 2009 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Author: Steven Dake (sdake@redhat.com)
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of the MontaVista Software, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file
+ * Totem Network interface - also does encryption/decryption
+ *
+ * depends on poll abstraction, POSIX, IPV4
+ */
+
+#ifndef TOTEMNET_H_DEFINED
+#define TOTEMNET_H_DEFINED
+
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <corosync/totem/totem.h>
+
+#define TOTEMNET_NOFLUSH 0
+#define TOTEMNET_FLUSH 1
+
+/**
+ * Create an instance
+ */
+extern int totemnet_initialize (
+ qb_loop_t *poll_handle,
+ void **net_context,
+ struct totem_config *totem_config,
+ totemsrp_stats_t *stats,
+ void *context,
+
+ int (*deliver_fn) (
+ void *context,
+ const void *msg,
+ unsigned int msg_len,
+ const struct sockaddr_storage *system_from),
+
+ int (*iface_change_fn) (
+ void *context,
+ const struct totem_ip_address *iface_address,
+ unsigned int iface_no),
+
+ void (*mtu_changed) (
+ void *context,
+ int net_mtu),
+
+ void (*target_set_completed) (
+ void *context));
+
+extern void *totemnet_buffer_alloc (void *net_context);
+
+extern void totemnet_buffer_release (void *net_context, void *ptr);
+
+extern int totemnet_processor_count_set (
+ void *net_context,
+ int processor_count);
+
+extern int totemnet_token_send (
+ void *net_context,
+ const void *msg,
+ unsigned int msg_len);
+
+extern int totemnet_mcast_flush_send (
+ void *net_context,
+ const void *msg,
+ unsigned int msg_len);
+
+extern int totemnet_mcast_noflush_send (
+ void *net_context,
+ const void *msg,
+ unsigned int msg_len);
+
+extern int totemnet_recv_flush (void *net_context);
+
+extern int totemnet_send_flush (void *net_context);
+
+extern int totemnet_iface_set (void *net_context,
+ const struct totem_ip_address *interface_addr,
+ unsigned short ip_port,
+ unsigned int iface_no);
+
+extern int totemnet_iface_check (void *net_context);
+
+extern int totemnet_finalize (void *net_context);
+
+extern int totemnet_net_mtu_adjust (void *net_context, struct totem_config *totem_config);
+
+extern int totemnet_reconfigure (void *net_context, struct totem_config *totem_config);
+
+extern int totemnet_crypto_reconfigure_phase (void *net_context, struct totem_config *totem_config, cfg_message_crypto_reconfig_phase_t phase);
+
+extern void totemnet_stats_clear (void *net_context);
+
+extern const char *totemnet_iface_print (void *net_context);
+
+extern int totemnet_nodestatus_get (
+ void *net_context,
+ unsigned int nodeid,
+ struct totem_node_status *node_status);
+
+extern int totemnet_ifaces_get (
+ void *net_context,
+ char ***status,
+ unsigned int *iface_count);
+
+extern int totemnet_token_target_set (
+ void *net_context,
+ unsigned int target_nodeid);
+
+extern int totemnet_crypto_set (
+ void *net_context,
+ const char *cipher_type,
+ const char *hash_type);
+
+extern int totemnet_recv_mcast_empty (
+ void *net_context);
+
+extern int totemnet_member_add (
+ void *net_context,
+ const struct totem_ip_address *local,
+ const struct totem_ip_address *member,
+ int ring_no);
+
+extern int totemnet_member_remove (
+ void *net_context,
+ const struct totem_ip_address *member,
+ int ring_no);
+
+extern int totemnet_member_set_active (
+ void *net_context,
+ const struct totem_ip_address *member,
+ int active);
+
+#endif /* TOTEMNET_H_DEFINED */
diff --git a/exec/totempg.c b/exec/totempg.c
new file mode 100644
index 0000000..c30c077
--- /dev/null
+++ b/exec/totempg.c
@@ -0,0 +1,1620 @@
+/*
+ * Copyright (c) 2003-2005 MontaVista Software, Inc.
+ * Copyright (c) 2005 OSDL.
+ * Copyright (c) 2006-2012 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Author: Steven Dake (sdake@redhat.com)
+ * Author: Mark Haverkamp (markh@osdl.org)
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of the MontaVista Software, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * FRAGMENTATION AND PACKING ALGORITHM:
+ *
+ * Assemble the entire message into one buffer
+ * if full fragment
+ * store fragment into lengths list
+ * for each full fragment
+ * multicast fragment
+ * set length and fragment fields of pg mesage
+ * store remaining multicast into head of fragmentation data and set lens field
+ *
+ * If a message exceeds the maximum packet size allowed by the totem
+ * single ring protocol, the protocol could lose forward progress.
+ * Statically calculating the allowed data amount doesn't work because
+ * the amount of data allowed depends on the number of fragments in
+ * each message. In this implementation, the maximum fragment size
+ * is dynamically calculated for each fragment added to the message.
+
+ * It is possible for a message to be two bytes short of the maximum
+ * packet size. This occurs when a message or collection of
+ * messages + the mcast header + the lens are two bytes short of the
+ * end of the packet. Since another len field consumes two bytes, the
+ * len field would consume the rest of the packet without room for data.
+ *
+ * One optimization would be to forgo the final len field and determine
+ * it from the size of the udp datagram. Then this condition would no
+ * longer occur.
+ */
+
+/*
+ * ASSEMBLY AND UNPACKING ALGORITHM:
+ *
+ * copy incoming packet into assembly data buffer indexed by current
+ * location of end of fragment
+ *
+ * if not fragmented
+ * deliver all messages in assembly data buffer
+ * else
+ * if msg_count > 1 and fragmented
+ * deliver all messages except last message in assembly data buffer
+ * copy last fragmented section to start of assembly data buffer
+ * else
+ * if msg_count = 1 and fragmented
+ * do nothing
+ *
+ */
+
+#include <config.h>
+
+#ifdef HAVE_ALLOCA_H
+#include <alloca.h>
+#endif
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <sys/uio.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <pthread.h>
+#include <errno.h>
+#include <limits.h>
+
+#include <corosync/swab.h>
+#include <qb/qblist.h>
+#include <qb/qbloop.h>
+#include <qb/qbipcs.h>
+#include <corosync/totem/totempg.h>
+#define LOGSYS_UTILS_ONLY 1
+#include <corosync/logsys.h>
+
+#include "util.h"
+#include "totemsrp.h"
+
+struct totempg_mcast_header {
+ short version;
+ short type;
+};
+
+#if !(defined(__i386__) || defined(__x86_64__))
+/*
+ * Need align on architectures different then i386 or x86_64
+ */
+#define TOTEMPG_NEED_ALIGN 1
+#endif
+
+/*
+ * totempg_mcast structure
+ *
+ * header: Identify the mcast.
+ * fragmented: Set if this message continues into next message
+ * continuation: Set if this message is a continuation from last message
+ * msg_count Indicates how many packed messages are contained
+ * in the mcast.
+ * Also, the size of each packed message and the messages themselves are
+ * appended to the end of this structure when sent.
+ */
+struct totempg_mcast {
+ struct totempg_mcast_header header;
+ unsigned char fragmented;
+ unsigned char continuation;
+ unsigned short msg_count;
+ /*
+ * short msg_len[msg_count];
+ */
+ /*
+ * data for messages
+ */
+};
+
+/*
+ * Maximum packet size for totem pg messages
+ */
+#define TOTEMPG_PACKET_SIZE (totempg_totem_config->net_mtu - \
+ sizeof (struct totempg_mcast))
+
+/*
+ * Local variables used for packing small messages
+ */
+static unsigned short mcast_packed_msg_lens[FRAME_SIZE_MAX];
+
+static int mcast_packed_msg_count = 0;
+
+static int totempg_reserved = 1;
+
+static unsigned int totempg_size_limit;
+
+static totem_queue_level_changed_fn totem_queue_level_changed = NULL;
+
+static uint32_t totempg_threaded_mode = 0;
+
+static void *totemsrp_context;
+
+/*
+ * Function and data used to log messages
+ */
+static int totempg_log_level_security;
+static int totempg_log_level_error;
+static int totempg_log_level_warning;
+static int totempg_log_level_notice;
+static int totempg_log_level_debug;
+static int totempg_subsys_id;
+static void (*totempg_log_printf) (
+ int level,
+ int subsys,
+ const char *function,
+ const char *file,
+ int line,
+ const char *format, ...) __attribute__((format(printf, 6, 7)));
+
+struct totem_config *totempg_totem_config;
+
+static totempg_stats_t totempg_stats;
+
+enum throw_away_mode {
+ THROW_AWAY_INACTIVE,
+ THROW_AWAY_ACTIVE
+};
+
+struct assembly {
+ unsigned int nodeid;
+ unsigned char data[MESSAGE_SIZE_MAX+KNET_MAX_PACKET_SIZE];
+ int index;
+ unsigned char last_frag_num;
+ enum throw_away_mode throw_away_mode;
+ struct qb_list_head list;
+};
+
+static void assembly_deref (struct assembly *assembly);
+
+static int callback_token_received_fn (enum totem_callback_token_type type,
+ const void *data);
+
+QB_LIST_DECLARE(assembly_list_inuse);
+
+/*
+ * Free list is used both for transitional and operational assemblies
+ */
+QB_LIST_DECLARE(assembly_list_free);
+
+QB_LIST_DECLARE(assembly_list_inuse_trans);
+
+QB_LIST_DECLARE(totempg_groups_list);
+
+/*
+ * Staging buffer for packed messages. Messages are staged in this buffer
+ * before sending. Multiple messages may fit which cuts down on the
+ * number of mcasts sent. If a message doesn't completely fit, then
+ * the mcast header has a fragment bit set that says that there are more
+ * data to follow. fragment_size is an index into the buffer. It indicates
+ * the size of message data and where to place new message data.
+ * fragment_contuation indicates whether the first packed message in
+ * the buffer is a continuation of a previously packed fragment.
+ */
+static unsigned char *fragmentation_data;
+
+static int fragment_size = 0;
+
+static int fragment_continuation = 0;
+
+static int totempg_waiting_transack = 0;
+
+struct totempg_group_instance {
+ void (*deliver_fn) (
+ unsigned int nodeid,
+ const void *msg,
+ unsigned int msg_len,
+ int endian_conversion_required);
+
+ void (*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);
+
+ struct totempg_group *groups;
+
+ int groups_cnt;
+ int32_t q_level;
+
+ struct qb_list_head list;
+};
+
+static unsigned char next_fragment = 1;
+
+static pthread_mutex_t totempg_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+static pthread_mutex_t callback_token_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+static pthread_mutex_t mcast_msg_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+#define log_printf(level, format, args...) \
+do { \
+ totempg_log_printf(level, \
+ totempg_subsys_id, \
+ __FUNCTION__, __FILE__, __LINE__, \
+ format, ##args); \
+} while (0);
+
+static int msg_count_send_ok (int msg_count);
+
+static int byte_count_send_ok (int byte_count);
+
+static void totempg_waiting_trans_ack_cb (int waiting_trans_ack)
+{
+ log_printf(LOG_DEBUG, "waiting_trans_ack changed to %u", waiting_trans_ack);
+ totempg_waiting_transack = waiting_trans_ack;
+}
+
+static struct assembly *assembly_ref (unsigned int nodeid)
+{
+ struct assembly *assembly;
+ struct qb_list_head *list;
+ struct qb_list_head *active_assembly_list_inuse;
+
+ if (totempg_waiting_transack) {
+ active_assembly_list_inuse = &assembly_list_inuse_trans;
+ } else {
+ active_assembly_list_inuse = &assembly_list_inuse;
+ }
+
+ /*
+ * Search inuse list for node id and return assembly buffer if found
+ */
+ qb_list_for_each(list, active_assembly_list_inuse) {
+ assembly = qb_list_entry (list, struct assembly, list);
+
+ if (nodeid == assembly->nodeid) {
+ return (assembly);
+ }
+ }
+
+ /*
+ * Nothing found in inuse list get one from free list if available
+ */
+ if (qb_list_empty (&assembly_list_free) == 0) {
+ assembly = qb_list_first_entry (&assembly_list_free, struct assembly, list);
+ qb_list_del (&assembly->list);
+ qb_list_add (&assembly->list, active_assembly_list_inuse);
+ assembly->nodeid = nodeid;
+ assembly->index = 0;
+ assembly->last_frag_num = 0;
+ assembly->throw_away_mode = THROW_AWAY_INACTIVE;
+ return (assembly);
+ }
+
+ /*
+ * Nothing available in inuse or free list, so allocate a new one
+ */
+ assembly = malloc (sizeof (struct assembly));
+ /*
+ * TODO handle memory allocation failure here
+ */
+ assert (assembly);
+ assembly->nodeid = nodeid;
+ assembly->data[0] = 0;
+ assembly->index = 0;
+ assembly->last_frag_num = 0;
+ assembly->throw_away_mode = THROW_AWAY_INACTIVE;
+ qb_list_init (&assembly->list);
+ qb_list_add (&assembly->list, active_assembly_list_inuse);
+
+ return (assembly);
+}
+
+static void assembly_deref (struct assembly *assembly)
+{
+ qb_list_del (&assembly->list);
+ qb_list_add (&assembly->list, &assembly_list_free);
+}
+
+static void assembly_deref_from_normal_and_trans (int nodeid)
+{
+ int j;
+ struct qb_list_head *list, *tmp_iter;
+ struct qb_list_head *active_assembly_list_inuse;
+ struct assembly *assembly;
+
+ for (j = 0; j < 2; j++) {
+ if (j == 0) {
+ active_assembly_list_inuse = &assembly_list_inuse;
+ } else {
+ active_assembly_list_inuse = &assembly_list_inuse_trans;
+ }
+
+ qb_list_for_each_safe(list, tmp_iter, active_assembly_list_inuse) {
+ assembly = qb_list_entry (list, struct assembly, list);
+
+ if (nodeid == assembly->nodeid) {
+ qb_list_del (&assembly->list);
+ qb_list_add (&assembly->list, &assembly_list_free);
+ }
+ }
+ }
+
+}
+
+static inline void app_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 totempg_group_instance *instance;
+ struct qb_list_head *list;
+
+ /*
+ * For every leaving processor, add to free list
+ * This also has the side effect of clearing out the dataset
+ * In the leaving processor's assembly buffer.
+ */
+ for (i = 0; i < left_list_entries; i++) {
+ assembly_deref_from_normal_and_trans (left_list[i]);
+ }
+
+ qb_list_for_each(list, &totempg_groups_list) {
+ instance = qb_list_entry (list, struct totempg_group_instance, list);
+
+ if (instance->confchg_fn) {
+ instance->confchg_fn (
+ configuration_type,
+ member_list,
+ member_list_entries,
+ left_list,
+ left_list_entries,
+ joined_list,
+ joined_list_entries,
+ ring_id);
+ }
+ }
+}
+
+static inline void group_endian_convert (
+ void *msg,
+ int msg_len)
+{
+ unsigned short *group_len;
+ int i;
+ char *aligned_msg;
+
+#ifdef TOTEMPG_NEED_ALIGN
+ /*
+ * Align data structure for not i386 or x86_64
+ */
+ if ((size_t)msg % sizeof(char *) != 0) {
+ aligned_msg = alloca(msg_len);
+ memcpy(aligned_msg, msg, msg_len);
+ } else {
+ aligned_msg = msg;
+ }
+#else
+ aligned_msg = msg;
+#endif
+
+ group_len = (unsigned short *)aligned_msg;
+ group_len[0] = swab16(group_len[0]);
+ for (i = 1; i < group_len[0] + 1; i++) {
+ group_len[i] = swab16(group_len[i]);
+ }
+
+ if (aligned_msg != msg) {
+ memcpy(msg, aligned_msg, msg_len);
+ }
+}
+
+static inline int group_matches (
+ struct iovec *iovec,
+ unsigned int iov_len,
+ struct totempg_group *groups_b,
+ unsigned int group_b_cnt,
+ unsigned int *adjust_iovec)
+{
+ unsigned short *group_len;
+ char *group_name;
+ int i;
+ int j;
+#ifdef TOTEMPG_NEED_ALIGN
+ struct iovec iovec_aligned = { NULL, 0 };
+#endif
+
+ assert (iov_len == 1);
+
+#ifdef TOTEMPG_NEED_ALIGN
+ /*
+ * Align data structure for not i386 or x86_64
+ */
+ if ((size_t)iovec->iov_base % sizeof(char *) != 0) {
+ iovec_aligned.iov_base = alloca(iovec->iov_len);
+ memcpy(iovec_aligned.iov_base, iovec->iov_base, iovec->iov_len);
+ iovec_aligned.iov_len = iovec->iov_len;
+ iovec = &iovec_aligned;
+ }
+#endif
+
+ group_len = (unsigned short *)iovec->iov_base;
+ group_name = ((char *)iovec->iov_base) +
+ sizeof (unsigned short) * (group_len[0] + 1);
+
+
+ /*
+ * Calculate amount to adjust the iovec by before delivering to app
+ */
+ *adjust_iovec = sizeof (unsigned short) * (group_len[0] + 1);
+ for (i = 1; i < group_len[0] + 1; i++) {
+ *adjust_iovec += group_len[i];
+ }
+
+ /*
+ * Determine if this message should be delivered to this instance
+ */
+ for (i = 1; i < group_len[0] + 1; i++) {
+ for (j = 0; j < group_b_cnt; j++) {
+ if ((group_len[i] == groups_b[j].group_len) &&
+ (memcmp (groups_b[j].group, group_name, group_len[i]) == 0)) {
+ return (1);
+ }
+ }
+ group_name += group_len[i];
+ }
+ return (0);
+}
+
+
+static inline void app_deliver_fn (
+ unsigned int nodeid,
+ void *msg,
+ unsigned int msg_len,
+ int endian_conversion_required)
+{
+ struct totempg_group_instance *instance;
+ struct iovec stripped_iovec;
+ unsigned int adjust_iovec;
+ struct iovec *iovec;
+ struct qb_list_head *list;
+
+ struct iovec aligned_iovec = { NULL, 0 };
+
+ if (endian_conversion_required) {
+ group_endian_convert (msg, msg_len);
+ }
+
+ /*
+ * TODO: segmentation/assembly need to be redesigned to provide aligned access
+ * in all cases to avoid memory copies on non386 archs. Probably broke backwars
+ * compatibility
+ */
+
+#ifdef TOTEMPG_NEED_ALIGN
+ /*
+ * Align data structure for not i386 or x86_64
+ */
+ aligned_iovec.iov_base = alloca(msg_len);
+ aligned_iovec.iov_len = msg_len;
+ memcpy(aligned_iovec.iov_base, msg, msg_len);
+#else
+ aligned_iovec.iov_base = msg;
+ aligned_iovec.iov_len = msg_len;
+#endif
+
+ iovec = &aligned_iovec;
+
+ qb_list_for_each(list, &totempg_groups_list) {
+ instance = qb_list_entry (list, struct totempg_group_instance, list);
+ if (group_matches (iovec, 1, instance->groups, instance->groups_cnt, &adjust_iovec)) {
+ stripped_iovec.iov_len = iovec->iov_len - adjust_iovec;
+ stripped_iovec.iov_base = (char *)iovec->iov_base + adjust_iovec;
+
+#ifdef TOTEMPG_NEED_ALIGN
+ /*
+ * Align data structure for not i386 or x86_64
+ */
+ if ((uintptr_t)((char *)iovec->iov_base + adjust_iovec) % (sizeof(char *)) != 0) {
+ /*
+ * Deal with misalignment
+ */
+ stripped_iovec.iov_base =
+ alloca (stripped_iovec.iov_len);
+ memcpy (stripped_iovec.iov_base,
+ (char *)iovec->iov_base + adjust_iovec,
+ stripped_iovec.iov_len);
+ }
+#endif
+ instance->deliver_fn (
+ nodeid,
+ stripped_iovec.iov_base,
+ stripped_iovec.iov_len,
+ endian_conversion_required);
+ }
+ }
+}
+
+static void totempg_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)
+{
+// TODO optimize this
+ app_confchg_fn (configuration_type,
+ member_list, member_list_entries,
+ left_list, left_list_entries,
+ joined_list, joined_list_entries,
+ ring_id);
+}
+
+static void totempg_deliver_fn (
+ unsigned int nodeid,
+ const void *msg,
+ unsigned int msg_len,
+ int endian_conversion_required)
+{
+ struct totempg_mcast *mcast;
+ unsigned short *msg_lens;
+ int i;
+ struct assembly *assembly;
+ char header[FRAME_SIZE_MAX];
+ int msg_count;
+ int continuation;
+ int start;
+ const char *data;
+ int datasize;
+ struct iovec iov_delv;
+ size_t expected_msg_len;
+
+ assembly = assembly_ref (nodeid);
+ assert (assembly);
+
+ if (msg_len < sizeof(struct totempg_mcast)) {
+ log_printf(LOG_WARNING,
+ "Message (totempg_mcast) received from node " CS_PRI_NODE_ID " is too short... Ignoring.", nodeid);
+
+ return ;
+ }
+
+ /*
+ * Assemble the header into one block of data and
+ * assemble the packet contents into one block of data to simplify delivery
+ */
+
+ mcast = (struct totempg_mcast *)msg;
+ if (endian_conversion_required) {
+ mcast->msg_count = swab16 (mcast->msg_count);
+ }
+
+ msg_count = mcast->msg_count;
+ datasize = sizeof (struct totempg_mcast) +
+ msg_count * sizeof (unsigned short);
+
+ if (msg_len < datasize) {
+ log_printf(LOG_WARNING,
+ "Message (totempg_mcast datasize) received from node " CS_PRI_NODE_ID
+ " is too short... Ignoring.", nodeid);
+
+ return ;
+ }
+
+ memcpy (header, msg, datasize);
+ data = msg;
+
+ msg_lens = (unsigned short *) (header + sizeof (struct totempg_mcast));
+ expected_msg_len = datasize;
+ for (i = 0; i < mcast->msg_count; i++) {
+ if (endian_conversion_required) {
+ msg_lens[i] = swab16 (msg_lens[i]);
+ }
+
+ expected_msg_len += msg_lens[i];
+ }
+
+ if (msg_len != expected_msg_len) {
+ log_printf(LOG_WARNING,
+ "Message (totempg_mcast) received from node " CS_PRI_NODE_ID
+ " doesn't have expected length of %zu (has %u) bytes... Ignoring.",
+ nodeid, expected_msg_len, msg_len);
+
+ return ;
+ }
+
+ assert((assembly->index+msg_len) < sizeof(assembly->data));
+ memcpy (&assembly->data[assembly->index], &data[datasize],
+ msg_len - datasize);
+
+ /*
+ * If the last message in the buffer is a fragment, then we
+ * can't deliver it. We'll first deliver the full messages
+ * then adjust the assembly buffer so we can add the rest of the
+ * fragment when it arrives.
+ */
+ msg_count = mcast->fragmented ? mcast->msg_count - 1 : mcast->msg_count;
+ continuation = mcast->continuation;
+ iov_delv.iov_base = (void *)&assembly->data[0];
+ iov_delv.iov_len = assembly->index + msg_lens[0];
+
+ /*
+ * Make sure that if this message is a continuation, that it
+ * matches the sequence number of the previous fragment.
+ * Also, if the first packed message is a continuation
+ * of a previous message, but the assembly buffer
+ * is empty, then we need to discard it since we can't
+ * assemble a complete message. Likewise, if this message isn't a
+ * continuation and the assembly buffer is empty, we have to discard
+ * the continued message.
+ */
+ start = 0;
+
+ if (assembly->throw_away_mode == THROW_AWAY_ACTIVE) {
+ /* Throw away the first msg block */
+ if (mcast->fragmented == 0 || mcast->fragmented == 1) {
+ assembly->throw_away_mode = THROW_AWAY_INACTIVE;
+
+ assembly->index += msg_lens[0];
+ iov_delv.iov_base = (void *)&assembly->data[assembly->index];
+ iov_delv.iov_len = msg_lens[1];
+ start = 1;
+ }
+ } else
+ if (assembly->throw_away_mode == THROW_AWAY_INACTIVE) {
+ if (continuation == assembly->last_frag_num) {
+ assembly->last_frag_num = mcast->fragmented;
+ for (i = start; i < msg_count; i++) {
+ app_deliver_fn(nodeid, iov_delv.iov_base, iov_delv.iov_len,
+ endian_conversion_required);
+ assembly->index += msg_lens[i];
+ iov_delv.iov_base = (void *)&assembly->data[assembly->index];
+ if (i < (msg_count - 1)) {
+ iov_delv.iov_len = msg_lens[i + 1];
+ }
+ }
+ } else {
+ log_printf (LOG_DEBUG, "fragmented continuation %u is not equal to assembly last_frag_num %u",
+ continuation, assembly->last_frag_num);
+ assembly->throw_away_mode = THROW_AWAY_ACTIVE;
+ }
+ }
+
+ if (mcast->fragmented == 0) {
+ /*
+ * End of messages, dereference assembly struct
+ */
+ assembly->last_frag_num = 0;
+ assembly->index = 0;
+ assembly_deref (assembly);
+ } else {
+ /*
+ * Message is fragmented, keep around assembly list
+ */
+ if (mcast->msg_count > 1) {
+ memmove (&assembly->data[0],
+ &assembly->data[assembly->index],
+ msg_lens[msg_count]);
+
+ assembly->index = 0;
+ }
+ assembly->index += msg_lens[msg_count];
+ }
+}
+
+/*
+ * Totem Process Group Abstraction
+ * depends on poll abstraction, POSIX, IPV4
+ */
+
+void *callback_token_received_handle;
+
+int callback_token_received_fn (enum totem_callback_token_type type,
+ const void *data)
+{
+ struct totempg_mcast mcast;
+ struct iovec iovecs[3];
+
+ if (totempg_threaded_mode == 1) {
+ pthread_mutex_lock (&mcast_msg_mutex);
+ }
+ if (mcast_packed_msg_count == 0) {
+ if (totempg_threaded_mode == 1) {
+ pthread_mutex_unlock (&mcast_msg_mutex);
+ }
+ return (0);
+ }
+ if (totemsrp_avail(totemsrp_context) == 0) {
+ if (totempg_threaded_mode == 1) {
+ pthread_mutex_unlock (&mcast_msg_mutex);
+ }
+ return (0);
+ }
+ mcast.header.version = 0;
+ mcast.header.type = 0;
+ mcast.fragmented = 0;
+
+ /*
+ * Was the first message in this buffer a continuation of a
+ * fragmented message?
+ */
+ mcast.continuation = fragment_continuation;
+ fragment_continuation = 0;
+
+ mcast.msg_count = mcast_packed_msg_count;
+
+ iovecs[0].iov_base = (void *)&mcast;
+ iovecs[0].iov_len = sizeof (struct totempg_mcast);
+ iovecs[1].iov_base = (void *)mcast_packed_msg_lens;
+ iovecs[1].iov_len = mcast_packed_msg_count * sizeof (unsigned short);
+ iovecs[2].iov_base = (void *)&fragmentation_data[0];
+ iovecs[2].iov_len = fragment_size;
+ (void)totemsrp_mcast (totemsrp_context, iovecs, 3, 0);
+
+ mcast_packed_msg_count = 0;
+ fragment_size = 0;
+
+ if (totempg_threaded_mode == 1) {
+ pthread_mutex_unlock (&mcast_msg_mutex);
+ }
+ return (0);
+}
+
+/*
+ * Initialize the totem process group abstraction
+ */
+int totempg_initialize (
+ qb_loop_t *poll_handle,
+ struct totem_config *totem_config)
+{
+ int res;
+
+ totempg_totem_config = totem_config;
+ totempg_log_level_security = totem_config->totem_logging_configuration.log_level_security;
+ totempg_log_level_error = totem_config->totem_logging_configuration.log_level_error;
+ totempg_log_level_warning = totem_config->totem_logging_configuration.log_level_warning;
+ totempg_log_level_notice = totem_config->totem_logging_configuration.log_level_notice;
+ totempg_log_level_debug = totem_config->totem_logging_configuration.log_level_debug;
+ totempg_log_printf = totem_config->totem_logging_configuration.log_printf;
+ totempg_subsys_id = totem_config->totem_logging_configuration.log_subsys_id;
+
+ fragmentation_data = malloc (TOTEMPG_PACKET_SIZE);
+ if (fragmentation_data == 0) {
+ return (-1);
+ }
+
+ totemsrp_net_mtu_adjust (totem_config);
+
+ res = totemsrp_initialize (
+ poll_handle,
+ &totemsrp_context,
+ totem_config,
+ &totempg_stats,
+ totempg_deliver_fn,
+ totempg_confchg_fn,
+ totempg_waiting_trans_ack_cb);
+
+ if (res == -1) {
+ goto error_exit;
+ }
+
+ totemsrp_callback_token_create (
+ totemsrp_context,
+ &callback_token_received_handle,
+ TOTEM_CALLBACK_TOKEN_RECEIVED,
+ 0,
+ callback_token_received_fn,
+ 0);
+
+ totempg_size_limit = (totemsrp_avail(totemsrp_context) - 1) *
+ (totempg_totem_config->net_mtu -
+ sizeof (struct totempg_mcast) - 16);
+
+ qb_list_init (&totempg_groups_list);
+
+error_exit:
+ return (res);
+}
+
+void totempg_finalize (void)
+{
+ if (totempg_threaded_mode == 1) {
+ pthread_mutex_lock (&totempg_mutex);
+ }
+ totemsrp_finalize (totemsrp_context);
+ if (totempg_threaded_mode == 1) {
+ pthread_mutex_unlock (&totempg_mutex);
+ }
+}
+
+/*
+ * Multicast a message
+ */
+static int mcast_msg (
+ struct iovec *iovec_in,
+ unsigned int iov_len,
+ int guarantee)
+{
+ int res = 0;
+ struct totempg_mcast mcast;
+ struct iovec iovecs[3];
+ struct iovec iovec[64];
+ int i;
+ int dest, src;
+ int max_packet_size = 0;
+ int copy_len = 0;
+ int copy_base = 0;
+ int total_size = 0;
+
+ if (totempg_threaded_mode == 1) {
+ pthread_mutex_lock (&mcast_msg_mutex);
+ }
+ totemsrp_event_signal (totemsrp_context, TOTEM_EVENT_NEW_MSG, 1);
+
+ /*
+ * Remove zero length iovectors from the list
+ */
+ assert (iov_len < 64);
+ for (dest = 0, src = 0; src < iov_len; src++) {
+ if (iovec_in[src].iov_len) {
+ memcpy (&iovec[dest++], &iovec_in[src],
+ sizeof (struct iovec));
+ }
+ }
+ iov_len = dest;
+
+ max_packet_size = TOTEMPG_PACKET_SIZE -
+ (sizeof (unsigned short) * (mcast_packed_msg_count + 1));
+
+ mcast_packed_msg_lens[mcast_packed_msg_count] = 0;
+
+ /*
+ * Check if we would overwrite new message queue
+ */
+ for (i = 0; i < iov_len; i++) {
+ total_size += iovec[i].iov_len;
+ }
+
+ if (byte_count_send_ok (total_size + sizeof(unsigned short) *
+ (mcast_packed_msg_count)) == 0) {
+
+ if (totempg_threaded_mode == 1) {
+ pthread_mutex_unlock (&mcast_msg_mutex);
+ }
+ return(-1);
+ }
+
+ memset(&mcast, 0, sizeof(mcast));
+
+ mcast.header.version = 0;
+ for (i = 0; i < iov_len; ) {
+ mcast.fragmented = 0;
+ mcast.continuation = fragment_continuation;
+ copy_len = iovec[i].iov_len - copy_base;
+
+ /*
+ * If it all fits with room left over, copy it in.
+ * We need to leave at least sizeof(short) + 1 bytes in the
+ * fragment_buffer on exit so that max_packet_size + fragment_size
+ * doesn't exceed the size of the fragment_buffer on the next call.
+ */
+ if ((iovec[i].iov_len + fragment_size) <
+ (max_packet_size - sizeof (unsigned short))) {
+
+ memcpy (&fragmentation_data[fragment_size],
+ (char *)iovec[i].iov_base + copy_base, copy_len);
+ fragment_size += copy_len;
+ mcast_packed_msg_lens[mcast_packed_msg_count] += copy_len;
+ next_fragment = 1;
+ copy_len = 0;
+ copy_base = 0;
+ i++;
+ continue;
+
+ /*
+ * If it just fits or is too big, then send out what fits.
+ */
+ } else {
+ unsigned char *data_ptr;
+
+ copy_len = min(copy_len, max_packet_size - fragment_size);
+ if( copy_len == max_packet_size )
+ data_ptr = (unsigned char *)iovec[i].iov_base + copy_base;
+ else {
+ data_ptr = fragmentation_data;
+ }
+
+ memcpy (&fragmentation_data[fragment_size],
+ (unsigned char *)iovec[i].iov_base + copy_base, copy_len);
+ mcast_packed_msg_lens[mcast_packed_msg_count] += copy_len;
+
+ /*
+ * if we're not on the last iovec or the iovec is too large to
+ * fit, then indicate a fragment. This also means that the next
+ * message will have the continuation of this one.
+ */
+ if ((i < (iov_len - 1)) ||
+ ((copy_base + copy_len) < iovec[i].iov_len)) {
+ if (!next_fragment) {
+ next_fragment++;
+ }
+ fragment_continuation = next_fragment;
+ mcast.fragmented = next_fragment++;
+ assert(fragment_continuation != 0);
+ assert(mcast.fragmented != 0);
+ } else {
+ fragment_continuation = 0;
+ }
+
+ /*
+ * assemble the message and send it
+ */
+ mcast.msg_count = ++mcast_packed_msg_count;
+ iovecs[0].iov_base = (void *)&mcast;
+ iovecs[0].iov_len = sizeof(struct totempg_mcast);
+ iovecs[1].iov_base = (void *)mcast_packed_msg_lens;
+ iovecs[1].iov_len = mcast_packed_msg_count *
+ sizeof(unsigned short);
+ iovecs[2].iov_base = (void *)data_ptr;
+ iovecs[2].iov_len = fragment_size + copy_len;
+ assert (totemsrp_avail(totemsrp_context) > 0);
+ res = totemsrp_mcast (totemsrp_context, iovecs, 3, guarantee);
+ if (res == -1) {
+ goto error_exit;
+ }
+
+ /*
+ * Recalculate counts and indexes for the next.
+ */
+ mcast_packed_msg_lens[0] = 0;
+ mcast_packed_msg_count = 0;
+ fragment_size = 0;
+ max_packet_size = TOTEMPG_PACKET_SIZE - (sizeof(unsigned short));
+
+ /*
+ * If the iovec all fit, go to the next iovec
+ */
+ if ((copy_base + copy_len) == iovec[i].iov_len) {
+ copy_len = 0;
+ copy_base = 0;
+ i++;
+
+ /*
+ * Continue with the rest of the current iovec.
+ */
+ } else {
+ copy_base += copy_len;
+ }
+ }
+ }
+
+ /*
+ * Bump only if we added message data. This may be zero if
+ * the last buffer just fit into the fragmentation_data buffer
+ * and we were at the last iovec.
+ */
+ if (mcast_packed_msg_lens[mcast_packed_msg_count]) {
+ mcast_packed_msg_count++;
+ }
+
+error_exit:
+ if (totempg_threaded_mode == 1) {
+ pthread_mutex_unlock (&mcast_msg_mutex);
+ }
+ return (res);
+}
+
+/*
+ * Determine if a message of msg_size could be queued
+ */
+static int msg_count_send_ok (
+ int msg_count)
+{
+ int avail = 0;
+
+ avail = totemsrp_avail (totemsrp_context);
+ totempg_stats.msg_queue_avail = avail;
+
+ return ((avail - totempg_reserved) > msg_count);
+}
+
+static int byte_count_send_ok (
+ int byte_count)
+{
+ unsigned int msg_count = 0;
+ int avail = 0;
+
+ avail = totemsrp_avail (totemsrp_context);
+
+ msg_count = (byte_count / (totempg_totem_config->net_mtu - sizeof (struct totempg_mcast) - 16)) + 1;
+
+ return (avail >= msg_count);
+}
+
+static int send_reserve (
+ int msg_size)
+{
+ unsigned int msg_count = 0;
+
+ msg_count = (msg_size / (totempg_totem_config->net_mtu - sizeof (struct totempg_mcast) - 16)) + 1;
+ totempg_reserved += msg_count;
+ totempg_stats.msg_reserved = totempg_reserved;
+
+ return (msg_count);
+}
+
+static void send_release (
+ int msg_count)
+{
+ totempg_reserved -= msg_count;
+ totempg_stats.msg_reserved = totempg_reserved;
+}
+
+#ifndef HAVE_SMALL_MEMORY_FOOTPRINT
+#undef MESSAGE_QUEUE_MAX
+#define MESSAGE_QUEUE_MAX ((4 * MESSAGE_SIZE_MAX) / totempg_totem_config->net_mtu)
+#endif /* HAVE_SMALL_MEMORY_FOOTPRINT */
+
+static uint32_t q_level_precent_used(void)
+{
+ return (100 - (((totemsrp_avail(totemsrp_context) - totempg_reserved) * 100) / MESSAGE_QUEUE_MAX));
+}
+
+int totempg_callback_token_create (
+ void **handle_out,
+ enum totem_callback_token_type type,
+ int delete,
+ int (*callback_fn) (enum totem_callback_token_type type, const void *),
+ const void *data)
+{
+ unsigned int res;
+ if (totempg_threaded_mode == 1) {
+ pthread_mutex_lock (&callback_token_mutex);
+ }
+ res = totemsrp_callback_token_create (totemsrp_context, handle_out, type, delete,
+ callback_fn, data);
+ if (totempg_threaded_mode == 1) {
+ pthread_mutex_unlock (&callback_token_mutex);
+ }
+ return (res);
+}
+
+void totempg_callback_token_destroy (
+ void *handle_out)
+{
+ if (totempg_threaded_mode == 1) {
+ pthread_mutex_lock (&callback_token_mutex);
+ }
+ totemsrp_callback_token_destroy (totemsrp_context, handle_out);
+ if (totempg_threaded_mode == 1) {
+ pthread_mutex_unlock (&callback_token_mutex);
+ }
+}
+
+/*
+ * vi: set autoindent tabstop=4 shiftwidth=4 :
+ */
+
+int totempg_groups_initialize (
+ void **totempg_groups_instance,
+
+ void (*deliver_fn) (
+ unsigned int nodeid,
+ const void *msg,
+ unsigned int msg_len,
+ int endian_conversion_required),
+
+ void (*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))
+{
+ struct totempg_group_instance *instance;
+
+ if (totempg_threaded_mode == 1) {
+ pthread_mutex_lock (&totempg_mutex);
+ }
+
+ instance = malloc (sizeof (struct totempg_group_instance));
+ if (instance == NULL) {
+ goto error_exit;
+ }
+
+ instance->deliver_fn = deliver_fn;
+ instance->confchg_fn = confchg_fn;
+ instance->groups = 0;
+ instance->groups_cnt = 0;
+ instance->q_level = QB_LOOP_MED;
+ qb_list_init (&instance->list);
+ qb_list_add (&instance->list, &totempg_groups_list);
+
+ if (totempg_threaded_mode == 1) {
+ pthread_mutex_unlock (&totempg_mutex);
+ }
+ *totempg_groups_instance = instance;
+ return (0);
+
+error_exit:
+ if (totempg_threaded_mode == 1) {
+ pthread_mutex_unlock (&totempg_mutex);
+ }
+ return (-1);
+}
+
+int totempg_groups_join (
+ void *totempg_groups_instance,
+ const struct totempg_group *groups,
+ size_t group_cnt)
+{
+ struct totempg_group_instance *instance = (struct totempg_group_instance *)totempg_groups_instance;
+ struct totempg_group *new_groups;
+ int res = 0;
+
+ if (totempg_threaded_mode == 1) {
+ pthread_mutex_lock (&totempg_mutex);
+ }
+
+ new_groups = realloc (instance->groups,
+ sizeof (struct totempg_group) *
+ (instance->groups_cnt + group_cnt));
+ if (new_groups == 0) {
+ res = -1;
+ goto error_exit;
+ }
+ memcpy (&new_groups[instance->groups_cnt],
+ groups, group_cnt * sizeof (struct totempg_group));
+ instance->groups = new_groups;
+ instance->groups_cnt += group_cnt;
+
+error_exit:
+ if (totempg_threaded_mode == 1) {
+ pthread_mutex_unlock (&totempg_mutex);
+ }
+ return (res);
+}
+
+int totempg_groups_leave (
+ void *totempg_groups_instance,
+ const struct totempg_group *groups,
+ size_t group_cnt)
+{
+ if (totempg_threaded_mode == 1) {
+ pthread_mutex_lock (&totempg_mutex);
+ }
+
+ if (totempg_threaded_mode == 1) {
+ pthread_mutex_unlock (&totempg_mutex);
+ }
+ return (0);
+}
+
+#define MAX_IOVECS_FROM_APP 32
+#define MAX_GROUPS_PER_MSG 32
+
+int totempg_groups_mcast_joined (
+ void *totempg_groups_instance,
+ const struct iovec *iovec,
+ unsigned int iov_len,
+ int guarantee)
+{
+ struct totempg_group_instance *instance = (struct totempg_group_instance *)totempg_groups_instance;
+ unsigned short group_len[MAX_GROUPS_PER_MSG + 1];
+ struct iovec iovec_mcast[MAX_GROUPS_PER_MSG + 1 + MAX_IOVECS_FROM_APP];
+ int i;
+ unsigned int res;
+
+ if (totempg_threaded_mode == 1) {
+ pthread_mutex_lock (&totempg_mutex);
+ }
+
+ /*
+ * Build group_len structure and the iovec_mcast structure
+ */
+ group_len[0] = instance->groups_cnt;
+ for (i = 0; i < instance->groups_cnt; i++) {
+ group_len[i + 1] = instance->groups[i].group_len;
+ iovec_mcast[i + 1].iov_len = instance->groups[i].group_len;
+ iovec_mcast[i + 1].iov_base = (void *) instance->groups[i].group;
+ }
+ iovec_mcast[0].iov_len = (instance->groups_cnt + 1) * sizeof (unsigned short);
+ iovec_mcast[0].iov_base = group_len;
+ for (i = 0; i < iov_len; i++) {
+ iovec_mcast[i + instance->groups_cnt + 1].iov_len = iovec[i].iov_len;
+ iovec_mcast[i + instance->groups_cnt + 1].iov_base = iovec[i].iov_base;
+ }
+
+ res = mcast_msg (iovec_mcast, iov_len + instance->groups_cnt + 1, guarantee);
+
+ if (totempg_threaded_mode == 1) {
+ pthread_mutex_unlock (&totempg_mutex);
+ }
+
+ return (res);
+}
+
+static void check_q_level(
+ void *totempg_groups_instance)
+{
+ struct totempg_group_instance *instance = (struct totempg_group_instance *)totempg_groups_instance;
+ int32_t old_level = instance->q_level;
+ int32_t percent_used = q_level_precent_used();
+
+ if (percent_used >= 75 && instance->q_level != TOTEM_Q_LEVEL_CRITICAL) {
+ instance->q_level = TOTEM_Q_LEVEL_CRITICAL;
+ } else if (percent_used < 30 && instance->q_level != TOTEM_Q_LEVEL_LOW) {
+ instance->q_level = TOTEM_Q_LEVEL_LOW;
+ } else if (percent_used > 40 && percent_used < 50 && instance->q_level != TOTEM_Q_LEVEL_GOOD) {
+ instance->q_level = TOTEM_Q_LEVEL_GOOD;
+ } else if (percent_used > 60 && percent_used < 70 && instance->q_level != TOTEM_Q_LEVEL_HIGH) {
+ instance->q_level = TOTEM_Q_LEVEL_HIGH;
+ }
+ if (totem_queue_level_changed && old_level != instance->q_level) {
+ totem_queue_level_changed(instance->q_level);
+ }
+}
+
+void totempg_check_q_level(
+ void *totempg_groups_instance)
+{
+ struct totempg_group_instance *instance = (struct totempg_group_instance *)totempg_groups_instance;
+
+ check_q_level(instance);
+}
+
+int totempg_groups_joined_reserve (
+ void *totempg_groups_instance,
+ const struct iovec *iovec,
+ unsigned int iov_len)
+{
+ struct totempg_group_instance *instance = (struct totempg_group_instance *)totempg_groups_instance;
+ unsigned int size = 0;
+ unsigned int i;
+ unsigned int reserved = 0;
+
+ if (totempg_threaded_mode == 1) {
+ pthread_mutex_lock (&totempg_mutex);
+ pthread_mutex_lock (&mcast_msg_mutex);
+ }
+
+ for (i = 0; i < instance->groups_cnt; i++) {
+ size += instance->groups[i].group_len;
+ }
+ for (i = 0; i < iov_len; i++) {
+ size += iovec[i].iov_len;
+ }
+
+ if (size >= totempg_size_limit) {
+ reserved = -1;
+ goto error_exit;
+ }
+
+ if (byte_count_send_ok (size)) {
+ reserved = send_reserve (size);
+ } else {
+ reserved = 0;
+ }
+
+error_exit:
+ check_q_level(instance);
+
+ if (totempg_threaded_mode == 1) {
+ pthread_mutex_unlock (&mcast_msg_mutex);
+ pthread_mutex_unlock (&totempg_mutex);
+ }
+ return (reserved);
+}
+
+
+int totempg_groups_joined_release (int msg_count)
+{
+ if (totempg_threaded_mode == 1) {
+ pthread_mutex_lock (&totempg_mutex);
+ pthread_mutex_lock (&mcast_msg_mutex);
+ }
+ send_release (msg_count);
+ if (totempg_threaded_mode == 1) {
+ pthread_mutex_unlock (&mcast_msg_mutex);
+ pthread_mutex_unlock (&totempg_mutex);
+ }
+ return 0;
+}
+
+int totempg_groups_mcast_groups (
+ void *totempg_groups_instance,
+ int guarantee,
+ const struct totempg_group *groups,
+ size_t groups_cnt,
+ const struct iovec *iovec,
+ unsigned int iov_len)
+{
+ unsigned short group_len[MAX_GROUPS_PER_MSG + 1];
+ struct iovec iovec_mcast[MAX_GROUPS_PER_MSG + 1 + MAX_IOVECS_FROM_APP];
+ int i;
+ unsigned int res;
+
+ if (totempg_threaded_mode == 1) {
+ pthread_mutex_lock (&totempg_mutex);
+ }
+
+ /*
+ * Build group_len structure and the iovec_mcast structure
+ */
+ group_len[0] = groups_cnt;
+ for (i = 0; i < groups_cnt; i++) {
+ group_len[i + 1] = groups[i].group_len;
+ iovec_mcast[i + 1].iov_len = groups[i].group_len;
+ iovec_mcast[i + 1].iov_base = (void *) groups[i].group;
+ }
+ iovec_mcast[0].iov_len = (groups_cnt + 1) * sizeof (unsigned short);
+ iovec_mcast[0].iov_base = group_len;
+ for (i = 0; i < iov_len; i++) {
+ iovec_mcast[i + groups_cnt + 1].iov_len = iovec[i].iov_len;
+ iovec_mcast[i + groups_cnt + 1].iov_base = iovec[i].iov_base;
+ }
+
+ res = mcast_msg (iovec_mcast, iov_len + groups_cnt + 1, guarantee);
+
+ if (totempg_threaded_mode == 1) {
+ pthread_mutex_unlock (&totempg_mutex);
+ }
+ return (res);
+}
+
+/*
+ * Returns -1 if error, 0 if can't send, 1 if can send the message
+ */
+int totempg_groups_send_ok_groups (
+ void *totempg_groups_instance,
+ const struct totempg_group *groups,
+ size_t groups_cnt,
+ const struct iovec *iovec,
+ unsigned int iov_len)
+{
+ unsigned int size = 0;
+ unsigned int i;
+ unsigned int res;
+
+ if (totempg_threaded_mode == 1) {
+ pthread_mutex_lock (&totempg_mutex);
+ }
+
+ for (i = 0; i < groups_cnt; i++) {
+ size += groups[i].group_len;
+ }
+ for (i = 0; i < iov_len; i++) {
+ size += iovec[i].iov_len;
+ }
+
+ res = msg_count_send_ok (size);
+
+ if (totempg_threaded_mode == 1) {
+ pthread_mutex_unlock (&totempg_mutex);
+ }
+ return (res);
+}
+
+int totempg_iface_set (
+ struct totem_ip_address *interface_addr,
+ unsigned short ip_port,
+ unsigned int iface_no)
+{
+ int res;
+
+ res = totemsrp_iface_set (
+ totemsrp_context,
+ interface_addr,
+ ip_port,
+ iface_no);
+
+ return (res);
+}
+
+int totempg_nodestatus_get (unsigned int nodeid,
+ struct totem_node_status *node_status)
+{
+ memset(node_status, 0, sizeof(struct totem_node_status));
+ return totemsrp_nodestatus_get (totemsrp_context, nodeid, node_status);
+}
+
+int totempg_ifaces_get (
+ unsigned int nodeid,
+ unsigned int *interface_id,
+ struct totem_ip_address *interfaces,
+ unsigned int interfaces_size,
+ char ***status,
+ unsigned int *iface_count)
+{
+ int res;
+
+ res = totemsrp_ifaces_get (
+ totemsrp_context,
+ nodeid,
+ interface_id,
+ interfaces,
+ interfaces_size,
+ status,
+ iface_count);
+
+ return (res);
+}
+
+void totempg_event_signal (enum totem_event_type type, int value)
+{
+ totemsrp_event_signal (totemsrp_context, type, value);
+}
+
+void* totempg_get_stats (void)
+{
+ return &totempg_stats;
+}
+
+int totempg_crypto_set (
+ const char *cipher_type,
+ const char *hash_type)
+{
+ int res;
+
+ res = totemsrp_crypto_set (totemsrp_context, cipher_type, hash_type);
+
+ return (res);
+}
+
+#define ONE_IFACE_LEN 63
+const char *totempg_ifaces_print (unsigned int nodeid)
+{
+ static char iface_string[256 * INTERFACE_MAX];
+ char one_iface[ONE_IFACE_LEN+1];
+ struct totem_ip_address interfaces[INTERFACE_MAX];
+ unsigned int iface_count;
+ unsigned int iface_ids[INTERFACE_MAX];
+ unsigned int i;
+ int res;
+
+ iface_string[0] = '\0';
+
+ res = totempg_ifaces_get (nodeid, iface_ids, interfaces, INTERFACE_MAX, NULL, &iface_count);
+ if (res == -1) {
+ return ("no interface found for nodeid");
+ }
+
+ res = totempg_ifaces_get (nodeid, iface_ids, interfaces, INTERFACE_MAX, NULL, &iface_count);
+
+ for (i = 0; i < iface_count; i++) {
+ if (!interfaces[i].family) {
+ continue;
+ }
+ snprintf (one_iface, ONE_IFACE_LEN,
+ "r(%d) ip(%s) ",
+ i, totemip_print (&interfaces[i]));
+ strcat (iface_string, one_iface);
+ }
+ return (iface_string);
+}
+
+unsigned int totempg_my_nodeid_get (void)
+{
+ return (totemsrp_my_nodeid_get(totemsrp_context));
+}
+
+int totempg_my_family_get (void)
+{
+ return (totemsrp_my_family_get(totemsrp_context));
+}
+extern void totempg_service_ready_register (
+ void (*totem_service_ready) (void))
+{
+ totemsrp_service_ready_register (totemsrp_context, totem_service_ready);
+}
+
+void totempg_queue_level_register_callback (totem_queue_level_changed_fn fn)
+{
+ totem_queue_level_changed = fn;
+}
+
+extern int totempg_member_add (
+ const struct totem_ip_address *member,
+ int ring_no)
+{
+ return totemsrp_member_add (totemsrp_context, member, ring_no);
+}
+
+extern int totempg_member_remove (
+ const struct totem_ip_address *member,
+ int ring_no)
+{
+ return totemsrp_member_remove (totemsrp_context, member, ring_no);
+}
+
+extern int totempg_reconfigure (void)
+{
+ return totemsrp_reconfigure (totemsrp_context, totempg_totem_config);
+}
+
+extern int totempg_crypto_reconfigure_phase (cfg_message_crypto_reconfig_phase_t phase)
+{
+ return totemsrp_crypto_reconfigure_phase (totemsrp_context, totempg_totem_config, phase);
+}
+
+extern void totempg_stats_clear (int flags)
+{
+ if (flags & TOTEMPG_STATS_CLEAR_TOTEM) {
+ totempg_stats.msg_reserved = 0;
+ totempg_stats.msg_queue_avail = 0;
+ }
+ return totemsrp_stats_clear (totemsrp_context, flags);
+}
+
+void totempg_threaded_mode_enable (void)
+{
+ totempg_threaded_mode = 1;
+ totemsrp_threaded_mode_enable (totemsrp_context);
+}
+
+void totempg_trans_ack (void)
+{
+ totemsrp_trans_ack (totemsrp_context);
+}
+
+void totempg_force_gather (void)
+{
+ totemsrp_force_gather(totemsrp_context);
+}
+
+/* Assumes ->orig_interfaces is already allocated */
+void totempg_get_config(struct totem_config *config)
+{
+ struct totem_interface *temp_if = config->orig_interfaces;
+
+ memcpy(config, totempg_totem_config, sizeof(struct totem_config));
+ config->orig_interfaces = temp_if;
+ memcpy(config->orig_interfaces, totempg_totem_config->interfaces, sizeof(struct totem_interface) * INTERFACE_MAX);
+ config->interfaces = NULL;
+}
+
+void totempg_put_config(struct totem_config *config)
+{
+ struct totem_interface *temp_if = totempg_totem_config->interfaces;
+
+ /* Preseve the existing interfaces[] array as transports might have pointers saved */
+ memcpy(totempg_totem_config->interfaces, config->interfaces, sizeof(struct totem_interface) * INTERFACE_MAX);
+ memcpy(totempg_totem_config, config, sizeof(struct totem_config));
+ totempg_totem_config->interfaces = temp_if;
+}
diff --git a/exec/totemsrp.c b/exec/totemsrp.c
new file mode 100644
index 0000000..63a47c1
--- /dev/null
+++ b/exec/totemsrp.c
@@ -0,0 +1,5252 @@
+/*
+ * Copyright (c) 2003-2006 MontaVista Software, Inc.
+ * Copyright (c) 2006-2018 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Author: Steven Dake (sdake@redhat.com)
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of the MontaVista Software, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * The first version of this code was based upon Yair Amir's PhD thesis:
+ * http://www.cs.jhu.edu/~yairamir/phd.ps) (ch4,5).
+ *
+ * The current version of totemsrp implements the Totem protocol specified in:
+ * http://citeseer.ist.psu.edu/amir95totem.html
+ *
+ * The deviations from the above published protocols are:
+ * - token hold mode where token doesn't rotate on unused ring - reduces cpu
+ * usage on 1.6ghz xeon from 35% to less then .1 % as measured by top
+ */
+
+#include <config.h>
+
+#include <assert.h>
+#ifdef HAVE_ALLOCA_H
+#include <alloca.h>
+#endif
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <sys/un.h>
+#include <sys/ioctl.h>
+#include <sys/param.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+#include <sched.h>
+#include <time.h>
+#include <sys/time.h>
+#include <sys/poll.h>
+#include <sys/uio.h>
+#include <limits.h>
+
+#include <qb/qblist.h>
+#include <qb/qbdefs.h>
+#include <qb/qbutil.h>
+#include <qb/qbloop.h>
+
+#include <corosync/swab.h>
+#include <corosync/sq.h>
+
+#define LOGSYS_UTILS_ONLY 1
+#include <corosync/logsys.h>
+
+#include "totemsrp.h"
+#include "totemnet.h"
+
+#include "icmap.h"
+#include "totemconfig.h"
+
+#include "cs_queue.h"
+
+#define LOCALHOST_IP inet_addr("127.0.0.1")
+#define QUEUE_RTR_ITEMS_SIZE_MAX 16384 /* allow 16384 retransmit items */
+#define RETRANS_MESSAGE_QUEUE_SIZE_MAX 16384 /* allow 500 messages to be queued */
+#define RECEIVED_MESSAGE_QUEUE_SIZE_MAX 500 /* allow 500 messages to be queued */
+#define MAXIOVS 5
+#define RETRANSMIT_ENTRIES_MAX 30
+#define TOKEN_SIZE_MAX 64000 /* bytes */
+#define LEAVE_DUMMY_NODEID 0
+
+/*
+ * SRP address.
+ */
+struct srp_addr {
+ unsigned int nodeid;
+};
+
+/*
+ * Rollover handling:
+ * SEQNO_START_MSG is the starting sequence number after a new configuration
+ * This should remain zero, unless testing overflow in which case
+ * 0x7ffff000 and 0xfffff000 are good starting values.
+ *
+ * SEQNO_START_TOKEN is the starting sequence number after a new configuration
+ * for a token. This should remain zero, unless testing overflow in which
+ * case 07fffff00 or 0xffffff00 are good starting values.
+ */
+#define SEQNO_START_MSG 0x0
+#define SEQNO_START_TOKEN 0x0
+
+/*
+ * These can be used ot test different rollover points
+ * #define SEQNO_START_MSG 0xfffffe00
+ * #define SEQNO_START_TOKEN 0xfffffe00
+ */
+
+/*
+ * These can be used to test the error recovery algorithms
+ * #define TEST_DROP_ORF_TOKEN_PERCENTAGE 30
+ * #define TEST_DROP_COMMIT_TOKEN_PERCENTAGE 30
+ * #define TEST_DROP_MCAST_PERCENTAGE 50
+ * #define TEST_RECOVERY_MSG_COUNT 300
+ */
+
+/*
+ * we compare incoming messages to determine if their endian is
+ * different - if so convert them
+ *
+ * do not change
+ */
+#define ENDIAN_LOCAL 0xff22
+
+enum message_type {
+ MESSAGE_TYPE_ORF_TOKEN = 0, /* Ordering, Reliability, Flow (ORF) control Token */
+ MESSAGE_TYPE_MCAST = 1, /* ring ordered multicast message */
+ MESSAGE_TYPE_MEMB_MERGE_DETECT = 2, /* merge rings if there are available rings */
+ MESSAGE_TYPE_MEMB_JOIN = 3, /* membership join message */
+ MESSAGE_TYPE_MEMB_COMMIT_TOKEN = 4, /* membership commit token */
+ MESSAGE_TYPE_TOKEN_HOLD_CANCEL = 5, /* cancel the holding of the token */
+};
+
+enum encapsulation_type {
+ MESSAGE_ENCAPSULATED = 1,
+ MESSAGE_NOT_ENCAPSULATED = 2
+};
+
+/*
+ * New membership algorithm local variables
+ */
+struct consensus_list_item {
+ struct srp_addr addr;
+ int set;
+};
+
+
+struct token_callback_instance {
+ struct qb_list_head list;
+ int (*callback_fn) (enum totem_callback_token_type type, const void *);
+ enum totem_callback_token_type callback_type;
+ int delete;
+ void *data;
+};
+
+
+struct totemsrp_socket {
+ int mcast;
+ int token;
+};
+
+struct mcast {
+ struct totem_message_header header;
+ struct srp_addr system_from;
+ unsigned int seq;
+ int this_seqno;
+ struct memb_ring_id ring_id;
+ unsigned int node_id;
+ int guarantee;
+} __attribute__((packed));
+
+
+struct rtr_item {
+ struct memb_ring_id ring_id;
+ unsigned int seq;
+}__attribute__((packed));
+
+
+struct orf_token {
+ struct totem_message_header header;
+ unsigned int seq;
+ unsigned int token_seq;
+ unsigned int aru;
+ unsigned int aru_addr;
+ struct memb_ring_id ring_id;
+ unsigned int backlog;
+ unsigned int fcc;
+ int retrans_flg;
+ int rtr_list_entries;
+ struct rtr_item rtr_list[0];
+}__attribute__((packed));
+
+
+struct memb_join {
+ struct totem_message_header header;
+ struct srp_addr system_from;
+ unsigned int proc_list_entries;
+ unsigned int failed_list_entries;
+ unsigned long long ring_seq;
+ unsigned char end_of_memb_join[0];
+/*
+ * These parts of the data structure are dynamic:
+ * struct srp_addr proc_list[];
+ * struct srp_addr failed_list[];
+ */
+} __attribute__((packed));
+
+
+struct memb_merge_detect {
+ struct totem_message_header header;
+ struct srp_addr system_from;
+ struct memb_ring_id ring_id;
+} __attribute__((packed));
+
+
+struct token_hold_cancel {
+ struct totem_message_header header;
+ struct memb_ring_id ring_id;
+} __attribute__((packed));
+
+
+struct memb_commit_token_memb_entry {
+ struct memb_ring_id ring_id;
+ unsigned int aru;
+ unsigned int high_delivered;
+ unsigned int received_flg;
+}__attribute__((packed));
+
+
+struct memb_commit_token {
+ struct totem_message_header header;
+ unsigned int token_seq;
+ struct memb_ring_id ring_id;
+ unsigned int retrans_flg;
+ int memb_index;
+ int addr_entries;
+ unsigned char end_of_commit_token[0];
+/*
+ * These parts of the data structure are dynamic:
+ *
+ * struct srp_addr addr[PROCESSOR_COUNT_MAX];
+ * struct memb_commit_token_memb_entry memb_list[PROCESSOR_COUNT_MAX];
+ */
+}__attribute__((packed));
+
+struct message_item {
+ struct mcast *mcast;
+ unsigned int msg_len;
+};
+
+struct sort_queue_item {
+ struct mcast *mcast;
+ unsigned int msg_len;
+};
+
+enum memb_state {
+ MEMB_STATE_OPERATIONAL = 1,
+ MEMB_STATE_GATHER = 2,
+ MEMB_STATE_COMMIT = 3,
+ MEMB_STATE_RECOVERY = 4
+};
+
+struct totemsrp_instance {
+ int iface_changes;
+
+ int failed_to_recv;
+
+ /*
+ * Flow control mcasts and remcasts on last and current orf_token
+ */
+ int fcc_remcast_last;
+
+ int fcc_mcast_last;
+
+ int fcc_remcast_current;
+
+ struct consensus_list_item consensus_list[PROCESSOR_COUNT_MAX];
+
+ int consensus_list_entries;
+
+ int lowest_active_if;
+
+ struct srp_addr my_id;
+
+ struct totem_ip_address my_addrs[INTERFACE_MAX];
+
+ struct srp_addr my_proc_list[PROCESSOR_COUNT_MAX];
+
+ struct srp_addr my_failed_list[PROCESSOR_COUNT_MAX];
+
+ struct srp_addr my_new_memb_list[PROCESSOR_COUNT_MAX];
+
+ struct srp_addr my_trans_memb_list[PROCESSOR_COUNT_MAX];
+
+ struct srp_addr my_memb_list[PROCESSOR_COUNT_MAX];
+
+ struct srp_addr my_deliver_memb_list[PROCESSOR_COUNT_MAX];
+
+ struct srp_addr my_left_memb_list[PROCESSOR_COUNT_MAX];
+
+ unsigned int my_leave_memb_list[PROCESSOR_COUNT_MAX];
+
+ int my_proc_list_entries;
+
+ int my_failed_list_entries;
+
+ int my_new_memb_entries;
+
+ int my_trans_memb_entries;
+
+ int my_memb_entries;
+
+ int my_deliver_memb_entries;
+
+ int my_left_memb_entries;
+
+ int my_leave_memb_entries;
+
+ struct memb_ring_id my_ring_id;
+
+ struct memb_ring_id my_old_ring_id;
+
+ int my_aru_count;
+
+ int my_merge_detect_timeout_outstanding;
+
+ unsigned int my_last_aru;
+
+ int my_seq_unchanged;
+
+ int my_received_flg;
+
+ unsigned int my_high_seq_received;
+
+ unsigned int my_install_seq;
+
+ int my_rotation_counter;
+
+ int my_set_retrans_flg;
+
+ int my_retrans_flg_count;
+
+ unsigned int my_high_ring_delivered;
+
+ int heartbeat_timeout;
+
+ /*
+ * Queues used to order, deliver, and recover messages
+ */
+ struct cs_queue new_message_queue;
+
+ struct cs_queue new_message_queue_trans;
+
+ struct cs_queue retrans_message_queue;
+
+ struct sq regular_sort_queue;
+
+ struct sq recovery_sort_queue;
+
+ /*
+ * Received up to and including
+ */
+ unsigned int my_aru;
+
+ unsigned int my_high_delivered;
+
+ struct qb_list_head token_callback_received_listhead;
+
+ struct qb_list_head token_callback_sent_listhead;
+
+ char orf_token_retransmit[TOKEN_SIZE_MAX];
+
+ int orf_token_retransmit_size;
+
+ unsigned int my_token_seq;
+
+ /*
+ * Timers
+ */
+ qb_loop_timer_handle timer_pause_timeout;
+
+ qb_loop_timer_handle timer_orf_token_timeout;
+
+ qb_loop_timer_handle timer_orf_token_warning;
+
+ qb_loop_timer_handle timer_orf_token_retransmit_timeout;
+
+ qb_loop_timer_handle timer_orf_token_hold_retransmit_timeout;
+
+ qb_loop_timer_handle timer_merge_detect_timeout;
+
+ qb_loop_timer_handle memb_timer_state_gather_join_timeout;
+
+ qb_loop_timer_handle memb_timer_state_gather_consensus_timeout;
+
+ qb_loop_timer_handle memb_timer_state_commit_timeout;
+
+ qb_loop_timer_handle timer_heartbeat_timeout;
+
+ /*
+ * Function and data used to log messages
+ */
+ int totemsrp_log_level_security;
+
+ int totemsrp_log_level_error;
+
+ int totemsrp_log_level_warning;
+
+ int totemsrp_log_level_notice;
+
+ int totemsrp_log_level_debug;
+
+ int totemsrp_log_level_trace;
+
+ int totemsrp_subsys_id;
+
+ void (*totemsrp_log_printf) (
+ int level,
+ int subsys,
+ const char *function,
+ const char *file,
+ int line,
+ const char *format, ...)__attribute__((format(printf, 6, 7)));;
+
+ enum memb_state memb_state;
+
+//TODO struct srp_addr next_memb;
+
+ qb_loop_t *totemsrp_poll_handle;
+
+ struct totem_ip_address mcast_address;
+
+ void (*totemsrp_deliver_fn) (
+ unsigned int nodeid,
+ const void *msg,
+ unsigned int msg_len,
+ int endian_conversion_required);
+
+ void (*totemsrp_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);
+
+ void (*totemsrp_service_ready_fn) (void);
+
+ void (*totemsrp_waiting_trans_ack_cb_fn) (
+ int waiting_trans_ack);
+
+ void (*memb_ring_id_create_or_load) (
+ struct memb_ring_id *memb_ring_id,
+ unsigned int nodeid);
+
+ void (*memb_ring_id_store) (
+ const struct memb_ring_id *memb_ring_id,
+ unsigned int nodeid);
+
+ int global_seqno;
+
+ int my_token_held;
+
+ unsigned long long token_ring_id_seq;
+
+ unsigned int last_released;
+
+ unsigned int set_aru;
+
+ int old_ring_state_saved;
+
+ int old_ring_state_aru;
+
+ unsigned int old_ring_state_high_seq_received;
+
+ unsigned int my_last_seq;
+
+ struct timeval tv_old;
+
+ void *totemnet_context;
+
+ struct totem_config *totem_config;
+
+ unsigned int use_heartbeat;
+
+ unsigned int my_trc;
+
+ unsigned int my_pbl;
+
+ unsigned int my_cbl;
+
+ uint64_t pause_timestamp;
+
+ struct memb_commit_token *commit_token;
+
+ totemsrp_stats_t stats;
+
+ uint32_t orf_token_discard;
+
+ uint32_t originated_orf_token;
+
+ uint32_t threaded_mode_enabled;
+
+ uint32_t waiting_trans_ack;
+
+ int flushing;
+
+ void * token_recv_event_handle;
+ void * token_sent_event_handle;
+ char commit_token_storage[40000];
+};
+
+struct message_handlers {
+ int count;
+ int (*handler_functions[6]) (
+ struct totemsrp_instance *instance,
+ const void *msg,
+ size_t msg_len,
+ int endian_conversion_needed);
+};
+
+enum gather_state_from {
+ TOTEMSRP_GSFROM_CONSENSUS_TIMEOUT = 0,
+ TOTEMSRP_GSFROM_GATHER_MISSING1 = 1,
+ TOTEMSRP_GSFROM_THE_TOKEN_WAS_LOST_IN_THE_OPERATIONAL_STATE = 2,
+ TOTEMSRP_GSFROM_THE_CONSENSUS_TIMEOUT_EXPIRED = 3,
+ TOTEMSRP_GSFROM_THE_TOKEN_WAS_LOST_IN_THE_COMMIT_STATE = 4,
+ TOTEMSRP_GSFROM_THE_TOKEN_WAS_LOST_IN_THE_RECOVERY_STATE = 5,
+ TOTEMSRP_GSFROM_FAILED_TO_RECEIVE = 6,
+ TOTEMSRP_GSFROM_FOREIGN_MESSAGE_IN_OPERATIONAL_STATE = 7,
+ TOTEMSRP_GSFROM_FOREIGN_MESSAGE_IN_GATHER_STATE = 8,
+ TOTEMSRP_GSFROM_MERGE_DURING_OPERATIONAL_STATE = 9,
+ TOTEMSRP_GSFROM_MERGE_DURING_GATHER_STATE = 10,
+ TOTEMSRP_GSFROM_MERGE_DURING_JOIN = 11,
+ TOTEMSRP_GSFROM_JOIN_DURING_OPERATIONAL_STATE = 12,
+ TOTEMSRP_GSFROM_JOIN_DURING_COMMIT_STATE = 13,
+ TOTEMSRP_GSFROM_JOIN_DURING_RECOVERY = 14,
+ TOTEMSRP_GSFROM_INTERFACE_CHANGE = 15,
+ TOTEMSRP_GSFROM_MAX = TOTEMSRP_GSFROM_INTERFACE_CHANGE,
+};
+
+const char* gather_state_from_desc [] = {
+ [TOTEMSRP_GSFROM_CONSENSUS_TIMEOUT] = "consensus timeout",
+ [TOTEMSRP_GSFROM_GATHER_MISSING1] = "MISSING",
+ [TOTEMSRP_GSFROM_THE_TOKEN_WAS_LOST_IN_THE_OPERATIONAL_STATE] = "The token was lost in the OPERATIONAL state.",
+ [TOTEMSRP_GSFROM_THE_CONSENSUS_TIMEOUT_EXPIRED] = "The consensus timeout expired.",
+ [TOTEMSRP_GSFROM_THE_TOKEN_WAS_LOST_IN_THE_COMMIT_STATE] = "The token was lost in the COMMIT state.",
+ [TOTEMSRP_GSFROM_THE_TOKEN_WAS_LOST_IN_THE_RECOVERY_STATE] = "The token was lost in the RECOVERY state.",
+ [TOTEMSRP_GSFROM_FAILED_TO_RECEIVE] = "failed to receive",
+ [TOTEMSRP_GSFROM_FOREIGN_MESSAGE_IN_OPERATIONAL_STATE] = "foreign message in operational state",
+ [TOTEMSRP_GSFROM_FOREIGN_MESSAGE_IN_GATHER_STATE] = "foreign message in gather state",
+ [TOTEMSRP_GSFROM_MERGE_DURING_OPERATIONAL_STATE] = "merge during operational state",
+ [TOTEMSRP_GSFROM_MERGE_DURING_GATHER_STATE] = "merge during gather state",
+ [TOTEMSRP_GSFROM_MERGE_DURING_JOIN] = "merge during join",
+ [TOTEMSRP_GSFROM_JOIN_DURING_OPERATIONAL_STATE] = "join during operational state",
+ [TOTEMSRP_GSFROM_JOIN_DURING_COMMIT_STATE] = "join during commit state",
+ [TOTEMSRP_GSFROM_JOIN_DURING_RECOVERY] = "join during recovery",
+ [TOTEMSRP_GSFROM_INTERFACE_CHANGE] = "interface change",
+};
+
+/*
+ * forward decls
+ */
+static int message_handler_orf_token (
+ struct totemsrp_instance *instance,
+ const void *msg,
+ size_t msg_len,
+ int endian_conversion_needed);
+
+static int message_handler_mcast (
+ struct totemsrp_instance *instance,
+ const void *msg,
+ size_t msg_len,
+ int endian_conversion_needed);
+
+static int message_handler_memb_merge_detect (
+ struct totemsrp_instance *instance,
+ const void *msg,
+ size_t msg_len,
+ int endian_conversion_needed);
+
+static int message_handler_memb_join (
+ struct totemsrp_instance *instance,
+ const void *msg,
+ size_t msg_len,
+ int endian_conversion_needed);
+
+static int message_handler_memb_commit_token (
+ struct totemsrp_instance *instance,
+ const void *msg,
+ size_t msg_len,
+ int endian_conversion_needed);
+
+static int message_handler_token_hold_cancel (
+ struct totemsrp_instance *instance,
+ const void *msg,
+ size_t msg_len,
+ int endian_conversion_needed);
+
+static void totemsrp_instance_initialize (struct totemsrp_instance *instance);
+
+static void srp_addr_to_nodeid (
+ struct totemsrp_instance *instance,
+ unsigned int *nodeid_out,
+ struct srp_addr *srp_addr_in,
+ unsigned int entries);
+
+static int srp_addr_equal (const struct srp_addr *a, const struct srp_addr *b);
+
+static void memb_leave_message_send (struct totemsrp_instance *instance);
+
+static void token_callbacks_execute (struct totemsrp_instance *instance, enum totem_callback_token_type type);
+static void memb_state_gather_enter (struct totemsrp_instance *instance, enum gather_state_from gather_from);
+static void messages_deliver_to_app (struct totemsrp_instance *instance, int skip, unsigned int end_point);
+static int orf_token_mcast (struct totemsrp_instance *instance, struct orf_token *oken,
+ int fcc_mcasts_allowed);
+static void messages_free (struct totemsrp_instance *instance, unsigned int token_aru);
+
+static void memb_ring_id_set (struct totemsrp_instance *instance,
+ const struct memb_ring_id *ring_id);
+static void target_set_completed (void *context);
+static void memb_state_commit_token_update (struct totemsrp_instance *instance);
+static void memb_state_commit_token_target_set (struct totemsrp_instance *instance);
+static int memb_state_commit_token_send (struct totemsrp_instance *instance);
+static int memb_state_commit_token_send_recovery (struct totemsrp_instance *instance, struct memb_commit_token *memb_commit_token);
+static void memb_state_commit_token_create (struct totemsrp_instance *instance);
+static int token_hold_cancel_send (struct totemsrp_instance *instance);
+static void orf_token_endian_convert (const struct orf_token *in, struct orf_token *out);
+static void memb_commit_token_endian_convert (const struct memb_commit_token *in, struct memb_commit_token *out);
+static void memb_join_endian_convert (const struct memb_join *in, struct memb_join *out);
+static void mcast_endian_convert (const struct mcast *in, struct mcast *out);
+static void memb_merge_detect_endian_convert (
+ const struct memb_merge_detect *in,
+ struct memb_merge_detect *out);
+static struct srp_addr srp_addr_endian_convert (struct srp_addr in);
+static void timer_function_orf_token_timeout (void *data);
+static void timer_function_orf_token_warning (void *data);
+static void timer_function_pause_timeout (void *data);
+static void timer_function_heartbeat_timeout (void *data);
+static void timer_function_token_retransmit_timeout (void *data);
+static void timer_function_token_hold_retransmit_timeout (void *data);
+static void timer_function_merge_detect_timeout (void *data);
+static void *totemsrp_buffer_alloc (struct totemsrp_instance *instance);
+static void totemsrp_buffer_release (struct totemsrp_instance *instance, void *ptr);
+static const char* gsfrom_to_msg(enum gather_state_from gsfrom);
+
+int main_deliver_fn (
+ void *context,
+ const void *msg,
+ unsigned int msg_len,
+ const struct sockaddr_storage *system_from);
+
+int main_iface_change_fn (
+ void *context,
+ const struct totem_ip_address *iface_address,
+ unsigned int iface_no);
+
+struct message_handlers totemsrp_message_handlers = {
+ 6,
+ {
+ message_handler_orf_token, /* MESSAGE_TYPE_ORF_TOKEN */
+ message_handler_mcast, /* MESSAGE_TYPE_MCAST */
+ message_handler_memb_merge_detect, /* MESSAGE_TYPE_MEMB_MERGE_DETECT */
+ message_handler_memb_join, /* MESSAGE_TYPE_MEMB_JOIN */
+ message_handler_memb_commit_token, /* MESSAGE_TYPE_MEMB_COMMIT_TOKEN */
+ message_handler_token_hold_cancel /* MESSAGE_TYPE_TOKEN_HOLD_CANCEL */
+ }
+};
+
+#define log_printf(level, format, args...) \
+do { \
+ instance->totemsrp_log_printf ( \
+ level, instance->totemsrp_subsys_id, \
+ __FUNCTION__, __FILE__, __LINE__, \
+ format, ##args); \
+} while (0);
+#define LOGSYS_PERROR(err_num, level, fmt, args...) \
+do { \
+ char _error_str[LOGSYS_MAX_PERROR_MSG_LEN]; \
+ const char *_error_ptr = qb_strerror_r(err_num, _error_str, sizeof(_error_str)); \
+ instance->totemsrp_log_printf ( \
+ level, instance->totemsrp_subsys_id, \
+ __FUNCTION__, __FILE__, __LINE__, \
+ fmt ": %s (%d)\n", ##args, _error_ptr, err_num); \
+ } while(0)
+
+static const char* gsfrom_to_msg(enum gather_state_from gsfrom)
+{
+ if (gsfrom <= TOTEMSRP_GSFROM_MAX) {
+ return gather_state_from_desc[gsfrom];
+ }
+ else {
+ return "UNKNOWN";
+ }
+}
+
+static void totemsrp_instance_initialize (struct totemsrp_instance *instance)
+{
+ memset (instance, 0, sizeof (struct totemsrp_instance));
+
+ qb_list_init (&instance->token_callback_received_listhead);
+
+ qb_list_init (&instance->token_callback_sent_listhead);
+
+ instance->my_received_flg = 1;
+
+ instance->my_token_seq = SEQNO_START_TOKEN - 1;
+
+ instance->memb_state = MEMB_STATE_OPERATIONAL;
+
+ instance->set_aru = -1;
+
+ instance->my_aru = SEQNO_START_MSG;
+
+ instance->my_high_seq_received = SEQNO_START_MSG;
+
+ instance->my_high_delivered = SEQNO_START_MSG;
+
+ instance->orf_token_discard = 0;
+
+ instance->originated_orf_token = 0;
+
+ instance->commit_token = (struct memb_commit_token *)instance->commit_token_storage;
+
+ instance->waiting_trans_ack = 1;
+}
+
+static int pause_flush (struct totemsrp_instance *instance)
+{
+ uint64_t now_msec;
+ uint64_t timestamp_msec;
+ int res = 0;
+
+ now_msec = (qb_util_nano_current_get () / QB_TIME_NS_IN_MSEC);
+ timestamp_msec = instance->pause_timestamp / QB_TIME_NS_IN_MSEC;
+
+ if ((now_msec - timestamp_msec) > (instance->totem_config->token_timeout / 2)) {
+ log_printf (instance->totemsrp_log_level_notice,
+ "Process pause detected for %d ms, flushing membership messages.", (unsigned int)(now_msec - timestamp_msec));
+ /*
+ * -1 indicates an error from recvmsg
+ */
+ do {
+ res = totemnet_recv_mcast_empty (instance->totemnet_context);
+ } while (res == -1);
+ }
+ return (res);
+}
+
+static int token_event_stats_collector (enum totem_callback_token_type type, const void *void_instance)
+{
+ struct totemsrp_instance *instance = (struct totemsrp_instance *)void_instance;
+ uint32_t time_now;
+ unsigned long long nano_secs = qb_util_nano_current_get ();
+
+ time_now = (nano_secs / QB_TIME_NS_IN_MSEC);
+
+ if (type == TOTEM_CALLBACK_TOKEN_RECEIVED) {
+ /* incr latest token the index */
+ if (instance->stats.latest_token == (TOTEM_TOKEN_STATS_MAX - 1))
+ instance->stats.latest_token = 0;
+ else
+ instance->stats.latest_token++;
+
+ if (instance->stats.earliest_token == instance->stats.latest_token) {
+ /* we have filled up the array, start overwriting */
+ if (instance->stats.earliest_token == (TOTEM_TOKEN_STATS_MAX - 1))
+ instance->stats.earliest_token = 0;
+ else
+ instance->stats.earliest_token++;
+
+ instance->stats.token[instance->stats.earliest_token].rx = 0;
+ instance->stats.token[instance->stats.earliest_token].tx = 0;
+ instance->stats.token[instance->stats.earliest_token].backlog_calc = 0;
+ }
+
+ instance->stats.token[instance->stats.latest_token].rx = time_now;
+ instance->stats.token[instance->stats.latest_token].tx = 0; /* in case we drop the token */
+ } else {
+ instance->stats.token[instance->stats.latest_token].tx = time_now;
+ }
+ return 0;
+}
+
+static void totempg_mtu_changed(void *context, int net_mtu)
+{
+ struct totemsrp_instance *instance = context;
+
+ instance->totem_config->net_mtu = net_mtu - 2 * sizeof (struct mcast);
+
+ log_printf (instance->totemsrp_log_level_debug,
+ "Net MTU changed to %d, new value is %d",
+ net_mtu, instance->totem_config->net_mtu);
+}
+
+/*
+ * Exported interfaces
+ */
+int totemsrp_initialize (
+ qb_loop_t *poll_handle,
+ void **srp_context,
+ struct totem_config *totem_config,
+ totempg_stats_t *stats,
+
+ void (*deliver_fn) (
+ unsigned int nodeid,
+ const void *msg,
+ unsigned int msg_len,
+ int endian_conversion_required),
+
+ void (*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),
+ void (*waiting_trans_ack_cb_fn) (
+ int waiting_trans_ack))
+{
+ struct totemsrp_instance *instance;
+ int res;
+
+ instance = malloc (sizeof (struct totemsrp_instance));
+ if (instance == NULL) {
+ goto error_exit;
+ }
+
+ totemsrp_instance_initialize (instance);
+
+ instance->totemsrp_waiting_trans_ack_cb_fn = waiting_trans_ack_cb_fn;
+ instance->totemsrp_waiting_trans_ack_cb_fn (1);
+
+ stats->srp = &instance->stats;
+ instance->stats.latest_token = 0;
+ instance->stats.earliest_token = 0;
+
+ instance->totem_config = totem_config;
+
+ /*
+ * Configure logging
+ */
+ instance->totemsrp_log_level_security = totem_config->totem_logging_configuration.log_level_security;
+ instance->totemsrp_log_level_error = totem_config->totem_logging_configuration.log_level_error;
+ instance->totemsrp_log_level_warning = totem_config->totem_logging_configuration.log_level_warning;
+ instance->totemsrp_log_level_notice = totem_config->totem_logging_configuration.log_level_notice;
+ instance->totemsrp_log_level_debug = totem_config->totem_logging_configuration.log_level_debug;
+ instance->totemsrp_log_level_trace = totem_config->totem_logging_configuration.log_level_trace;
+ instance->totemsrp_subsys_id = totem_config->totem_logging_configuration.log_subsys_id;
+ instance->totemsrp_log_printf = totem_config->totem_logging_configuration.log_printf;
+
+ /*
+ * Configure totem store and load functions
+ */
+ instance->memb_ring_id_create_or_load = totem_config->totem_memb_ring_id_create_or_load;
+ instance->memb_ring_id_store = totem_config->totem_memb_ring_id_store;
+
+ /*
+ * Initialize local variables for totemsrp
+ */
+ totemip_copy (&instance->mcast_address, &totem_config->interfaces[instance->lowest_active_if].mcast_addr);
+
+ /*
+ * Display totem configuration
+ */
+ log_printf (instance->totemsrp_log_level_debug,
+ "Token Timeout (%d ms) retransmit timeout (%d ms)",
+ totem_config->token_timeout, totem_config->token_retransmit_timeout);
+ if (totem_config->token_warning) {
+ uint32_t token_warning_ms = totem_config->token_warning * totem_config->token_timeout / 100;
+ log_printf(instance->totemsrp_log_level_debug,
+ "Token warning every %d ms (%d%% of Token Timeout)",
+ token_warning_ms, totem_config->token_warning);
+ if (token_warning_ms < totem_config->token_retransmit_timeout)
+ log_printf (LOGSYS_LEVEL_DEBUG,
+ "The token warning interval (%d ms) is less than the token retransmit timeout (%d ms) "
+ "which can lead to spurious token warnings. Consider increasing the token_warning parameter.",
+ token_warning_ms, totem_config->token_retransmit_timeout);
+ } else {
+ log_printf(instance->totemsrp_log_level_debug,
+ "Token warnings disabled");
+ }
+ log_printf (instance->totemsrp_log_level_debug,
+ "token hold (%d ms) retransmits before loss (%d retrans)",
+ totem_config->token_hold_timeout, totem_config->token_retransmits_before_loss_const);
+ log_printf (instance->totemsrp_log_level_debug,
+ "join (%d ms) send_join (%d ms) consensus (%d ms) merge (%d ms)",
+ totem_config->join_timeout,
+ totem_config->send_join_timeout,
+ totem_config->consensus_timeout,
+
+ totem_config->merge_timeout);
+ log_printf (instance->totemsrp_log_level_debug,
+ "downcheck (%d ms) fail to recv const (%d msgs)",
+ totem_config->downcheck_timeout, totem_config->fail_to_recv_const);
+ log_printf (instance->totemsrp_log_level_debug,
+ "seqno unchanged const (%d rotations) Maximum network MTU %d", totem_config->seqno_unchanged_const, totem_config->net_mtu);
+
+ log_printf (instance->totemsrp_log_level_debug,
+ "window size per rotation (%d messages) maximum messages per rotation (%d messages)",
+ totem_config->window_size, totem_config->max_messages);
+
+ log_printf (instance->totemsrp_log_level_debug,
+ "missed count const (%d messages)",
+ totem_config->miss_count_const);
+
+ log_printf (instance->totemsrp_log_level_debug,
+ "send threads (%d threads)", totem_config->threads);
+
+ log_printf (instance->totemsrp_log_level_debug,
+ "heartbeat_failures_allowed (%d)", totem_config->heartbeat_failures_allowed);
+ log_printf (instance->totemsrp_log_level_debug,
+ "max_network_delay (%d ms)", totem_config->max_network_delay);
+
+
+ cs_queue_init (&instance->retrans_message_queue, RETRANS_MESSAGE_QUEUE_SIZE_MAX,
+ sizeof (struct message_item), instance->threaded_mode_enabled);
+
+ sq_init (&instance->regular_sort_queue,
+ QUEUE_RTR_ITEMS_SIZE_MAX, sizeof (struct sort_queue_item), 0);
+
+ sq_init (&instance->recovery_sort_queue,
+ QUEUE_RTR_ITEMS_SIZE_MAX, sizeof (struct sort_queue_item), 0);
+
+ instance->totemsrp_poll_handle = poll_handle;
+
+ instance->totemsrp_deliver_fn = deliver_fn;
+
+ instance->totemsrp_confchg_fn = confchg_fn;
+ instance->use_heartbeat = 1;
+
+ timer_function_pause_timeout (instance);
+
+ if ( totem_config->heartbeat_failures_allowed == 0 ) {
+ log_printf (instance->totemsrp_log_level_debug,
+ "HeartBeat is Disabled. To enable set heartbeat_failures_allowed > 0");
+ instance->use_heartbeat = 0;
+ }
+
+ if (instance->use_heartbeat) {
+ instance->heartbeat_timeout
+ = (totem_config->heartbeat_failures_allowed) * totem_config->token_retransmit_timeout
+ + totem_config->max_network_delay;
+
+ if (instance->heartbeat_timeout >= totem_config->token_timeout) {
+ log_printf (instance->totemsrp_log_level_debug,
+ "total heartbeat_timeout (%d ms) is not less than token timeout (%d ms)",
+ instance->heartbeat_timeout,
+ totem_config->token_timeout);
+ log_printf (instance->totemsrp_log_level_debug,
+ "heartbeat_timeout = heartbeat_failures_allowed * token_retransmit_timeout + max_network_delay");
+ log_printf (instance->totemsrp_log_level_debug,
+ "heartbeat timeout should be less than the token timeout. Heartbeat is disabled!!");
+ instance->use_heartbeat = 0;
+ }
+ else {
+ log_printf (instance->totemsrp_log_level_debug,
+ "total heartbeat_timeout (%d ms)", instance->heartbeat_timeout);
+ }
+ }
+
+ res = totemnet_initialize (
+ poll_handle,
+ &instance->totemnet_context,
+ totem_config,
+ stats->srp,
+ instance,
+ main_deliver_fn,
+ main_iface_change_fn,
+ totempg_mtu_changed,
+ target_set_completed);
+ if (res == -1) {
+ goto error_exit;
+ }
+
+ instance->my_id.nodeid = instance->totem_config->interfaces[instance->lowest_active_if].boundto.nodeid;
+
+ /*
+ * Must have net_mtu adjusted by totemnet_initialize first
+ */
+ cs_queue_init (&instance->new_message_queue,
+ MESSAGE_QUEUE_MAX,
+ sizeof (struct message_item), instance->threaded_mode_enabled);
+
+ cs_queue_init (&instance->new_message_queue_trans,
+ MESSAGE_QUEUE_MAX,
+ sizeof (struct message_item), instance->threaded_mode_enabled);
+
+ totemsrp_callback_token_create (instance,
+ &instance->token_recv_event_handle,
+ TOTEM_CALLBACK_TOKEN_RECEIVED,
+ 0,
+ token_event_stats_collector,
+ instance);
+ totemsrp_callback_token_create (instance,
+ &instance->token_sent_event_handle,
+ TOTEM_CALLBACK_TOKEN_SENT,
+ 0,
+ token_event_stats_collector,
+ instance);
+ *srp_context = instance;
+ return (0);
+
+error_exit:
+ return (-1);
+}
+
+void totemsrp_finalize (
+ void *srp_context)
+{
+ struct totemsrp_instance *instance = (struct totemsrp_instance *)srp_context;
+
+ memb_leave_message_send (instance);
+ totemnet_finalize (instance->totemnet_context);
+ cs_queue_free (&instance->new_message_queue);
+ cs_queue_free (&instance->new_message_queue_trans);
+ cs_queue_free (&instance->retrans_message_queue);
+ sq_free (&instance->regular_sort_queue);
+ sq_free (&instance->recovery_sort_queue);
+ free (instance);
+}
+
+int totemsrp_nodestatus_get (
+ void *srp_context,
+ unsigned int nodeid,
+ struct totem_node_status *node_status)
+{
+ struct totemsrp_instance *instance = (struct totemsrp_instance *)srp_context;
+ int i;
+
+ node_status->version = TOTEM_NODE_STATUS_STRUCTURE_VERSION;
+
+ /* Fill in 'reachable' here as the lower level UDP[u] layers don't know */
+ for (i = 0; i < instance->my_proc_list_entries; i++) {
+ if (instance->my_proc_list[i].nodeid == nodeid) {
+ node_status->reachable = 1;
+ }
+ }
+
+ return totemnet_nodestatus_get(instance->totemnet_context, nodeid, node_status);
+}
+
+
+/*
+ * Return configured interfaces. interfaces is array of totem_ip addresses allocated by caller,
+ * with interaces_size number of items. iface_count is final number of interfaces filled by this
+ * function.
+ *
+ * Function returns 0 on success, otherwise if interfaces array is not big enough, -2 is returned,
+ * and if interface was not found, -1 is returned.
+ */
+int totemsrp_ifaces_get (
+ void *srp_context,
+ unsigned int nodeid,
+ unsigned int *interface_id,
+ struct totem_ip_address *interfaces,
+ unsigned int interfaces_size,
+ char ***status,
+ unsigned int *iface_count)
+{
+ struct totemsrp_instance *instance = (struct totemsrp_instance *)srp_context;
+ struct totem_ip_address *iface_ptr = interfaces;
+ int res = 0;
+ int i,n;
+ int num_ifs = 0;
+
+ memset(interfaces, 0, sizeof(struct totem_ip_address) * interfaces_size);
+ *iface_count = INTERFACE_MAX;
+
+ for (i=0; i<INTERFACE_MAX; i++) {
+ for (n=0; n < instance->totem_config->interfaces[i].member_count; n++) {
+ if (instance->totem_config->interfaces[i].configured &&
+ instance->totem_config->interfaces[i].member_list[n].nodeid == nodeid) {
+ memcpy(iface_ptr, &instance->totem_config->interfaces[i].member_list[n], sizeof(struct totem_ip_address));
+ interface_id[num_ifs] = i;
+ iface_ptr++;
+ if (++num_ifs > interfaces_size) {
+ res = -2;
+ break;
+ }
+ }
+ }
+ }
+
+ totemnet_ifaces_get(instance->totemnet_context, status, iface_count);
+ *iface_count = num_ifs;
+ return (res);
+}
+
+int totemsrp_crypto_set (
+ void *srp_context,
+ const char *cipher_type,
+ const char *hash_type)
+{
+ struct totemsrp_instance *instance = (struct totemsrp_instance *)srp_context;
+ int res;
+
+ res = totemnet_crypto_set(instance->totemnet_context, cipher_type, hash_type);
+
+ return (res);
+}
+
+
+unsigned int totemsrp_my_nodeid_get (
+ void *srp_context)
+{
+ struct totemsrp_instance *instance = (struct totemsrp_instance *)srp_context;
+ unsigned int res;
+
+ res = instance->my_id.nodeid;
+
+ return (res);
+}
+
+int totemsrp_my_family_get (
+ void *srp_context)
+{
+ struct totemsrp_instance *instance = (struct totemsrp_instance *)srp_context;
+ int res;
+
+ res = instance->totem_config->interfaces[instance->lowest_active_if].boundto.family;
+
+ return (res);
+}
+
+
+/*
+ * Set operations for use by the membership algorithm
+ */
+static int srp_addr_equal (const struct srp_addr *a, const struct srp_addr *b)
+{
+ if (a->nodeid == b->nodeid) {
+ return 1;
+ }
+ return 0;
+}
+
+static void srp_addr_to_nodeid (
+ struct totemsrp_instance *instance,
+ unsigned int *nodeid_out,
+ struct srp_addr *srp_addr_in,
+ unsigned int entries)
+{
+ unsigned int i;
+
+ for (i = 0; i < entries; i++) {
+ nodeid_out[i] = srp_addr_in[i].nodeid;
+ }
+}
+
+static struct srp_addr srp_addr_endian_convert (struct srp_addr in)
+{
+ struct srp_addr res;
+
+ res.nodeid = swab32 (in.nodeid);
+
+ return (res);
+}
+
+static void memb_consensus_reset (struct totemsrp_instance *instance)
+{
+ instance->consensus_list_entries = 0;
+}
+
+static void memb_set_subtract (
+ struct srp_addr *out_list, int *out_list_entries,
+ struct srp_addr *one_list, int one_list_entries,
+ struct srp_addr *two_list, int two_list_entries)
+{
+ int found = 0;
+ int i;
+ int j;
+
+ *out_list_entries = 0;
+
+ for (i = 0; i < one_list_entries; i++) {
+ for (j = 0; j < two_list_entries; j++) {
+ if (srp_addr_equal (&one_list[i], &two_list[j])) {
+ found = 1;
+ break;
+ }
+ }
+ if (found == 0) {
+ out_list[*out_list_entries] = one_list[i];
+ *out_list_entries = *out_list_entries + 1;
+ }
+ found = 0;
+ }
+}
+
+/*
+ * Set consensus for a specific processor
+ */
+static void memb_consensus_set (
+ struct totemsrp_instance *instance,
+ const struct srp_addr *addr)
+{
+ int found = 0;
+ int i;
+
+ for (i = 0; i < instance->consensus_list_entries; i++) {
+ if (srp_addr_equal(addr, &instance->consensus_list[i].addr)) {
+ found = 1;
+ break; /* found entry */
+ }
+ }
+ instance->consensus_list[i].addr = *addr;
+ instance->consensus_list[i].set = 1;
+ if (found == 0) {
+ instance->consensus_list_entries++;
+ }
+ return;
+}
+
+/*
+ * Is consensus set for a specific processor
+ */
+static int memb_consensus_isset (
+ struct totemsrp_instance *instance,
+ const struct srp_addr *addr)
+{
+ int i;
+
+ for (i = 0; i < instance->consensus_list_entries; i++) {
+ if (srp_addr_equal (addr, &instance->consensus_list[i].addr)) {
+ return (instance->consensus_list[i].set);
+ }
+ }
+ return (0);
+}
+
+/*
+ * Is consensus agreed upon based upon consensus database
+ */
+static int memb_consensus_agreed (
+ struct totemsrp_instance *instance)
+{
+ struct srp_addr token_memb[PROCESSOR_COUNT_MAX];
+ int token_memb_entries = 0;
+ int agreed = 1;
+ int i;
+
+ memb_set_subtract (token_memb, &token_memb_entries,
+ instance->my_proc_list, instance->my_proc_list_entries,
+ instance->my_failed_list, instance->my_failed_list_entries);
+
+ for (i = 0; i < token_memb_entries; i++) {
+ if (memb_consensus_isset (instance, &token_memb[i]) == 0) {
+ agreed = 0;
+ break;
+ }
+ }
+
+ if (agreed && instance->failed_to_recv == 1) {
+ /*
+ * Both nodes agreed on our failure. We don't care how many proc list items left because we
+ * will create single ring anyway.
+ */
+
+ return (agreed);
+ }
+
+ assert (token_memb_entries >= 1);
+
+ return (agreed);
+}
+
+static void memb_consensus_notset (
+ struct totemsrp_instance *instance,
+ struct srp_addr *no_consensus_list,
+ int *no_consensus_list_entries,
+ struct srp_addr *comparison_list,
+ int comparison_list_entries)
+{
+ int i;
+
+ *no_consensus_list_entries = 0;
+
+ for (i = 0; i < instance->my_proc_list_entries; i++) {
+ if (memb_consensus_isset (instance, &instance->my_proc_list[i]) == 0) {
+ no_consensus_list[*no_consensus_list_entries] = instance->my_proc_list[i];
+ *no_consensus_list_entries = *no_consensus_list_entries + 1;
+ }
+ }
+}
+
+/*
+ * Is set1 equal to set2 Entries can be in different orders
+ */
+static int memb_set_equal (
+ struct srp_addr *set1, int set1_entries,
+ struct srp_addr *set2, int set2_entries)
+{
+ int i;
+ int j;
+
+ int found = 0;
+
+ if (set1_entries != set2_entries) {
+ return (0);
+ }
+ for (i = 0; i < set2_entries; i++) {
+ for (j = 0; j < set1_entries; j++) {
+ if (srp_addr_equal (&set1[j], &set2[i])) {
+ found = 1;
+ break;
+ }
+ }
+ if (found == 0) {
+ return (0);
+ }
+ found = 0;
+ }
+ return (1);
+}
+
+/*
+ * Is subset fully contained in fullset
+ */
+static int memb_set_subset (
+ const struct srp_addr *subset, int subset_entries,
+ const struct srp_addr *fullset, int fullset_entries)
+{
+ int i;
+ int j;
+ int found = 0;
+
+ if (subset_entries > fullset_entries) {
+ return (0);
+ }
+ for (i = 0; i < subset_entries; i++) {
+ for (j = 0; j < fullset_entries; j++) {
+ if (srp_addr_equal (&subset[i], &fullset[j])) {
+ found = 1;
+ }
+ }
+ if (found == 0) {
+ return (0);
+ }
+ found = 0;
+ }
+ return (1);
+}
+/*
+ * merge subset into fullset taking care not to add duplicates
+ */
+static void memb_set_merge (
+ const struct srp_addr *subset, int subset_entries,
+ struct srp_addr *fullset, int *fullset_entries)
+{
+ int found = 0;
+ int i;
+ int j;
+
+ for (i = 0; i < subset_entries; i++) {
+ for (j = 0; j < *fullset_entries; j++) {
+ if (srp_addr_equal (&fullset[j], &subset[i])) {
+ found = 1;
+ break;
+ }
+ }
+ if (found == 0) {
+ fullset[*fullset_entries] = subset[i];
+ *fullset_entries = *fullset_entries + 1;
+ }
+ found = 0;
+ }
+ return;
+}
+
+static void memb_set_and_with_ring_id (
+ struct srp_addr *set1,
+ struct memb_ring_id *set1_ring_ids,
+ int set1_entries,
+ struct srp_addr *set2,
+ int set2_entries,
+ struct memb_ring_id *old_ring_id,
+ struct srp_addr *and,
+ int *and_entries)
+{
+ int i;
+ int j;
+ int found = 0;
+
+ *and_entries = 0;
+
+ for (i = 0; i < set2_entries; i++) {
+ for (j = 0; j < set1_entries; j++) {
+ if (srp_addr_equal (&set1[j], &set2[i])) {
+ if (memcmp (&set1_ring_ids[j], old_ring_id, sizeof (struct memb_ring_id)) == 0) {
+ found = 1;
+ }
+ break;
+ }
+ }
+ if (found) {
+ and[*and_entries] = set1[j];
+ *and_entries = *and_entries + 1;
+ }
+ found = 0;
+ }
+ return;
+}
+
+static void memb_set_log(
+ struct totemsrp_instance *instance,
+ int level,
+ const char *string,
+ struct srp_addr *list,
+ int list_entries)
+{
+ char int_buf[32];
+ char list_str[512];
+ int i;
+
+ memset(list_str, 0, sizeof(list_str));
+
+ for (i = 0; i < list_entries; i++) {
+ if (i == 0) {
+ snprintf(int_buf, sizeof(int_buf), CS_PRI_NODE_ID, list[i].nodeid);
+ } else {
+ snprintf(int_buf, sizeof(int_buf), "," CS_PRI_NODE_ID, list[i].nodeid);
+ }
+
+ if (strlen(list_str) + strlen(int_buf) >= sizeof(list_str)) {
+ break ;
+ }
+ strcat(list_str, int_buf);
+ }
+
+ log_printf(level, "List '%s' contains %d entries: %s", string, list_entries, list_str);
+}
+
+static void my_leave_memb_clear(
+ struct totemsrp_instance *instance)
+{
+ memset(instance->my_leave_memb_list, 0, sizeof(instance->my_leave_memb_list));
+ instance->my_leave_memb_entries = 0;
+}
+
+static unsigned int my_leave_memb_match(
+ struct totemsrp_instance *instance,
+ unsigned int nodeid)
+{
+ int i;
+ unsigned int ret = 0;
+
+ for (i = 0; i < instance->my_leave_memb_entries; i++){
+ if (instance->my_leave_memb_list[i] == nodeid){
+ ret = nodeid;
+ break;
+ }
+ }
+ return ret;
+}
+
+static void my_leave_memb_set(
+ struct totemsrp_instance *instance,
+ unsigned int nodeid)
+{
+ int i, found = 0;
+ for (i = 0; i < instance->my_leave_memb_entries; i++){
+ if (instance->my_leave_memb_list[i] == nodeid){
+ found = 1;
+ break;
+ }
+ }
+ if (found == 1) {
+ return;
+ }
+ if (instance->my_leave_memb_entries < (PROCESSOR_COUNT_MAX - 1)) {
+ instance->my_leave_memb_list[instance->my_leave_memb_entries] = nodeid;
+ instance->my_leave_memb_entries++;
+ } else {
+ log_printf (instance->totemsrp_log_level_warning,
+ "Cannot set LEAVE nodeid=" CS_PRI_NODE_ID, nodeid);
+ }
+}
+
+
+static void *totemsrp_buffer_alloc (struct totemsrp_instance *instance)
+{
+ assert (instance != NULL);
+ return totemnet_buffer_alloc (instance->totemnet_context);
+}
+
+static void totemsrp_buffer_release (struct totemsrp_instance *instance, void *ptr)
+{
+ assert (instance != NULL);
+ totemnet_buffer_release (instance->totemnet_context, ptr);
+}
+
+static void reset_token_retransmit_timeout (struct totemsrp_instance *instance)
+{
+ int32_t res;
+
+ qb_loop_timer_del (instance->totemsrp_poll_handle,
+ instance->timer_orf_token_retransmit_timeout);
+ res = qb_loop_timer_add (instance->totemsrp_poll_handle,
+ QB_LOOP_MED,
+ instance->totem_config->token_retransmit_timeout*QB_TIME_NS_IN_MSEC,
+ (void *)instance,
+ timer_function_token_retransmit_timeout,
+ &instance->timer_orf_token_retransmit_timeout);
+ if (res != 0) {
+ log_printf(instance->totemsrp_log_level_error, "reset_token_retransmit_timeout - qb_loop_timer_add error : %d", res);
+ }
+
+}
+
+static void start_merge_detect_timeout (struct totemsrp_instance *instance)
+{
+ int32_t res;
+
+ if (instance->my_merge_detect_timeout_outstanding == 0) {
+ res = qb_loop_timer_add (instance->totemsrp_poll_handle,
+ QB_LOOP_MED,
+ instance->totem_config->merge_timeout*QB_TIME_NS_IN_MSEC,
+ (void *)instance,
+ timer_function_merge_detect_timeout,
+ &instance->timer_merge_detect_timeout);
+ if (res != 0) {
+ log_printf(instance->totemsrp_log_level_error, "start_merge_detect_timeout - qb_loop_timer_add error : %d", res);
+ }
+
+ instance->my_merge_detect_timeout_outstanding = 1;
+ }
+}
+
+static void cancel_merge_detect_timeout (struct totemsrp_instance *instance)
+{
+ qb_loop_timer_del (instance->totemsrp_poll_handle, instance->timer_merge_detect_timeout);
+ instance->my_merge_detect_timeout_outstanding = 0;
+}
+
+/*
+ * ring_state_* is used to save and restore the sort queue
+ * state when a recovery operation fails (and enters gather)
+ */
+static void old_ring_state_save (struct totemsrp_instance *instance)
+{
+ if (instance->old_ring_state_saved == 0) {
+ instance->old_ring_state_saved = 1;
+ memcpy (&instance->my_old_ring_id, &instance->my_ring_id,
+ sizeof (struct memb_ring_id));
+ instance->old_ring_state_aru = instance->my_aru;
+ instance->old_ring_state_high_seq_received = instance->my_high_seq_received;
+ log_printf (instance->totemsrp_log_level_debug,
+ "Saving state aru %x high seq received %x",
+ instance->my_aru, instance->my_high_seq_received);
+ }
+}
+
+static void old_ring_state_restore (struct totemsrp_instance *instance)
+{
+ instance->my_aru = instance->old_ring_state_aru;
+ instance->my_high_seq_received = instance->old_ring_state_high_seq_received;
+ log_printf (instance->totemsrp_log_level_debug,
+ "Restoring instance->my_aru %x my high seq received %x",
+ instance->my_aru, instance->my_high_seq_received);
+}
+
+static void old_ring_state_reset (struct totemsrp_instance *instance)
+{
+ log_printf (instance->totemsrp_log_level_debug,
+ "Resetting old ring state");
+ instance->old_ring_state_saved = 0;
+}
+
+static void reset_pause_timeout (struct totemsrp_instance *instance)
+{
+ int32_t res;
+
+ qb_loop_timer_del (instance->totemsrp_poll_handle, instance->timer_pause_timeout);
+ res = qb_loop_timer_add (instance->totemsrp_poll_handle,
+ QB_LOOP_MED,
+ instance->totem_config->token_timeout * QB_TIME_NS_IN_MSEC / 5,
+ (void *)instance,
+ timer_function_pause_timeout,
+ &instance->timer_pause_timeout);
+ if (res != 0) {
+ log_printf(instance->totemsrp_log_level_error, "reset_pause_timeout - qb_loop_timer_add error : %d", res);
+ }
+}
+
+static void reset_token_warning (struct totemsrp_instance *instance) {
+ int32_t res;
+
+ qb_loop_timer_del (instance->totemsrp_poll_handle, instance->timer_orf_token_warning);
+ res = qb_loop_timer_add (instance->totemsrp_poll_handle,
+ QB_LOOP_MED,
+ instance->totem_config->token_warning * instance->totem_config->token_timeout / 100 * QB_TIME_NS_IN_MSEC,
+ (void *)instance,
+ timer_function_orf_token_warning,
+ &instance->timer_orf_token_warning);
+ if (res != 0) {
+ log_printf(instance->totemsrp_log_level_error, "reset_token_warning - qb_loop_timer_add error : %d", res);
+ }
+}
+
+static void reset_token_timeout (struct totemsrp_instance *instance) {
+ int32_t res;
+
+ qb_loop_timer_del (instance->totemsrp_poll_handle, instance->timer_orf_token_timeout);
+ res = qb_loop_timer_add (instance->totemsrp_poll_handle,
+ QB_LOOP_MED,
+ instance->totem_config->token_timeout*QB_TIME_NS_IN_MSEC,
+ (void *)instance,
+ timer_function_orf_token_timeout,
+ &instance->timer_orf_token_timeout);
+ if (res != 0) {
+ log_printf(instance->totemsrp_log_level_error, "reset_token_timeout - qb_loop_timer_add error : %d", res);
+ }
+
+ if (instance->totem_config->token_warning)
+ reset_token_warning(instance);
+}
+
+static void reset_heartbeat_timeout (struct totemsrp_instance *instance) {
+ int32_t res;
+
+ qb_loop_timer_del (instance->totemsrp_poll_handle, instance->timer_heartbeat_timeout);
+ res = qb_loop_timer_add (instance->totemsrp_poll_handle,
+ QB_LOOP_MED,
+ instance->heartbeat_timeout*QB_TIME_NS_IN_MSEC,
+ (void *)instance,
+ timer_function_heartbeat_timeout,
+ &instance->timer_heartbeat_timeout);
+ if (res != 0) {
+ log_printf(instance->totemsrp_log_level_error, "reset_heartbeat_timeout - qb_loop_timer_add error : %d", res);
+ }
+}
+
+
+static void cancel_token_warning (struct totemsrp_instance *instance) {
+ qb_loop_timer_del (instance->totemsrp_poll_handle, instance->timer_orf_token_warning);
+}
+
+static void cancel_token_timeout (struct totemsrp_instance *instance) {
+ qb_loop_timer_del (instance->totemsrp_poll_handle, instance->timer_orf_token_timeout);
+
+ if (instance->totem_config->token_warning)
+ cancel_token_warning(instance);
+}
+
+static void cancel_heartbeat_timeout (struct totemsrp_instance *instance) {
+ qb_loop_timer_del (instance->totemsrp_poll_handle, instance->timer_heartbeat_timeout);
+}
+
+static void cancel_token_retransmit_timeout (struct totemsrp_instance *instance)
+{
+ qb_loop_timer_del (instance->totemsrp_poll_handle, instance->timer_orf_token_retransmit_timeout);
+}
+
+static void start_token_hold_retransmit_timeout (struct totemsrp_instance *instance)
+{
+ int32_t res;
+
+ res = qb_loop_timer_add (instance->totemsrp_poll_handle,
+ QB_LOOP_MED,
+ instance->totem_config->token_hold_timeout*QB_TIME_NS_IN_MSEC,
+ (void *)instance,
+ timer_function_token_hold_retransmit_timeout,
+ &instance->timer_orf_token_hold_retransmit_timeout);
+ if (res != 0) {
+ log_printf(instance->totemsrp_log_level_error, "start_token_hold_retransmit_timeout - qb_loop_timer_add error : %d", res);
+ }
+}
+
+static void cancel_token_hold_retransmit_timeout (struct totemsrp_instance *instance)
+{
+ qb_loop_timer_del (instance->totemsrp_poll_handle,
+ instance->timer_orf_token_hold_retransmit_timeout);
+}
+
+static void memb_state_consensus_timeout_expired (
+ struct totemsrp_instance *instance)
+{
+ struct srp_addr no_consensus_list[PROCESSOR_COUNT_MAX];
+ int no_consensus_list_entries;
+
+ instance->stats.consensus_timeouts++;
+ if (memb_consensus_agreed (instance)) {
+ memb_consensus_reset (instance);
+
+ memb_consensus_set (instance, &instance->my_id);
+
+ reset_token_timeout (instance); // REVIEWED
+ } else {
+ memb_consensus_notset (
+ instance,
+ no_consensus_list,
+ &no_consensus_list_entries,
+ instance->my_proc_list,
+ instance->my_proc_list_entries);
+
+ memb_set_merge (no_consensus_list, no_consensus_list_entries,
+ instance->my_failed_list, &instance->my_failed_list_entries);
+ memb_state_gather_enter (instance, TOTEMSRP_GSFROM_CONSENSUS_TIMEOUT);
+ }
+}
+
+static void memb_join_message_send (struct totemsrp_instance *instance);
+
+static void memb_merge_detect_transmit (struct totemsrp_instance *instance);
+
+/*
+ * Timers used for various states of the membership algorithm
+ */
+static void timer_function_pause_timeout (void *data)
+{
+ struct totemsrp_instance *instance = data;
+
+ instance->pause_timestamp = qb_util_nano_current_get ();
+ reset_pause_timeout (instance);
+}
+
+static void memb_recovery_state_token_loss (struct totemsrp_instance *instance)
+{
+ old_ring_state_restore (instance);
+ memb_state_gather_enter (instance, TOTEMSRP_GSFROM_THE_TOKEN_WAS_LOST_IN_THE_RECOVERY_STATE);
+ instance->stats.recovery_token_lost++;
+}
+
+static void timer_function_orf_token_warning (void *data)
+{
+ struct totemsrp_instance *instance = data;
+ uint64_t tv_diff;
+
+ /* need to protect against the case where token_warning is set to 0 dynamically */
+ if (instance->totem_config->token_warning) {
+ tv_diff = qb_util_nano_current_get () / QB_TIME_NS_IN_MSEC -
+ instance->stats.token[instance->stats.latest_token].rx;
+ log_printf (instance->totemsrp_log_level_notice,
+ "Token has not been received in %d ms ", (unsigned int) tv_diff);
+ reset_token_warning(instance);
+ } else {
+ cancel_token_warning(instance);
+ }
+}
+
+static void timer_function_orf_token_timeout (void *data)
+{
+ struct totemsrp_instance *instance = data;
+
+ switch (instance->memb_state) {
+ case MEMB_STATE_OPERATIONAL:
+ log_printf (instance->totemsrp_log_level_debug,
+ "The token was lost in the OPERATIONAL state.");
+ log_printf (instance->totemsrp_log_level_notice,
+ "A processor failed, forming new configuration:"
+ " token timed out (%ums), waiting %ums for consensus.",
+ instance->totem_config->token_timeout,
+ instance->totem_config->consensus_timeout);
+ totemnet_iface_check (instance->totemnet_context);
+ memb_state_gather_enter (instance, TOTEMSRP_GSFROM_THE_TOKEN_WAS_LOST_IN_THE_OPERATIONAL_STATE);
+ instance->stats.operational_token_lost++;
+ break;
+
+ case MEMB_STATE_GATHER:
+ log_printf (instance->totemsrp_log_level_debug,
+ "The consensus timeout expired (%ums).",
+ instance->totem_config->consensus_timeout);
+ memb_state_consensus_timeout_expired (instance);
+ memb_state_gather_enter (instance, TOTEMSRP_GSFROM_THE_CONSENSUS_TIMEOUT_EXPIRED);
+ instance->stats.gather_token_lost++;
+ break;
+
+ case MEMB_STATE_COMMIT:
+ log_printf (instance->totemsrp_log_level_debug,
+ "The token was lost in the COMMIT state.");
+ memb_state_gather_enter (instance, TOTEMSRP_GSFROM_THE_TOKEN_WAS_LOST_IN_THE_COMMIT_STATE);
+ instance->stats.commit_token_lost++;
+ break;
+
+ case MEMB_STATE_RECOVERY:
+ log_printf (instance->totemsrp_log_level_debug,
+ "The token was lost in the RECOVERY state.");
+ memb_recovery_state_token_loss (instance);
+ instance->orf_token_discard = 1;
+ break;
+ }
+}
+
+static void timer_function_heartbeat_timeout (void *data)
+{
+ struct totemsrp_instance *instance = data;
+ log_printf (instance->totemsrp_log_level_debug,
+ "HeartBeat Timer expired Invoking token loss mechanism in state %d ", instance->memb_state);
+ timer_function_orf_token_timeout(data);
+}
+
+static void memb_timer_function_state_gather (void *data)
+{
+ struct totemsrp_instance *instance = data;
+ int32_t res;
+
+ switch (instance->memb_state) {
+ case MEMB_STATE_OPERATIONAL:
+ case MEMB_STATE_RECOVERY:
+ assert (0); /* this should never happen */
+ break;
+ case MEMB_STATE_GATHER:
+ case MEMB_STATE_COMMIT:
+ memb_join_message_send (instance);
+
+ /*
+ * Restart the join timeout
+ `*/
+ qb_loop_timer_del (instance->totemsrp_poll_handle, instance->memb_timer_state_gather_join_timeout);
+
+ res = qb_loop_timer_add (instance->totemsrp_poll_handle,
+ QB_LOOP_MED,
+ instance->totem_config->join_timeout*QB_TIME_NS_IN_MSEC,
+ (void *)instance,
+ memb_timer_function_state_gather,
+ &instance->memb_timer_state_gather_join_timeout);
+
+ if (res != 0) {
+ log_printf(instance->totemsrp_log_level_error, "memb_timer_function_state_gather - qb_loop_timer_add error : %d", res);
+ }
+ break;
+ }
+}
+
+static void memb_timer_function_gather_consensus_timeout (void *data)
+{
+ struct totemsrp_instance *instance = data;
+ memb_state_consensus_timeout_expired (instance);
+}
+
+static void deliver_messages_from_recovery_to_regular (struct totemsrp_instance *instance)
+{
+ unsigned int i;
+ struct sort_queue_item *recovery_message_item;
+ struct sort_queue_item regular_message_item;
+ unsigned int range = 0;
+ int res;
+ void *ptr;
+ struct mcast *mcast;
+
+ log_printf (instance->totemsrp_log_level_debug,
+ "recovery to regular %x-%x", SEQNO_START_MSG + 1, instance->my_aru);
+
+ range = instance->my_aru - SEQNO_START_MSG;
+ /*
+ * Move messages from recovery to regular sort queue
+ */
+// todo should i be initialized to 0 or 1 ?
+ for (i = 1; i <= range; i++) {
+ res = sq_item_get (&instance->recovery_sort_queue,
+ i + SEQNO_START_MSG, &ptr);
+ if (res != 0) {
+ continue;
+ }
+ recovery_message_item = ptr;
+
+ /*
+ * Convert recovery message into regular message
+ */
+ mcast = recovery_message_item->mcast;
+ if (mcast->header.encapsulated == MESSAGE_ENCAPSULATED) {
+ /*
+ * Message is a recovery message encapsulated
+ * in a new ring message
+ */
+ regular_message_item.mcast =
+ (struct mcast *)(((char *)recovery_message_item->mcast) + sizeof (struct mcast));
+ regular_message_item.msg_len =
+ recovery_message_item->msg_len - sizeof (struct mcast);
+ mcast = regular_message_item.mcast;
+ } else {
+ /*
+ * TODO this case shouldn't happen
+ */
+ continue;
+ }
+
+ log_printf (instance->totemsrp_log_level_debug,
+ "comparing if ring id is for this processors old ring seqno " CS_PRI_RING_ID_SEQ,
+ (uint64_t)mcast->seq);
+
+ /*
+ * Only add this message to the regular sort
+ * queue if it was originated with the same ring
+ * id as the previous ring
+ */
+ if (memcmp (&instance->my_old_ring_id, &mcast->ring_id,
+ sizeof (struct memb_ring_id)) == 0) {
+
+ res = sq_item_inuse (&instance->regular_sort_queue, mcast->seq);
+ if (res == 0) {
+ sq_item_add (&instance->regular_sort_queue,
+ &regular_message_item, mcast->seq);
+ if (sq_lt_compare (instance->old_ring_state_high_seq_received, mcast->seq)) {
+ instance->old_ring_state_high_seq_received = mcast->seq;
+ }
+ }
+ } else {
+ log_printf (instance->totemsrp_log_level_debug,
+ "-not adding msg with seq no " CS_PRI_RING_ID_SEQ, (uint64_t)mcast->seq);
+ }
+ }
+}
+
+/*
+ * Change states in the state machine of the membership algorithm
+ */
+static void memb_state_operational_enter (struct totemsrp_instance *instance)
+{
+ struct srp_addr joined_list[PROCESSOR_COUNT_MAX];
+ int joined_list_entries = 0;
+ unsigned int aru_save;
+ unsigned int joined_list_totemip[PROCESSOR_COUNT_MAX];
+ unsigned int trans_memb_list_totemip[PROCESSOR_COUNT_MAX];
+ unsigned int new_memb_list_totemip[PROCESSOR_COUNT_MAX];
+ unsigned int left_list[PROCESSOR_COUNT_MAX];
+ unsigned int i;
+ unsigned int res;
+ char left_node_msg[1024];
+ char joined_node_msg[1024];
+ char failed_node_msg[1024];
+
+ instance->originated_orf_token = 0;
+
+ memb_consensus_reset (instance);
+
+ old_ring_state_reset (instance);
+
+ deliver_messages_from_recovery_to_regular (instance);
+
+ log_printf (instance->totemsrp_log_level_trace,
+ "Delivering to app %x to %x",
+ instance->my_high_delivered + 1, instance->old_ring_state_high_seq_received);
+
+ aru_save = instance->my_aru;
+ instance->my_aru = instance->old_ring_state_aru;
+
+ messages_deliver_to_app (instance, 0, instance->old_ring_state_high_seq_received);
+
+ /*
+ * Calculate joined and left list
+ */
+ memb_set_subtract (instance->my_left_memb_list,
+ &instance->my_left_memb_entries,
+ instance->my_memb_list, instance->my_memb_entries,
+ instance->my_trans_memb_list, instance->my_trans_memb_entries);
+
+ memb_set_subtract (joined_list, &joined_list_entries,
+ instance->my_new_memb_list, instance->my_new_memb_entries,
+ instance->my_trans_memb_list, instance->my_trans_memb_entries);
+
+ /*
+ * Install new membership
+ */
+ instance->my_memb_entries = instance->my_new_memb_entries;
+ memcpy (&instance->my_memb_list, instance->my_new_memb_list,
+ sizeof (struct srp_addr) * instance->my_memb_entries);
+ instance->last_released = 0;
+ instance->my_set_retrans_flg = 0;
+
+ /*
+ * Deliver transitional configuration to application
+ */
+ srp_addr_to_nodeid (instance, left_list, instance->my_left_memb_list,
+ instance->my_left_memb_entries);
+ srp_addr_to_nodeid (instance, trans_memb_list_totemip,
+ instance->my_trans_memb_list, instance->my_trans_memb_entries);
+ instance->totemsrp_confchg_fn (TOTEM_CONFIGURATION_TRANSITIONAL,
+ trans_memb_list_totemip, instance->my_trans_memb_entries,
+ left_list, instance->my_left_memb_entries,
+ 0, 0, &instance->my_ring_id);
+ /*
+ * Switch new totemsrp messages queue. Messages sent from now on are stored
+ * in different queue so synchronization messages are delivered first. Totempg
+ * buffers will be switched later.
+ */
+ instance->waiting_trans_ack = 1;
+
+// TODO we need to filter to ensure we only deliver those
+// messages which are part of instance->my_deliver_memb
+ messages_deliver_to_app (instance, 1, instance->old_ring_state_high_seq_received);
+
+ /*
+ * Switch totempg buffers. This used to be right after
+ * instance->waiting_trans_ack = 1;
+ * line. This was causing problem, because there may be not yet
+ * processed parts of messages in totempg buffers.
+ * So when buffers were switched and recovered messages
+ * got delivered it was not possible to assemble them.
+ */
+ instance->totemsrp_waiting_trans_ack_cb_fn (1);
+
+ instance->my_aru = aru_save;
+
+ /*
+ * Deliver regular configuration to application
+ */
+ srp_addr_to_nodeid (instance, new_memb_list_totemip,
+ instance->my_new_memb_list, instance->my_new_memb_entries);
+ srp_addr_to_nodeid (instance, joined_list_totemip, joined_list,
+ joined_list_entries);
+ instance->totemsrp_confchg_fn (TOTEM_CONFIGURATION_REGULAR,
+ new_memb_list_totemip, instance->my_new_memb_entries,
+ 0, 0,
+ joined_list_totemip, joined_list_entries, &instance->my_ring_id);
+
+ /*
+ * The recovery sort queue now becomes the regular
+ * sort queue. It is necessary to copy the state
+ * into the regular sort queue.
+ */
+ sq_copy (&instance->regular_sort_queue, &instance->recovery_sort_queue);
+ instance->my_last_aru = SEQNO_START_MSG;
+
+ /* When making my_proc_list smaller, ensure that the
+ * now non-used entries are zero-ed out. There are some suspect
+ * assert's that assume that there is always 2 entries in the list.
+ * These fail when my_proc_list is reduced to 1 entry (and the
+ * valid [0] entry is the same as the 'unused' [1] entry).
+ */
+ memset(instance->my_proc_list, 0,
+ sizeof (struct srp_addr) * instance->my_proc_list_entries);
+
+ instance->my_proc_list_entries = instance->my_new_memb_entries;
+ memcpy (instance->my_proc_list, instance->my_new_memb_list,
+ sizeof (struct srp_addr) * instance->my_memb_entries);
+
+ instance->my_failed_list_entries = 0;
+ /*
+ * TODO Not exactly to spec
+ *
+ * At the entry to this function all messages without a gap are
+ * deliered.
+ *
+ * This code throw away messages from the last gap in the sort queue
+ * to my_high_seq_received
+ *
+ * What should really happen is we should deliver all messages up to
+ * a gap, then delier the transitional configuration, then deliver
+ * the messages between the first gap and my_high_seq_received, then
+ * deliver a regular configuration, then deliver the regular
+ * configuration
+ *
+ * Unfortunately totempg doesn't appear to like this operating mode
+ * which needs more inspection
+ */
+ i = instance->my_high_seq_received + 1;
+ do {
+ void *ptr;
+
+ i -= 1;
+ res = sq_item_get (&instance->regular_sort_queue, i, &ptr);
+ if (i == 0) {
+ break;
+ }
+ } while (res);
+
+ instance->my_high_delivered = i;
+
+ for (i = 0; i <= instance->my_high_delivered; i++) {
+ void *ptr;
+
+ res = sq_item_get (&instance->regular_sort_queue, i, &ptr);
+ if (res == 0) {
+ struct sort_queue_item *regular_message;
+
+ regular_message = ptr;
+ free (regular_message->mcast);
+ }
+ }
+ sq_items_release (&instance->regular_sort_queue, instance->my_high_delivered);
+ instance->last_released = instance->my_high_delivered;
+
+ if (joined_list_entries) {
+ int sptr = 0;
+ sptr += snprintf(joined_node_msg, sizeof(joined_node_msg)-sptr, " joined:");
+ for (i=0; i< joined_list_entries; i++) {
+ sptr += snprintf(joined_node_msg+sptr, sizeof(joined_node_msg)-sptr, " " CS_PRI_NODE_ID, joined_list_totemip[i]);
+ }
+ }
+ else {
+ joined_node_msg[0] = '\0';
+ }
+
+ if (instance->my_left_memb_entries) {
+ int sptr = 0;
+ int sptr2 = 0;
+ sptr += snprintf(left_node_msg, sizeof(left_node_msg)-sptr, " left:");
+ for (i=0; i< instance->my_left_memb_entries; i++) {
+ sptr += snprintf(left_node_msg+sptr, sizeof(left_node_msg)-sptr, " " CS_PRI_NODE_ID, left_list[i]);
+ }
+ for (i=0; i< instance->my_left_memb_entries; i++) {
+ if (my_leave_memb_match(instance, left_list[i]) == 0) {
+ if (sptr2 == 0) {
+ sptr2 += snprintf(failed_node_msg, sizeof(failed_node_msg)-sptr2, " failed:");
+ }
+ sptr2 += snprintf(failed_node_msg+sptr2, sizeof(left_node_msg)-sptr2, " " CS_PRI_NODE_ID, left_list[i]);
+ }
+ }
+ if (sptr2 == 0) {
+ failed_node_msg[0] = '\0';
+ }
+ }
+ else {
+ left_node_msg[0] = '\0';
+ failed_node_msg[0] = '\0';
+ }
+
+ my_leave_memb_clear(instance);
+
+ log_printf (instance->totemsrp_log_level_debug,
+ "entering OPERATIONAL state.");
+ log_printf (instance->totemsrp_log_level_notice,
+ "A new membership (" CS_PRI_RING_ID ") was formed. Members%s%s",
+ instance->my_ring_id.rep,
+ (uint64_t)instance->my_ring_id.seq,
+ joined_node_msg,
+ left_node_msg);
+
+ if (strlen(failed_node_msg)) {
+ log_printf (instance->totemsrp_log_level_notice,
+ "Failed to receive the leave message.%s",
+ failed_node_msg);
+ }
+
+ instance->memb_state = MEMB_STATE_OPERATIONAL;
+
+ instance->stats.operational_entered++;
+ instance->stats.continuous_gather = 0;
+
+ instance->my_received_flg = 1;
+
+ reset_pause_timeout (instance);
+
+ /*
+ * Save ring id information from this configuration to determine
+ * which processors are transitioning from old regular configuration
+ * in to new regular configuration on the next configuration change
+ */
+ memcpy (&instance->my_old_ring_id, &instance->my_ring_id,
+ sizeof (struct memb_ring_id));
+
+ return;
+}
+
+static void memb_state_gather_enter (
+ struct totemsrp_instance *instance,
+ enum gather_state_from gather_from)
+{
+ int32_t res;
+
+ instance->orf_token_discard = 1;
+
+ instance->originated_orf_token = 0;
+
+ memb_set_merge (
+ &instance->my_id, 1,
+ instance->my_proc_list, &instance->my_proc_list_entries);
+
+ memb_join_message_send (instance);
+
+ /*
+ * Restart the join timeout
+ */
+ qb_loop_timer_del (instance->totemsrp_poll_handle, instance->memb_timer_state_gather_join_timeout);
+
+ res = qb_loop_timer_add (instance->totemsrp_poll_handle,
+ QB_LOOP_MED,
+ instance->totem_config->join_timeout*QB_TIME_NS_IN_MSEC,
+ (void *)instance,
+ memb_timer_function_state_gather,
+ &instance->memb_timer_state_gather_join_timeout);
+ if (res != 0) {
+ log_printf(instance->totemsrp_log_level_error, "memb_state_gather_enter - qb_loop_timer_add error(1) : %d", res);
+ }
+
+ /*
+ * Restart the consensus timeout
+ */
+ qb_loop_timer_del (instance->totemsrp_poll_handle,
+ instance->memb_timer_state_gather_consensus_timeout);
+
+ res = qb_loop_timer_add (instance->totemsrp_poll_handle,
+ QB_LOOP_MED,
+ instance->totem_config->consensus_timeout*QB_TIME_NS_IN_MSEC,
+ (void *)instance,
+ memb_timer_function_gather_consensus_timeout,
+ &instance->memb_timer_state_gather_consensus_timeout);
+ if (res != 0) {
+ log_printf(instance->totemsrp_log_level_error, "memb_state_gather_enter - qb_loop_timer_add error(2) : %d", res);
+ }
+
+ /*
+ * Cancel the token loss and token retransmission timeouts
+ */
+ cancel_token_retransmit_timeout (instance); // REVIEWED
+ cancel_token_timeout (instance); // REVIEWED
+ cancel_merge_detect_timeout (instance);
+
+ memb_consensus_reset (instance);
+
+ memb_consensus_set (instance, &instance->my_id);
+
+ log_printf (instance->totemsrp_log_level_debug,
+ "entering GATHER state from %d(%s).",
+ gather_from, gsfrom_to_msg(gather_from));
+
+ instance->memb_state = MEMB_STATE_GATHER;
+ instance->stats.gather_entered++;
+
+ if (gather_from == TOTEMSRP_GSFROM_THE_CONSENSUS_TIMEOUT_EXPIRED) {
+ /*
+ * State 3 means gather, so we are continuously gathering.
+ */
+ instance->stats.continuous_gather++;
+ }
+
+ return;
+}
+
+static void timer_function_token_retransmit_timeout (void *data);
+
+static void target_set_completed (
+ void *context)
+{
+ struct totemsrp_instance *instance = (struct totemsrp_instance *)context;
+
+ memb_state_commit_token_send (instance);
+
+}
+
+static void memb_state_commit_enter (
+ struct totemsrp_instance *instance)
+{
+ old_ring_state_save (instance);
+
+ memb_state_commit_token_update (instance);
+
+ memb_state_commit_token_target_set (instance);
+
+ qb_loop_timer_del (instance->totemsrp_poll_handle, instance->memb_timer_state_gather_join_timeout);
+
+ instance->memb_timer_state_gather_join_timeout = 0;
+
+ qb_loop_timer_del (instance->totemsrp_poll_handle, instance->memb_timer_state_gather_consensus_timeout);
+
+ instance->memb_timer_state_gather_consensus_timeout = 0;
+
+ memb_ring_id_set (instance, &instance->commit_token->ring_id);
+
+ instance->memb_ring_id_store (&instance->my_ring_id, instance->my_id.nodeid);
+
+ instance->token_ring_id_seq = instance->my_ring_id.seq;
+
+ log_printf (instance->totemsrp_log_level_debug,
+ "entering COMMIT state.");
+
+ instance->memb_state = MEMB_STATE_COMMIT;
+ reset_token_retransmit_timeout (instance); // REVIEWED
+ reset_token_timeout (instance); // REVIEWED
+
+ instance->stats.commit_entered++;
+ instance->stats.continuous_gather = 0;
+
+ /*
+ * reset all flow control variables since we are starting a new ring
+ */
+ instance->my_trc = 0;
+ instance->my_pbl = 0;
+ instance->my_cbl = 0;
+ /*
+ * commit token sent after callback that token target has been set
+ */
+}
+
+static void memb_state_recovery_enter (
+ struct totemsrp_instance *instance,
+ struct memb_commit_token *commit_token)
+{
+ int i;
+ int local_received_flg = 1;
+ unsigned int low_ring_aru;
+ unsigned int range = 0;
+ unsigned int messages_originated = 0;
+ const struct srp_addr *addr;
+ struct memb_commit_token_memb_entry *memb_list;
+ struct memb_ring_id my_new_memb_ring_id_list[PROCESSOR_COUNT_MAX];
+
+ addr = (const struct srp_addr *)commit_token->end_of_commit_token;
+ memb_list = (struct memb_commit_token_memb_entry *)(addr + commit_token->addr_entries);
+
+ log_printf (instance->totemsrp_log_level_debug,
+ "entering RECOVERY state.");
+
+ instance->orf_token_discard = 0;
+
+ instance->my_high_ring_delivered = 0;
+
+ sq_reinit (&instance->recovery_sort_queue, SEQNO_START_MSG);
+ cs_queue_reinit (&instance->retrans_message_queue);
+
+ low_ring_aru = instance->old_ring_state_high_seq_received;
+
+ memb_state_commit_token_send_recovery (instance, commit_token);
+
+ instance->my_token_seq = SEQNO_START_TOKEN - 1;
+
+ /*
+ * Build regular configuration
+ */
+ totemnet_processor_count_set (
+ instance->totemnet_context,
+ commit_token->addr_entries);
+
+ /*
+ * Build transitional configuration
+ */
+ for (i = 0; i < instance->my_new_memb_entries; i++) {
+ memcpy (&my_new_memb_ring_id_list[i],
+ &memb_list[i].ring_id,
+ sizeof (struct memb_ring_id));
+ }
+ memb_set_and_with_ring_id (
+ instance->my_new_memb_list,
+ my_new_memb_ring_id_list,
+ instance->my_new_memb_entries,
+ instance->my_memb_list,
+ instance->my_memb_entries,
+ &instance->my_old_ring_id,
+ instance->my_trans_memb_list,
+ &instance->my_trans_memb_entries);
+
+ for (i = 0; i < instance->my_trans_memb_entries; i++) {
+ log_printf (instance->totemsrp_log_level_debug,
+ "TRANS [%d] member " CS_PRI_NODE_ID ":", i, instance->my_trans_memb_list[i].nodeid);
+ }
+ for (i = 0; i < instance->my_new_memb_entries; i++) {
+ log_printf (instance->totemsrp_log_level_debug,
+ "position [%d] member " CS_PRI_NODE_ID ":", i, addr[i].nodeid);
+ log_printf (instance->totemsrp_log_level_debug,
+ "previous ringid (" CS_PRI_RING_ID ")",
+ memb_list[i].ring_id.rep, (uint64_t)memb_list[i].ring_id.seq);
+
+ log_printf (instance->totemsrp_log_level_debug,
+ "aru %x high delivered %x received flag %d",
+ memb_list[i].aru,
+ memb_list[i].high_delivered,
+ memb_list[i].received_flg);
+
+ // assert (totemip_print (&memb_list[i].ring_id.rep) != 0);
+ }
+ /*
+ * Determine if any received flag is false
+ */
+ for (i = 0; i < commit_token->addr_entries; i++) {
+ if (memb_set_subset (&instance->my_new_memb_list[i], 1,
+ instance->my_trans_memb_list, instance->my_trans_memb_entries) &&
+
+ memb_list[i].received_flg == 0) {
+ instance->my_deliver_memb_entries = instance->my_trans_memb_entries;
+ memcpy (instance->my_deliver_memb_list, instance->my_trans_memb_list,
+ sizeof (struct srp_addr) * instance->my_trans_memb_entries);
+ local_received_flg = 0;
+ break;
+ }
+ }
+ if (local_received_flg == 1) {
+ goto no_originate;
+ } /* Else originate messages if we should */
+
+ /*
+ * Calculate my_low_ring_aru, instance->my_high_ring_delivered for the transitional membership
+ */
+ for (i = 0; i < commit_token->addr_entries; i++) {
+ if (memb_set_subset (&instance->my_new_memb_list[i], 1,
+ instance->my_deliver_memb_list,
+ instance->my_deliver_memb_entries) &&
+
+ memcmp (&instance->my_old_ring_id,
+ &memb_list[i].ring_id,
+ sizeof (struct memb_ring_id)) == 0) {
+
+ if (sq_lt_compare (memb_list[i].aru, low_ring_aru)) {
+
+ low_ring_aru = memb_list[i].aru;
+ }
+ if (sq_lt_compare (instance->my_high_ring_delivered, memb_list[i].high_delivered)) {
+ instance->my_high_ring_delivered = memb_list[i].high_delivered;
+ }
+ }
+ }
+
+ /*
+ * Copy all old ring messages to instance->retrans_message_queue
+ */
+ range = instance->old_ring_state_high_seq_received - low_ring_aru;
+ if (range == 0) {
+ /*
+ * No messages to copy
+ */
+ goto no_originate;
+ }
+ assert (range < QUEUE_RTR_ITEMS_SIZE_MAX);
+
+ log_printf (instance->totemsrp_log_level_debug,
+ "copying all old ring messages from %x-%x.",
+ low_ring_aru + 1, instance->old_ring_state_high_seq_received);
+
+ for (i = 1; i <= range; i++) {
+ struct sort_queue_item *sort_queue_item;
+ struct message_item message_item;
+ void *ptr;
+ int res;
+
+ res = sq_item_get (&instance->regular_sort_queue,
+ low_ring_aru + i, &ptr);
+ if (res != 0) {
+ continue;
+ }
+ sort_queue_item = ptr;
+ messages_originated++;
+ memset (&message_item, 0, sizeof (struct message_item));
+ // TODO LEAK
+ message_item.mcast = totemsrp_buffer_alloc (instance);
+ assert (message_item.mcast);
+ memset(message_item.mcast, 0, sizeof (struct mcast));
+ message_item.mcast->header.magic = TOTEM_MH_MAGIC;
+ message_item.mcast->header.version = TOTEM_MH_VERSION;
+ message_item.mcast->header.type = MESSAGE_TYPE_MCAST;
+ message_item.mcast->system_from = instance->my_id;
+ message_item.mcast->header.encapsulated = MESSAGE_ENCAPSULATED;
+
+ message_item.mcast->header.nodeid = instance->my_id.nodeid;
+ assert (message_item.mcast->header.nodeid);
+ memcpy (&message_item.mcast->ring_id, &instance->my_ring_id,
+ sizeof (struct memb_ring_id));
+ message_item.msg_len = sort_queue_item->msg_len + sizeof (struct mcast);
+ memcpy (((char *)message_item.mcast) + sizeof (struct mcast),
+ sort_queue_item->mcast,
+ sort_queue_item->msg_len);
+ cs_queue_item_add (&instance->retrans_message_queue, &message_item);
+ }
+ log_printf (instance->totemsrp_log_level_debug,
+ "Originated %d messages in RECOVERY.", messages_originated);
+ goto originated;
+
+no_originate:
+ log_printf (instance->totemsrp_log_level_debug,
+ "Did not need to originate any messages in recovery.");
+
+originated:
+ instance->my_aru = SEQNO_START_MSG;
+ instance->my_aru_count = 0;
+ instance->my_seq_unchanged = 0;
+ instance->my_high_seq_received = SEQNO_START_MSG;
+ instance->my_install_seq = SEQNO_START_MSG;
+ instance->last_released = SEQNO_START_MSG;
+
+ reset_token_timeout (instance); // REVIEWED
+ reset_token_retransmit_timeout (instance); // REVIEWED
+
+ instance->memb_state = MEMB_STATE_RECOVERY;
+ instance->stats.recovery_entered++;
+ instance->stats.continuous_gather = 0;
+
+ return;
+}
+
+void totemsrp_event_signal (void *srp_context, enum totem_event_type type, int value)
+{
+ struct totemsrp_instance *instance = (struct totemsrp_instance *)srp_context;
+
+ token_hold_cancel_send (instance);
+
+ return;
+}
+
+int totemsrp_mcast (
+ void *srp_context,
+ struct iovec *iovec,
+ unsigned int iov_len,
+ int guarantee)
+{
+ struct totemsrp_instance *instance = (struct totemsrp_instance *)srp_context;
+ int i;
+ struct message_item message_item;
+ char *addr;
+ unsigned int addr_idx;
+ struct cs_queue *queue_use;
+
+ if (instance->waiting_trans_ack) {
+ queue_use = &instance->new_message_queue_trans;
+ } else {
+ queue_use = &instance->new_message_queue;
+ }
+
+ if (cs_queue_is_full (queue_use)) {
+ log_printf (instance->totemsrp_log_level_debug, "queue full");
+ return (-1);
+ }
+
+ memset (&message_item, 0, sizeof (struct message_item));
+
+ /*
+ * Allocate pending item
+ */
+ message_item.mcast = totemsrp_buffer_alloc (instance);
+ if (message_item.mcast == 0) {
+ goto error_mcast;
+ }
+
+ /*
+ * Set mcast header
+ */
+ memset(message_item.mcast, 0, sizeof (struct mcast));
+ message_item.mcast->header.magic = TOTEM_MH_MAGIC;
+ message_item.mcast->header.version = TOTEM_MH_VERSION;
+ message_item.mcast->header.type = MESSAGE_TYPE_MCAST;
+ message_item.mcast->header.encapsulated = MESSAGE_NOT_ENCAPSULATED;
+
+ message_item.mcast->header.nodeid = instance->my_id.nodeid;
+ assert (message_item.mcast->header.nodeid);
+
+ message_item.mcast->guarantee = guarantee;
+ message_item.mcast->system_from = instance->my_id;
+
+ addr = (char *)message_item.mcast;
+ addr_idx = sizeof (struct mcast);
+ for (i = 0; i < iov_len; i++) {
+ memcpy (&addr[addr_idx], iovec[i].iov_base, iovec[i].iov_len);
+ addr_idx += iovec[i].iov_len;
+ }
+
+ message_item.msg_len = addr_idx;
+
+ log_printf (instance->totemsrp_log_level_trace, "mcasted message added to pending queue");
+ instance->stats.mcast_tx++;
+ cs_queue_item_add (queue_use, &message_item);
+
+ return (0);
+
+error_mcast:
+ return (-1);
+}
+
+/*
+ * Determine if there is room to queue a new message
+ */
+int totemsrp_avail (void *srp_context)
+{
+ struct totemsrp_instance *instance = (struct totemsrp_instance *)srp_context;
+ int avail;
+ struct cs_queue *queue_use;
+
+ if (instance->waiting_trans_ack) {
+ queue_use = &instance->new_message_queue_trans;
+ } else {
+ queue_use = &instance->new_message_queue;
+ }
+ cs_queue_avail (queue_use, &avail);
+
+ return (avail);
+}
+
+/*
+ * ORF Token Management
+ */
+/*
+ * Recast message to mcast group if it is available
+ */
+static int orf_token_remcast (
+ struct totemsrp_instance *instance,
+ int seq)
+{
+ struct sort_queue_item *sort_queue_item;
+ int res;
+ void *ptr;
+
+ struct sq *sort_queue;
+
+ if (instance->memb_state == MEMB_STATE_RECOVERY) {
+ sort_queue = &instance->recovery_sort_queue;
+ } else {
+ sort_queue = &instance->regular_sort_queue;
+ }
+
+ res = sq_in_range (sort_queue, seq);
+ if (res == 0) {
+ log_printf (instance->totemsrp_log_level_debug, "sq not in range");
+ return (-1);
+ }
+
+ /*
+ * Get RTR item at seq, if not available, return
+ */
+ res = sq_item_get (sort_queue, seq, &ptr);
+ if (res != 0) {
+ return -1;
+ }
+
+ sort_queue_item = ptr;
+
+ totemnet_mcast_noflush_send (
+ instance->totemnet_context,
+ sort_queue_item->mcast,
+ sort_queue_item->msg_len);
+
+ return (0);
+}
+
+
+/*
+ * Free all freeable messages from ring
+ */
+static void messages_free (
+ struct totemsrp_instance *instance,
+ unsigned int token_aru)
+{
+ struct sort_queue_item *regular_message;
+ unsigned int i;
+ int res;
+ int log_release = 0;
+ unsigned int release_to;
+ unsigned int range = 0;
+
+ release_to = token_aru;
+ if (sq_lt_compare (instance->my_last_aru, release_to)) {
+ release_to = instance->my_last_aru;
+ }
+ if (sq_lt_compare (instance->my_high_delivered, release_to)) {
+ release_to = instance->my_high_delivered;
+ }
+
+ /*
+ * Ensure we dont try release before an already released point
+ */
+ if (sq_lt_compare (release_to, instance->last_released)) {
+ return;
+ }
+
+ range = release_to - instance->last_released;
+ assert (range < QUEUE_RTR_ITEMS_SIZE_MAX);
+
+ /*
+ * Release retransmit list items if group aru indicates they are transmitted
+ */
+ for (i = 1; i <= range; i++) {
+ void *ptr;
+
+ res = sq_item_get (&instance->regular_sort_queue,
+ instance->last_released + i, &ptr);
+ if (res == 0) {
+ regular_message = ptr;
+ totemsrp_buffer_release (instance, regular_message->mcast);
+ }
+ sq_items_release (&instance->regular_sort_queue,
+ instance->last_released + i);
+
+ log_release = 1;
+ }
+ instance->last_released += range;
+
+ if (log_release) {
+ log_printf (instance->totemsrp_log_level_trace,
+ "releasing messages up to and including %x", release_to);
+ }
+}
+
+static void update_aru (
+ struct totemsrp_instance *instance)
+{
+ unsigned int i;
+ int res;
+ struct sq *sort_queue;
+ unsigned int range;
+ unsigned int my_aru_saved = 0;
+
+ if (instance->memb_state == MEMB_STATE_RECOVERY) {
+ sort_queue = &instance->recovery_sort_queue;
+ } else {
+ sort_queue = &instance->regular_sort_queue;
+ }
+
+ range = instance->my_high_seq_received - instance->my_aru;
+
+ my_aru_saved = instance->my_aru;
+ for (i = 1; i <= range; i++) {
+
+ void *ptr;
+
+ res = sq_item_get (sort_queue, my_aru_saved + i, &ptr);
+ /*
+ * If hole, stop updating aru
+ */
+ if (res != 0) {
+ break;
+ }
+ }
+ instance->my_aru += i - 1;
+}
+
+/*
+ * Multicasts pending messages onto the ring (requires orf_token possession)
+ */
+static int orf_token_mcast (
+ struct totemsrp_instance *instance,
+ struct orf_token *token,
+ int fcc_mcasts_allowed)
+{
+ struct message_item *message_item = 0;
+ struct cs_queue *mcast_queue;
+ struct sq *sort_queue;
+ struct sort_queue_item sort_queue_item;
+ struct mcast *mcast;
+ unsigned int fcc_mcast_current;
+
+ if (instance->memb_state == MEMB_STATE_RECOVERY) {
+ mcast_queue = &instance->retrans_message_queue;
+ sort_queue = &instance->recovery_sort_queue;
+ reset_token_retransmit_timeout (instance); // REVIEWED
+ } else {
+ if (instance->waiting_trans_ack) {
+ mcast_queue = &instance->new_message_queue_trans;
+ } else {
+ mcast_queue = &instance->new_message_queue;
+ }
+
+ sort_queue = &instance->regular_sort_queue;
+ }
+
+ for (fcc_mcast_current = 0; fcc_mcast_current < fcc_mcasts_allowed; fcc_mcast_current++) {
+ if (cs_queue_is_empty (mcast_queue)) {
+ break;
+ }
+ message_item = (struct message_item *)cs_queue_item_get (mcast_queue);
+
+ message_item->mcast->seq = ++token->seq;
+ message_item->mcast->this_seqno = instance->global_seqno++;
+
+ /*
+ * Build IO vector
+ */
+ memset (&sort_queue_item, 0, sizeof (struct sort_queue_item));
+ sort_queue_item.mcast = message_item->mcast;
+ sort_queue_item.msg_len = message_item->msg_len;
+
+ mcast = sort_queue_item.mcast;
+
+ memcpy (&mcast->ring_id, &instance->my_ring_id, sizeof (struct memb_ring_id));
+
+ /*
+ * Add message to retransmit queue
+ */
+ sq_item_add (sort_queue, &sort_queue_item, message_item->mcast->seq);
+
+ totemnet_mcast_noflush_send (
+ instance->totemnet_context,
+ message_item->mcast,
+ message_item->msg_len);
+
+ /*
+ * Delete item from pending queue
+ */
+ cs_queue_item_remove (mcast_queue);
+
+ /*
+ * If messages mcasted, deliver any new messages to totempg
+ */
+ instance->my_high_seq_received = token->seq;
+ }
+
+ update_aru (instance);
+
+ /*
+ * Return 1 if more messages are available for single node clusters
+ */
+ return (fcc_mcast_current);
+}
+
+/*
+ * Remulticasts messages in orf_token's retransmit list (requires orf_token)
+ * Modify's orf_token's rtr to include retransmits required by this process
+ */
+static int orf_token_rtr (
+ struct totemsrp_instance *instance,
+ struct orf_token *orf_token,
+ unsigned int *fcc_allowed)
+{
+ unsigned int res;
+ unsigned int i, j;
+ unsigned int found;
+ struct sq *sort_queue;
+ struct rtr_item *rtr_list;
+ unsigned int range = 0;
+ char retransmit_msg[1024];
+ char value[64];
+
+ if (instance->memb_state == MEMB_STATE_RECOVERY) {
+ sort_queue = &instance->recovery_sort_queue;
+ } else {
+ sort_queue = &instance->regular_sort_queue;
+ }
+
+ rtr_list = &orf_token->rtr_list[0];
+
+ strcpy (retransmit_msg, "Retransmit List: ");
+ if (orf_token->rtr_list_entries) {
+ log_printf (instance->totemsrp_log_level_debug,
+ "Retransmit List %d", orf_token->rtr_list_entries);
+ for (i = 0; i < orf_token->rtr_list_entries; i++) {
+ sprintf (value, "%x ", rtr_list[i].seq);
+ strcat (retransmit_msg, value);
+ }
+ strcat (retransmit_msg, "");
+ log_printf (instance->totemsrp_log_level_notice,
+ "%s", retransmit_msg);
+ }
+
+ /*
+ * Retransmit messages on orf_token's RTR list from RTR queue
+ */
+ for (instance->fcc_remcast_current = 0, i = 0;
+ instance->fcc_remcast_current < *fcc_allowed && i < orf_token->rtr_list_entries;) {
+
+ /*
+ * If this retransmit request isn't from this configuration,
+ * try next rtr entry
+ */
+ if (memcmp (&rtr_list[i].ring_id, &instance->my_ring_id,
+ sizeof (struct memb_ring_id)) != 0) {
+
+ i += 1;
+ continue;
+ }
+
+ res = orf_token_remcast (instance, rtr_list[i].seq);
+ if (res == 0) {
+ /*
+ * Multicasted message, so no need to copy to new retransmit list
+ */
+ orf_token->rtr_list_entries -= 1;
+ assert (orf_token->rtr_list_entries >= 0);
+ memmove (&rtr_list[i], &rtr_list[i + 1],
+ sizeof (struct rtr_item) * (orf_token->rtr_list_entries - i));
+
+ instance->stats.mcast_retx++;
+ instance->fcc_remcast_current++;
+ } else {
+ i += 1;
+ }
+ }
+ *fcc_allowed = *fcc_allowed - instance->fcc_remcast_current;
+
+ /*
+ * Add messages to retransmit to RTR list
+ * but only retry if there is room in the retransmit list
+ */
+
+ range = orf_token->seq - instance->my_aru;
+ assert (range < QUEUE_RTR_ITEMS_SIZE_MAX);
+
+ for (i = 1; (orf_token->rtr_list_entries < RETRANSMIT_ENTRIES_MAX) &&
+ (i <= range); i++) {
+
+ /*
+ * Ensure message is within the sort queue range
+ */
+ res = sq_in_range (sort_queue, instance->my_aru + i);
+ if (res == 0) {
+ break;
+ }
+
+ /*
+ * Find if a message is missing from this processor
+ */
+ res = sq_item_inuse (sort_queue, instance->my_aru + i);
+ if (res == 0) {
+ /*
+ * Determine how many times we have missed receiving
+ * this sequence number. sq_item_miss_count increments
+ * a counter for the sequence number. The miss count
+ * will be returned and compared. This allows time for
+ * delayed multicast messages to be received before
+ * declaring the message is missing and requesting a
+ * retransmit.
+ */
+ res = sq_item_miss_count (sort_queue, instance->my_aru + i);
+ if (res < instance->totem_config->miss_count_const) {
+ continue;
+ }
+
+ /*
+ * Determine if missing message is already in retransmit list
+ */
+ found = 0;
+ for (j = 0; j < orf_token->rtr_list_entries; j++) {
+ if (instance->my_aru + i == rtr_list[j].seq) {
+ found = 1;
+ }
+ }
+ if (found == 0) {
+ /*
+ * Missing message not found in current retransmit list so add it
+ */
+ memcpy (&rtr_list[orf_token->rtr_list_entries].ring_id,
+ &instance->my_ring_id, sizeof (struct memb_ring_id));
+ rtr_list[orf_token->rtr_list_entries].seq = instance->my_aru + i;
+ orf_token->rtr_list_entries++;
+ }
+ }
+ }
+ return (instance->fcc_remcast_current);
+}
+
+static void token_retransmit (struct totemsrp_instance *instance)
+{
+ totemnet_token_send (instance->totemnet_context,
+ instance->orf_token_retransmit,
+ instance->orf_token_retransmit_size);
+}
+
+/*
+ * Retransmit the regular token if no mcast or token has
+ * been received in retransmit token period retransmit
+ * the token to the next processor
+ */
+static void timer_function_token_retransmit_timeout (void *data)
+{
+ struct totemsrp_instance *instance = data;
+
+ switch (instance->memb_state) {
+ case MEMB_STATE_GATHER:
+ break;
+ case MEMB_STATE_COMMIT:
+ case MEMB_STATE_OPERATIONAL:
+ case MEMB_STATE_RECOVERY:
+ token_retransmit (instance);
+ reset_token_retransmit_timeout (instance); // REVIEWED
+ break;
+ }
+}
+
+static void timer_function_token_hold_retransmit_timeout (void *data)
+{
+ struct totemsrp_instance *instance = data;
+
+ switch (instance->memb_state) {
+ case MEMB_STATE_GATHER:
+ break;
+ case MEMB_STATE_COMMIT:
+ break;
+ case MEMB_STATE_OPERATIONAL:
+ case MEMB_STATE_RECOVERY:
+ token_retransmit (instance);
+ break;
+ }
+}
+
+static void timer_function_merge_detect_timeout(void *data)
+{
+ struct totemsrp_instance *instance = data;
+
+ instance->my_merge_detect_timeout_outstanding = 0;
+
+ switch (instance->memb_state) {
+ case MEMB_STATE_OPERATIONAL:
+ if (instance->my_ring_id.rep == instance->my_id.nodeid) {
+ memb_merge_detect_transmit (instance);
+ }
+ break;
+ case MEMB_STATE_GATHER:
+ case MEMB_STATE_COMMIT:
+ case MEMB_STATE_RECOVERY:
+ break;
+ }
+}
+
+/*
+ * Send orf_token to next member (requires orf_token)
+ */
+static int token_send (
+ struct totemsrp_instance *instance,
+ struct orf_token *orf_token,
+ int forward_token)
+{
+ int res = 0;
+ unsigned int orf_token_size;
+
+ orf_token_size = sizeof (struct orf_token) +
+ (orf_token->rtr_list_entries * sizeof (struct rtr_item));
+
+ orf_token->header.nodeid = instance->my_id.nodeid;
+ memcpy (instance->orf_token_retransmit, orf_token, orf_token_size);
+ instance->orf_token_retransmit_size = orf_token_size;
+ assert (orf_token->header.nodeid);
+
+ if (forward_token == 0) {
+ return (0);
+ }
+
+ totemnet_token_send (instance->totemnet_context,
+ orf_token,
+ orf_token_size);
+
+ return (res);
+}
+
+static int token_hold_cancel_send (struct totemsrp_instance *instance)
+{
+ struct token_hold_cancel token_hold_cancel;
+
+ /*
+ * Only cancel if the token is currently held
+ */
+ if (instance->my_token_held == 0) {
+ return (0);
+ }
+ instance->my_token_held = 0;
+
+ /*
+ * Build message
+ */
+ token_hold_cancel.header.magic = TOTEM_MH_MAGIC;
+ token_hold_cancel.header.version = TOTEM_MH_VERSION;
+ token_hold_cancel.header.type = MESSAGE_TYPE_TOKEN_HOLD_CANCEL;
+ token_hold_cancel.header.encapsulated = 0;
+ token_hold_cancel.header.nodeid = instance->my_id.nodeid;
+ memcpy (&token_hold_cancel.ring_id, &instance->my_ring_id,
+ sizeof (struct memb_ring_id));
+ assert (token_hold_cancel.header.nodeid);
+
+ instance->stats.token_hold_cancel_tx++;
+
+ totemnet_mcast_flush_send (instance->totemnet_context, &token_hold_cancel,
+ sizeof (struct token_hold_cancel));
+
+ return (0);
+}
+
+static int orf_token_send_initial (struct totemsrp_instance *instance)
+{
+ struct orf_token orf_token;
+ int res;
+
+ orf_token.header.magic = TOTEM_MH_MAGIC;
+ orf_token.header.version = TOTEM_MH_VERSION;
+ orf_token.header.type = MESSAGE_TYPE_ORF_TOKEN;
+ orf_token.header.encapsulated = 0;
+ orf_token.header.nodeid = instance->my_id.nodeid;
+ assert (orf_token.header.nodeid);
+ orf_token.seq = SEQNO_START_MSG;
+ orf_token.token_seq = SEQNO_START_TOKEN;
+ orf_token.retrans_flg = 1;
+ instance->my_set_retrans_flg = 1;
+ instance->stats.orf_token_tx++;
+
+ if (cs_queue_is_empty (&instance->retrans_message_queue) == 1) {
+ orf_token.retrans_flg = 0;
+ instance->my_set_retrans_flg = 0;
+ } else {
+ orf_token.retrans_flg = 1;
+ instance->my_set_retrans_flg = 1;
+ }
+
+ orf_token.aru = 0;
+ orf_token.aru = SEQNO_START_MSG - 1;
+ orf_token.aru_addr = instance->my_id.nodeid;
+
+ memcpy (&orf_token.ring_id, &instance->my_ring_id, sizeof (struct memb_ring_id));
+ orf_token.fcc = 0;
+ orf_token.backlog = 0;
+
+ orf_token.rtr_list_entries = 0;
+
+ res = token_send (instance, &orf_token, 1);
+
+ return (res);
+}
+
+static void memb_state_commit_token_update (
+ struct totemsrp_instance *instance)
+{
+ struct srp_addr *addr;
+ struct memb_commit_token_memb_entry *memb_list;
+ unsigned int high_aru;
+ unsigned int i;
+
+ addr = (struct srp_addr *)instance->commit_token->end_of_commit_token;
+ memb_list = (struct memb_commit_token_memb_entry *)(addr + instance->commit_token->addr_entries);
+
+ memcpy (instance->my_new_memb_list, addr,
+ sizeof (struct srp_addr) * instance->commit_token->addr_entries);
+
+ instance->my_new_memb_entries = instance->commit_token->addr_entries;
+
+ memcpy (&memb_list[instance->commit_token->memb_index].ring_id,
+ &instance->my_old_ring_id, sizeof (struct memb_ring_id));
+
+ memb_list[instance->commit_token->memb_index].aru = instance->old_ring_state_aru;
+ /*
+ * TODO high delivered is really instance->my_aru, but with safe this
+ * could change?
+ */
+ instance->my_received_flg =
+ (instance->my_aru == instance->my_high_seq_received);
+
+ memb_list[instance->commit_token->memb_index].received_flg = instance->my_received_flg;
+
+ memb_list[instance->commit_token->memb_index].high_delivered = instance->my_high_delivered;
+ /*
+ * find high aru up to current memb_index for all matching ring ids
+ * if any ring id matching memb_index has aru less then high aru set
+ * received flag for that entry to false
+ */
+ high_aru = memb_list[instance->commit_token->memb_index].aru;
+ for (i = 0; i <= instance->commit_token->memb_index; i++) {
+ if (memcmp (&memb_list[instance->commit_token->memb_index].ring_id,
+ &memb_list[i].ring_id,
+ sizeof (struct memb_ring_id)) == 0) {
+
+ if (sq_lt_compare (high_aru, memb_list[i].aru)) {
+ high_aru = memb_list[i].aru;
+ }
+ }
+ }
+
+ for (i = 0; i <= instance->commit_token->memb_index; i++) {
+ if (memcmp (&memb_list[instance->commit_token->memb_index].ring_id,
+ &memb_list[i].ring_id,
+ sizeof (struct memb_ring_id)) == 0) {
+
+ if (sq_lt_compare (memb_list[i].aru, high_aru)) {
+ memb_list[i].received_flg = 0;
+ if (i == instance->commit_token->memb_index) {
+ instance->my_received_flg = 0;
+ }
+ }
+ }
+ }
+
+ instance->commit_token->header.nodeid = instance->my_id.nodeid;
+ instance->commit_token->memb_index += 1;
+ assert (instance->commit_token->memb_index <= instance->commit_token->addr_entries);
+ assert (instance->commit_token->header.nodeid);
+}
+
+static void memb_state_commit_token_target_set (
+ struct totemsrp_instance *instance)
+{
+ struct srp_addr *addr;
+
+ addr = (struct srp_addr *)instance->commit_token->end_of_commit_token;
+
+ /* Totemnet just looks at the node id */
+ totemnet_token_target_set (
+ instance->totemnet_context,
+ addr[instance->commit_token->memb_index %
+ instance->commit_token->addr_entries].nodeid);
+}
+
+static int memb_state_commit_token_send_recovery (
+ struct totemsrp_instance *instance,
+ struct memb_commit_token *commit_token)
+{
+ unsigned int commit_token_size;
+
+ commit_token->token_seq++;
+ commit_token->header.nodeid = instance->my_id.nodeid;
+ commit_token_size = sizeof (struct memb_commit_token) +
+ ((sizeof (struct srp_addr) +
+ sizeof (struct memb_commit_token_memb_entry)) * commit_token->addr_entries);
+ /*
+ * Make a copy for retransmission if necessary
+ */
+ memcpy (instance->orf_token_retransmit, commit_token, commit_token_size);
+ instance->orf_token_retransmit_size = commit_token_size;
+
+ instance->stats.memb_commit_token_tx++;
+
+ totemnet_token_send (instance->totemnet_context,
+ commit_token,
+ commit_token_size);
+
+ /*
+ * Request retransmission of the commit token in case it is lost
+ */
+ reset_token_retransmit_timeout (instance);
+ return (0);
+}
+
+static int memb_state_commit_token_send (
+ struct totemsrp_instance *instance)
+{
+ unsigned int commit_token_size;
+
+ instance->commit_token->token_seq++;
+ instance->commit_token->header.nodeid = instance->my_id.nodeid;
+ commit_token_size = sizeof (struct memb_commit_token) +
+ ((sizeof (struct srp_addr) +
+ sizeof (struct memb_commit_token_memb_entry)) * instance->commit_token->addr_entries);
+ /*
+ * Make a copy for retransmission if necessary
+ */
+ memcpy (instance->orf_token_retransmit, instance->commit_token, commit_token_size);
+ instance->orf_token_retransmit_size = commit_token_size;
+
+ instance->stats.memb_commit_token_tx++;
+
+ totemnet_token_send (instance->totemnet_context,
+ instance->commit_token,
+ commit_token_size);
+
+ /*
+ * Request retransmission of the commit token in case it is lost
+ */
+ reset_token_retransmit_timeout (instance);
+ return (0);
+}
+
+
+static int memb_lowest_in_config (struct totemsrp_instance *instance)
+{
+ struct srp_addr token_memb[PROCESSOR_COUNT_MAX];
+ int token_memb_entries = 0;
+ int i;
+ unsigned int lowest_nodeid;
+
+ memb_set_subtract (token_memb, &token_memb_entries,
+ instance->my_proc_list, instance->my_proc_list_entries,
+ instance->my_failed_list, instance->my_failed_list_entries);
+
+ /*
+ * find representative by searching for smallest identifier
+ */
+ assert(token_memb_entries > 0);
+
+ lowest_nodeid = token_memb[0].nodeid;
+ for (i = 1; i < token_memb_entries; i++) {
+ if (lowest_nodeid > token_memb[i].nodeid) {
+ lowest_nodeid = token_memb[i].nodeid;
+ }
+ }
+ return (lowest_nodeid == instance->my_id.nodeid);
+}
+
+static int srp_addr_compare (const void *a, const void *b)
+{
+ const struct srp_addr *srp_a = (const struct srp_addr *)a;
+ const struct srp_addr *srp_b = (const struct srp_addr *)b;
+
+ if (srp_a->nodeid < srp_b->nodeid) {
+ return -1;
+ } else if (srp_a->nodeid > srp_b->nodeid) {
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+static void memb_state_commit_token_create (
+ struct totemsrp_instance *instance)
+{
+ struct srp_addr token_memb[PROCESSOR_COUNT_MAX];
+ struct srp_addr *addr;
+ struct memb_commit_token_memb_entry *memb_list;
+ int token_memb_entries = 0;
+
+ log_printf (instance->totemsrp_log_level_debug,
+ "Creating commit token because I am the rep.");
+
+ memb_set_subtract (token_memb, &token_memb_entries,
+ instance->my_proc_list, instance->my_proc_list_entries,
+ instance->my_failed_list, instance->my_failed_list_entries);
+
+ memset (instance->commit_token, 0, sizeof (struct memb_commit_token));
+ instance->commit_token->header.magic = TOTEM_MH_MAGIC;
+ instance->commit_token->header.version = TOTEM_MH_VERSION;
+ instance->commit_token->header.type = MESSAGE_TYPE_MEMB_COMMIT_TOKEN;
+ instance->commit_token->header.encapsulated = 0;
+ instance->commit_token->header.nodeid = instance->my_id.nodeid;
+ assert (instance->commit_token->header.nodeid);
+
+ instance->commit_token->ring_id.rep = instance->my_id.nodeid;
+ instance->commit_token->ring_id.seq = instance->token_ring_id_seq + 4;
+
+ /*
+ * This qsort is necessary to ensure the commit token traverses
+ * the ring in the proper order
+ */
+ qsort (token_memb, token_memb_entries, sizeof (struct srp_addr),
+ srp_addr_compare);
+
+ instance->commit_token->memb_index = 0;
+ instance->commit_token->addr_entries = token_memb_entries;
+
+ addr = (struct srp_addr *)instance->commit_token->end_of_commit_token;
+ memb_list = (struct memb_commit_token_memb_entry *)(addr + instance->commit_token->addr_entries);
+
+ memcpy (addr, token_memb,
+ token_memb_entries * sizeof (struct srp_addr));
+ memset (memb_list, 0,
+ sizeof (struct memb_commit_token_memb_entry) * token_memb_entries);
+}
+
+static void memb_join_message_send (struct totemsrp_instance *instance)
+{
+ char memb_join_data[40000];
+ struct memb_join *memb_join = (struct memb_join *)memb_join_data;
+ char *addr;
+ unsigned int addr_idx;
+ size_t msg_len;
+
+ memb_join->header.magic = TOTEM_MH_MAGIC;
+ memb_join->header.version = TOTEM_MH_VERSION;
+ memb_join->header.type = MESSAGE_TYPE_MEMB_JOIN;
+ memb_join->header.encapsulated = 0;
+ memb_join->header.nodeid = instance->my_id.nodeid;
+ assert (memb_join->header.nodeid);
+
+ msg_len = sizeof(struct memb_join) +
+ ((instance->my_proc_list_entries + instance->my_failed_list_entries) * sizeof(struct srp_addr));
+
+ if (msg_len > sizeof(memb_join_data)) {
+ log_printf (instance->totemsrp_log_level_error,
+ "memb_join_message too long. Ignoring message.");
+
+ return ;
+ }
+
+ memb_join->ring_seq = instance->my_ring_id.seq;
+ memb_join->proc_list_entries = instance->my_proc_list_entries;
+ memb_join->failed_list_entries = instance->my_failed_list_entries;
+ memb_join->system_from = instance->my_id;
+
+ /*
+ * This mess adds the joined and failed processor lists into the join
+ * message
+ */
+ addr = (char *)memb_join;
+ addr_idx = sizeof (struct memb_join);
+ memcpy (&addr[addr_idx],
+ instance->my_proc_list,
+ instance->my_proc_list_entries *
+ sizeof (struct srp_addr));
+ addr_idx +=
+ instance->my_proc_list_entries *
+ sizeof (struct srp_addr);
+ memcpy (&addr[addr_idx],
+ instance->my_failed_list,
+ instance->my_failed_list_entries *
+ sizeof (struct srp_addr));
+ addr_idx +=
+ instance->my_failed_list_entries *
+ sizeof (struct srp_addr);
+
+ if (instance->totem_config->send_join_timeout) {
+ usleep (random() % (instance->totem_config->send_join_timeout * 1000));
+ }
+
+ instance->stats.memb_join_tx++;
+
+ totemnet_mcast_flush_send (
+ instance->totemnet_context,
+ memb_join,
+ addr_idx);
+}
+
+static void memb_leave_message_send (struct totemsrp_instance *instance)
+{
+ char memb_join_data[40000];
+ struct memb_join *memb_join = (struct memb_join *)memb_join_data;
+ char *addr;
+ unsigned int addr_idx;
+ int active_memb_entries;
+ struct srp_addr active_memb[PROCESSOR_COUNT_MAX];
+ size_t msg_len;
+
+ log_printf (instance->totemsrp_log_level_debug,
+ "sending join/leave message");
+
+ /*
+ * add us to the failed list, and remove us from
+ * the members list
+ */
+ memb_set_merge(
+ &instance->my_id, 1,
+ instance->my_failed_list, &instance->my_failed_list_entries);
+
+ memb_set_subtract (active_memb, &active_memb_entries,
+ instance->my_proc_list, instance->my_proc_list_entries,
+ &instance->my_id, 1);
+
+ msg_len = sizeof(struct memb_join) +
+ ((active_memb_entries + instance->my_failed_list_entries) * sizeof(struct srp_addr));
+
+ if (msg_len > sizeof(memb_join_data)) {
+ log_printf (instance->totemsrp_log_level_error,
+ "memb_leave message too long. Ignoring message.");
+
+ return ;
+ }
+
+ memb_join->header.magic = TOTEM_MH_MAGIC;
+ memb_join->header.version = TOTEM_MH_VERSION;
+ memb_join->header.type = MESSAGE_TYPE_MEMB_JOIN;
+ memb_join->header.encapsulated = 0;
+ memb_join->header.nodeid = LEAVE_DUMMY_NODEID;
+
+ memb_join->ring_seq = instance->my_ring_id.seq;
+ memb_join->proc_list_entries = active_memb_entries;
+ memb_join->failed_list_entries = instance->my_failed_list_entries;
+ memb_join->system_from = instance->my_id;
+
+ // TODO: CC Maybe use the actual join send routine.
+ /*
+ * This mess adds the joined and failed processor lists into the join
+ * message
+ */
+ addr = (char *)memb_join;
+ addr_idx = sizeof (struct memb_join);
+ memcpy (&addr[addr_idx],
+ active_memb,
+ active_memb_entries *
+ sizeof (struct srp_addr));
+ addr_idx +=
+ active_memb_entries *
+ sizeof (struct srp_addr);
+ memcpy (&addr[addr_idx],
+ instance->my_failed_list,
+ instance->my_failed_list_entries *
+ sizeof (struct srp_addr));
+ addr_idx +=
+ instance->my_failed_list_entries *
+ sizeof (struct srp_addr);
+
+
+ if (instance->totem_config->send_join_timeout) {
+ usleep (random() % (instance->totem_config->send_join_timeout * 1000));
+ }
+ instance->stats.memb_join_tx++;
+
+ totemnet_mcast_flush_send (
+ instance->totemnet_context,
+ memb_join,
+ addr_idx);
+}
+
+static void memb_merge_detect_transmit (struct totemsrp_instance *instance)
+{
+ struct memb_merge_detect memb_merge_detect;
+
+ memb_merge_detect.header.magic = TOTEM_MH_MAGIC;
+ memb_merge_detect.header.version = TOTEM_MH_VERSION;
+ memb_merge_detect.header.type = MESSAGE_TYPE_MEMB_MERGE_DETECT;
+ memb_merge_detect.header.encapsulated = 0;
+ memb_merge_detect.header.nodeid = instance->my_id.nodeid;
+ memb_merge_detect.system_from = instance->my_id;
+ memcpy (&memb_merge_detect.ring_id, &instance->my_ring_id,
+ sizeof (struct memb_ring_id));
+ assert (memb_merge_detect.header.nodeid);
+
+ instance->stats.memb_merge_detect_tx++;
+ totemnet_mcast_flush_send (instance->totemnet_context,
+ &memb_merge_detect,
+ sizeof (struct memb_merge_detect));
+}
+
+static void memb_ring_id_set (
+ struct totemsrp_instance *instance,
+ const struct memb_ring_id *ring_id)
+{
+
+ memcpy (&instance->my_ring_id, ring_id, sizeof (struct memb_ring_id));
+}
+
+int totemsrp_callback_token_create (
+ void *srp_context,
+ void **handle_out,
+ enum totem_callback_token_type type,
+ int delete,
+ int (*callback_fn) (enum totem_callback_token_type type, const void *),
+ const void *data)
+{
+ struct totemsrp_instance *instance = (struct totemsrp_instance *)srp_context;
+ struct token_callback_instance *callback_handle;
+
+ token_hold_cancel_send (instance);
+
+ callback_handle = malloc (sizeof (struct token_callback_instance));
+ if (callback_handle == 0) {
+ return (-1);
+ }
+ *handle_out = (void *)callback_handle;
+ qb_list_init (&callback_handle->list);
+ callback_handle->callback_fn = callback_fn;
+ callback_handle->data = (void *) data;
+ callback_handle->callback_type = type;
+ callback_handle->delete = delete;
+ switch (type) {
+ case TOTEM_CALLBACK_TOKEN_RECEIVED:
+ qb_list_add (&callback_handle->list, &instance->token_callback_received_listhead);
+ break;
+ case TOTEM_CALLBACK_TOKEN_SENT:
+ qb_list_add (&callback_handle->list, &instance->token_callback_sent_listhead);
+ break;
+ }
+
+ return (0);
+}
+
+void totemsrp_callback_token_destroy (void *srp_context, void **handle_out)
+{
+ struct token_callback_instance *h;
+
+ if (*handle_out) {
+ h = (struct token_callback_instance *)*handle_out;
+ qb_list_del (&h->list);
+ free (h);
+ h = NULL;
+ *handle_out = 0;
+ }
+}
+
+static void token_callbacks_execute (
+ struct totemsrp_instance *instance,
+ enum totem_callback_token_type type)
+{
+ struct qb_list_head *list, *tmp_iter;
+ struct qb_list_head *callback_listhead = 0;
+ struct token_callback_instance *token_callback_instance;
+ int res;
+ int del;
+
+ switch (type) {
+ case TOTEM_CALLBACK_TOKEN_RECEIVED:
+ callback_listhead = &instance->token_callback_received_listhead;
+ break;
+ case TOTEM_CALLBACK_TOKEN_SENT:
+ callback_listhead = &instance->token_callback_sent_listhead;
+ break;
+ default:
+ assert (0);
+ }
+
+ qb_list_for_each_safe(list, tmp_iter, callback_listhead) {
+ token_callback_instance = qb_list_entry (list, struct token_callback_instance, list);
+ del = token_callback_instance->delete;
+ if (del == 1) {
+ qb_list_del (list);
+ }
+
+ res = token_callback_instance->callback_fn (
+ token_callback_instance->callback_type,
+ token_callback_instance->data);
+ /*
+ * This callback failed to execute, try it again on the next token
+ */
+ if (res == -1 && del == 1) {
+ qb_list_add (list, callback_listhead);
+ } else if (del) {
+ free (token_callback_instance);
+ }
+ }
+}
+
+/*
+ * Flow control functions
+ */
+static unsigned int backlog_get (struct totemsrp_instance *instance)
+{
+ unsigned int backlog = 0;
+ struct cs_queue *queue_use = NULL;
+
+ if (instance->memb_state == MEMB_STATE_OPERATIONAL) {
+ if (instance->waiting_trans_ack) {
+ queue_use = &instance->new_message_queue_trans;
+ } else {
+ queue_use = &instance->new_message_queue;
+ }
+ } else
+ if (instance->memb_state == MEMB_STATE_RECOVERY) {
+ queue_use = &instance->retrans_message_queue;
+ }
+
+ if (queue_use != NULL) {
+ backlog = cs_queue_used (queue_use);
+ }
+
+ instance->stats.token[instance->stats.latest_token].backlog_calc = backlog;
+ return (backlog);
+}
+
+static int fcc_calculate (
+ struct totemsrp_instance *instance,
+ struct orf_token *token)
+{
+ unsigned int transmits_allowed;
+ unsigned int backlog_calc;
+
+ transmits_allowed = instance->totem_config->max_messages;
+
+ if (transmits_allowed > instance->totem_config->window_size - token->fcc) {
+ transmits_allowed = instance->totem_config->window_size - token->fcc;
+ }
+
+ instance->my_cbl = backlog_get (instance);
+
+ /*
+ * Only do backlog calculation if there is a backlog otherwise
+ * we would result in div by zero
+ */
+ if (token->backlog + instance->my_cbl - instance->my_pbl) {
+ backlog_calc = (instance->totem_config->window_size * instance->my_pbl) /
+ (token->backlog + instance->my_cbl - instance->my_pbl);
+ if (backlog_calc > 0 && transmits_allowed > backlog_calc) {
+ transmits_allowed = backlog_calc;
+ }
+ }
+
+ return (transmits_allowed);
+}
+
+/*
+ * don't overflow the RTR sort queue
+ */
+static void fcc_rtr_limit (
+ struct totemsrp_instance *instance,
+ struct orf_token *token,
+ unsigned int *transmits_allowed)
+{
+ int check = QUEUE_RTR_ITEMS_SIZE_MAX;
+ check -= (*transmits_allowed + instance->totem_config->window_size);
+ assert (check >= 0);
+ if (sq_lt_compare (instance->last_released +
+ QUEUE_RTR_ITEMS_SIZE_MAX - *transmits_allowed -
+ instance->totem_config->window_size,
+
+ token->seq)) {
+
+ *transmits_allowed = 0;
+ }
+}
+
+static void fcc_token_update (
+ struct totemsrp_instance *instance,
+ struct orf_token *token,
+ unsigned int msgs_transmitted)
+{
+ token->fcc += msgs_transmitted - instance->my_trc;
+ token->backlog += instance->my_cbl - instance->my_pbl;
+ instance->my_trc = msgs_transmitted;
+ instance->my_pbl = instance->my_cbl;
+}
+
+/*
+ * Sanity checkers
+ */
+static int check_orf_token_sanity(
+ const struct totemsrp_instance *instance,
+ const void *msg,
+ size_t msg_len,
+ int endian_conversion_needed)
+{
+ int rtr_entries;
+ const struct orf_token *token = (const struct orf_token *)msg;
+ size_t required_len;
+
+ if (msg_len < sizeof(struct orf_token)) {
+ log_printf (instance->totemsrp_log_level_security,
+ "Received orf_token message is too short... ignoring.");
+
+ return (-1);
+ }
+
+ if (endian_conversion_needed) {
+ rtr_entries = swab32(token->rtr_list_entries);
+ } else {
+ rtr_entries = token->rtr_list_entries;
+ }
+
+ required_len = sizeof(struct orf_token) + rtr_entries * sizeof(struct rtr_item);
+ if (msg_len < required_len) {
+ log_printf (instance->totemsrp_log_level_security,
+ "Received orf_token message is too short... ignoring.");
+
+ return (-1);
+ }
+
+ return (0);
+}
+
+static int check_mcast_sanity(
+ struct totemsrp_instance *instance,
+ const void *msg,
+ size_t msg_len,
+ int endian_conversion_needed)
+{
+
+ if (msg_len < sizeof(struct mcast)) {
+ log_printf (instance->totemsrp_log_level_security,
+ "Received mcast message is too short... ignoring.");
+
+ return (-1);
+ }
+
+ return (0);
+}
+
+static int check_memb_merge_detect_sanity(
+ struct totemsrp_instance *instance,
+ const void *msg,
+ size_t msg_len,
+ int endian_conversion_needed)
+{
+
+ if (msg_len < sizeof(struct memb_merge_detect)) {
+ log_printf (instance->totemsrp_log_level_security,
+ "Received memb_merge_detect message is too short... ignoring.");
+
+ return (-1);
+ }
+
+ return (0);
+}
+
+static int check_memb_join_sanity(
+ struct totemsrp_instance *instance,
+ const void *msg,
+ size_t msg_len,
+ int endian_conversion_needed)
+{
+ const struct memb_join *mj_msg = (const struct memb_join *)msg;
+ unsigned int proc_list_entries;
+ unsigned int failed_list_entries;
+ size_t required_len;
+
+ if (msg_len < sizeof(struct memb_join)) {
+ log_printf (instance->totemsrp_log_level_security,
+ "Received memb_join message is too short... ignoring.");
+
+ return (-1);
+ }
+
+ proc_list_entries = mj_msg->proc_list_entries;
+ failed_list_entries = mj_msg->failed_list_entries;
+
+ if (endian_conversion_needed) {
+ proc_list_entries = swab32(proc_list_entries);
+ failed_list_entries = swab32(failed_list_entries);
+ }
+
+ required_len = sizeof(struct memb_join) + ((proc_list_entries + failed_list_entries) * sizeof(struct srp_addr));
+ if (msg_len < required_len) {
+ log_printf (instance->totemsrp_log_level_security,
+ "Received memb_join message is too short... ignoring.");
+
+ return (-1);
+ }
+
+ return (0);
+}
+
+static int check_memb_commit_token_sanity(
+ struct totemsrp_instance *instance,
+ const void *msg,
+ size_t msg_len,
+ int endian_conversion_needed)
+{
+ const struct memb_commit_token *mct_msg = (const struct memb_commit_token *)msg;
+ unsigned int addr_entries;
+ size_t required_len;
+
+ if (msg_len < sizeof(struct memb_commit_token)) {
+ log_printf (instance->totemsrp_log_level_security,
+ "Received memb_commit_token message is too short... ignoring.");
+
+ return (0);
+ }
+
+ addr_entries= mct_msg->addr_entries;
+ if (endian_conversion_needed) {
+ addr_entries = swab32(addr_entries);
+ }
+
+ required_len = sizeof(struct memb_commit_token) +
+ (addr_entries * (sizeof(struct srp_addr) + sizeof(struct memb_commit_token_memb_entry)));
+ if (msg_len < required_len) {
+ log_printf (instance->totemsrp_log_level_security,
+ "Received memb_commit_token message is too short... ignoring.");
+
+ return (-1);
+ }
+
+ return (0);
+}
+
+static int check_token_hold_cancel_sanity(
+ struct totemsrp_instance *instance,
+ const void *msg,
+ size_t msg_len,
+ int endian_conversion_needed)
+{
+
+ if (msg_len < sizeof(struct token_hold_cancel)) {
+ log_printf (instance->totemsrp_log_level_security,
+ "Received token_hold_cancel message is too short... ignoring.");
+
+ return (-1);
+ }
+
+ return (0);
+}
+
+/*
+ * Message Handlers
+ */
+
+unsigned long long int tv_old;
+/*
+ * message handler called when TOKEN message type received
+ */
+static int message_handler_orf_token (
+ struct totemsrp_instance *instance,
+ const void *msg,
+ size_t msg_len,
+ int endian_conversion_needed)
+{
+ char token_storage[1500];
+ char token_convert[1500];
+ struct orf_token *token = NULL;
+ int forward_token;
+ unsigned int transmits_allowed;
+ unsigned int mcasted_retransmit;
+ unsigned int mcasted_regular;
+ unsigned int last_aru;
+
+#ifdef GIVEINFO
+ unsigned long long tv_current;
+ unsigned long long tv_diff;
+
+ tv_current = qb_util_nano_current_get ();
+ tv_diff = tv_current - tv_old;
+ tv_old = tv_current;
+
+ log_printf (instance->totemsrp_log_level_debug,
+ "Time since last token %0.4f ms", ((float)tv_diff) / 1000000.0);
+#endif
+
+ if (check_orf_token_sanity(instance, msg, msg_len, endian_conversion_needed) == -1) {
+ return (0);
+ }
+
+ if (instance->orf_token_discard) {
+ return (0);
+ }
+#ifdef TEST_DROP_ORF_TOKEN_PERCENTAGE
+ if (random()%100 < TEST_DROP_ORF_TOKEN_PERCENTAGE) {
+ return (0);
+ }
+#endif
+
+ if (endian_conversion_needed) {
+ orf_token_endian_convert ((struct orf_token *)msg,
+ (struct orf_token *)token_convert);
+ msg = (struct orf_token *)token_convert;
+ }
+
+ /*
+ * Make copy of token and retransmit list in case we have
+ * to flush incoming messages from the kernel queue
+ */
+ token = (struct orf_token *)token_storage;
+ memcpy (token, msg, sizeof (struct orf_token));
+ memcpy (&token->rtr_list[0], (char *)msg + sizeof (struct orf_token),
+ sizeof (struct rtr_item) * RETRANSMIT_ENTRIES_MAX);
+
+
+ /*
+ * Handle merge detection timeout
+ */
+ if (token->seq == instance->my_last_seq) {
+ start_merge_detect_timeout (instance);
+ instance->my_seq_unchanged += 1;
+ } else {
+ cancel_merge_detect_timeout (instance);
+ cancel_token_hold_retransmit_timeout (instance);
+ instance->my_seq_unchanged = 0;
+ }
+
+ instance->my_last_seq = token->seq;
+
+#ifdef TEST_RECOVERY_MSG_COUNT
+ if (instance->memb_state == MEMB_STATE_OPERATIONAL && token->seq > TEST_RECOVERY_MSG_COUNT) {
+ return (0);
+ }
+#endif
+ instance->flushing = 1;
+ totemnet_recv_flush (instance->totemnet_context);
+ instance->flushing = 0;
+
+ /*
+ * Determine if we should hold (in reality drop) the token
+ */
+ instance->my_token_held = 0;
+ if (instance->my_ring_id.rep == instance->my_id.nodeid &&
+ instance->my_seq_unchanged > instance->totem_config->seqno_unchanged_const) {
+ instance->my_token_held = 1;
+ } else {
+ if (instance->my_ring_id.rep != instance->my_id.nodeid &&
+ instance->my_seq_unchanged >= instance->totem_config->seqno_unchanged_const) {
+ instance->my_token_held = 1;
+ }
+ }
+
+ /*
+ * Hold onto token when there is no activity on ring and
+ * this processor is the ring rep
+ */
+ forward_token = 1;
+ if (instance->my_ring_id.rep == instance->my_id.nodeid) {
+ if (instance->my_token_held) {
+ forward_token = 0;
+ }
+ }
+
+ switch (instance->memb_state) {
+ case MEMB_STATE_COMMIT:
+ /* Discard token */
+ break;
+
+ case MEMB_STATE_OPERATIONAL:
+ messages_free (instance, token->aru);
+ /*
+ * Do NOT add break, this case should also execute code in gather case.
+ */
+
+ case MEMB_STATE_GATHER:
+ /*
+ * DO NOT add break, we use different free mechanism in recovery state
+ */
+
+ case MEMB_STATE_RECOVERY:
+ /*
+ * Discard tokens from another configuration
+ */
+ if (memcmp (&token->ring_id, &instance->my_ring_id,
+ sizeof (struct memb_ring_id)) != 0) {
+
+ if ((forward_token)
+ && instance->use_heartbeat) {
+ reset_heartbeat_timeout(instance);
+ }
+ else {
+ cancel_heartbeat_timeout(instance);
+ }
+
+ return (0); /* discard token */
+ }
+
+ /*
+ * Discard retransmitted tokens
+ */
+ if (sq_lte_compare (token->token_seq, instance->my_token_seq)) {
+ return (0); /* discard token */
+ }
+
+ /*
+ * Token is valid so trigger callbacks
+ */
+ token_callbacks_execute (instance, TOTEM_CALLBACK_TOKEN_RECEIVED);
+
+ last_aru = instance->my_last_aru;
+ instance->my_last_aru = token->aru;
+
+ transmits_allowed = fcc_calculate (instance, token);
+ mcasted_retransmit = orf_token_rtr (instance, token, &transmits_allowed);
+
+ if (instance->totem_config->cancel_token_hold_on_retransmit &&
+ instance->my_token_held == 1 &&
+ (token->rtr_list_entries > 0 || mcasted_retransmit > 0)) {
+ instance->my_token_held = 0;
+ forward_token = 1;
+ }
+
+ fcc_rtr_limit (instance, token, &transmits_allowed);
+ mcasted_regular = orf_token_mcast (instance, token, transmits_allowed);
+/*
+if (mcasted_regular) {
+printf ("mcasted regular %d\n", mcasted_regular);
+printf ("token seq %d\n", token->seq);
+}
+*/
+ fcc_token_update (instance, token, mcasted_retransmit +
+ mcasted_regular);
+
+ if (sq_lt_compare (instance->my_aru, token->aru) ||
+ instance->my_id.nodeid == token->aru_addr ||
+ token->aru_addr == 0) {
+
+ token->aru = instance->my_aru;
+ if (token->aru == token->seq) {
+ token->aru_addr = 0;
+ } else {
+ token->aru_addr = instance->my_id.nodeid;
+ }
+ }
+ if (token->aru == last_aru && token->aru_addr != 0) {
+ instance->my_aru_count += 1;
+ } else {
+ instance->my_aru_count = 0;
+ }
+
+ /*
+ * We really don't follow specification there. In specification, OTHER nodes
+ * detect failure of one node (based on aru_count) and my_id IS NEVER added
+ * to failed list (so node never mark itself as failed)
+ */
+ if (instance->my_aru_count > instance->totem_config->fail_to_recv_const &&
+ token->aru_addr == instance->my_id.nodeid) {
+
+ log_printf (instance->totemsrp_log_level_error,
+ "FAILED TO RECEIVE");
+
+ instance->failed_to_recv = 1;
+
+ memb_set_merge (&instance->my_id, 1,
+ instance->my_failed_list,
+ &instance->my_failed_list_entries);
+
+ memb_state_gather_enter (instance, TOTEMSRP_GSFROM_FAILED_TO_RECEIVE);
+ } else {
+ instance->my_token_seq = token->token_seq;
+ token->token_seq += 1;
+
+ if (instance->memb_state == MEMB_STATE_RECOVERY) {
+ /*
+ * instance->my_aru == instance->my_high_seq_received means this processor
+ * has recovered all messages it can recover
+ * (ie: its retrans queue is empty)
+ */
+ if (cs_queue_is_empty (&instance->retrans_message_queue) == 0) {
+
+ if (token->retrans_flg == 0) {
+ token->retrans_flg = 1;
+ instance->my_set_retrans_flg = 1;
+ }
+ } else
+ if (token->retrans_flg == 1 && instance->my_set_retrans_flg) {
+ token->retrans_flg = 0;
+ instance->my_set_retrans_flg = 0;
+ }
+ log_printf (instance->totemsrp_log_level_debug,
+ "token retrans flag is %d my set retrans flag%d retrans queue empty %d count %d, aru %x",
+ token->retrans_flg, instance->my_set_retrans_flg,
+ cs_queue_is_empty (&instance->retrans_message_queue),
+ instance->my_retrans_flg_count, token->aru);
+ if (token->retrans_flg == 0) {
+ instance->my_retrans_flg_count += 1;
+ } else {
+ instance->my_retrans_flg_count = 0;
+ }
+ if (instance->my_retrans_flg_count == 2) {
+ instance->my_install_seq = token->seq;
+ }
+ log_printf (instance->totemsrp_log_level_debug,
+ "install seq %x aru %x high seq received %x",
+ instance->my_install_seq, instance->my_aru, instance->my_high_seq_received);
+ if (instance->my_retrans_flg_count >= 2 &&
+ instance->my_received_flg == 0 &&
+ sq_lte_compare (instance->my_install_seq, instance->my_aru)) {
+ instance->my_received_flg = 1;
+ instance->my_deliver_memb_entries = instance->my_trans_memb_entries;
+ memcpy (instance->my_deliver_memb_list, instance->my_trans_memb_list,
+ sizeof (struct totem_ip_address) * instance->my_trans_memb_entries);
+ }
+ if (instance->my_retrans_flg_count >= 3 &&
+ sq_lte_compare (instance->my_install_seq, token->aru)) {
+ instance->my_rotation_counter += 1;
+ } else {
+ instance->my_rotation_counter = 0;
+ }
+ if (instance->my_rotation_counter == 2) {
+ log_printf (instance->totemsrp_log_level_debug,
+ "retrans flag count %x token aru %x install seq %x aru %x %x",
+ instance->my_retrans_flg_count, token->aru, instance->my_install_seq,
+ instance->my_aru, token->seq);
+
+ memb_state_operational_enter (instance);
+ instance->my_rotation_counter = 0;
+ instance->my_retrans_flg_count = 0;
+ }
+ }
+
+ totemnet_send_flush (instance->totemnet_context);
+ token_send (instance, token, forward_token);
+
+#ifdef GIVEINFO
+ tv_current = qb_util_nano_current_get ();
+ tv_diff = tv_current - tv_old;
+ tv_old = tv_current;
+ log_printf (instance->totemsrp_log_level_debug,
+ "I held %0.4f ms",
+ ((float)tv_diff) / 1000000.0);
+#endif
+ if (instance->memb_state == MEMB_STATE_OPERATIONAL) {
+ messages_deliver_to_app (instance, 0,
+ instance->my_high_seq_received);
+ }
+
+ /*
+ * Deliver messages after token has been transmitted
+ * to improve performance
+ */
+ reset_token_timeout (instance); // REVIEWED
+ reset_token_retransmit_timeout (instance); // REVIEWED
+ if (instance->my_id.nodeid == instance->my_ring_id.rep &&
+ instance->my_token_held == 1) {
+
+ start_token_hold_retransmit_timeout (instance);
+ }
+
+ token_callbacks_execute (instance, TOTEM_CALLBACK_TOKEN_SENT);
+ }
+ break;
+ }
+
+ if ((forward_token)
+ && instance->use_heartbeat) {
+ reset_heartbeat_timeout(instance);
+ }
+ else {
+ cancel_heartbeat_timeout(instance);
+ }
+
+ return (0);
+}
+
+static void messages_deliver_to_app (
+ struct totemsrp_instance *instance,
+ int skip,
+ unsigned int end_point)
+{
+ struct sort_queue_item *sort_queue_item_p;
+ unsigned int i;
+ int res;
+ struct mcast *mcast_in;
+ struct mcast mcast_header;
+ unsigned int range = 0;
+ int endian_conversion_required;
+ unsigned int my_high_delivered_stored = 0;
+ struct srp_addr aligned_system_from;
+
+ range = end_point - instance->my_high_delivered;
+
+ if (range) {
+ log_printf (instance->totemsrp_log_level_trace,
+ "Delivering %x to %x", instance->my_high_delivered,
+ end_point);
+ }
+ assert (range < QUEUE_RTR_ITEMS_SIZE_MAX);
+ my_high_delivered_stored = instance->my_high_delivered;
+
+ /*
+ * Deliver messages in order from rtr queue to pending delivery queue
+ */
+ for (i = 1; i <= range; i++) {
+
+ void *ptr = 0;
+
+ /*
+ * If out of range of sort queue, stop assembly
+ */
+ res = sq_in_range (&instance->regular_sort_queue,
+ my_high_delivered_stored + i);
+ if (res == 0) {
+ break;
+ }
+
+ res = sq_item_get (&instance->regular_sort_queue,
+ my_high_delivered_stored + i, &ptr);
+ /*
+ * If hole, stop assembly
+ */
+ if (res != 0 && skip == 0) {
+ break;
+ }
+
+ instance->my_high_delivered = my_high_delivered_stored + i;
+
+ if (res != 0) {
+ continue;
+
+ }
+
+ sort_queue_item_p = ptr;
+
+ mcast_in = sort_queue_item_p->mcast;
+ assert (mcast_in != (struct mcast *)0xdeadbeef);
+
+ endian_conversion_required = 0;
+ if (mcast_in->header.magic != TOTEM_MH_MAGIC) {
+ endian_conversion_required = 1;
+ mcast_endian_convert (mcast_in, &mcast_header);
+ } else {
+ memcpy (&mcast_header, mcast_in, sizeof (struct mcast));
+ }
+
+ aligned_system_from = mcast_header.system_from;
+
+ /*
+ * Skip messages not originated in instance->my_deliver_memb
+ */
+ if (skip &&
+ memb_set_subset (&aligned_system_from,
+ 1,
+ instance->my_deliver_memb_list,
+ instance->my_deliver_memb_entries) == 0) {
+
+ instance->my_high_delivered = my_high_delivered_stored + i;
+
+ continue;
+ }
+
+ /*
+ * Message found
+ */
+ log_printf (instance->totemsrp_log_level_trace,
+ "Delivering MCAST message with seq %x to pending delivery queue",
+ mcast_header.seq);
+
+ /*
+ * Message is locally originated multicast
+ */
+ instance->totemsrp_deliver_fn (
+ mcast_header.header.nodeid,
+ ((char *)sort_queue_item_p->mcast) + sizeof (struct mcast),
+ sort_queue_item_p->msg_len - sizeof (struct mcast),
+ endian_conversion_required);
+ }
+}
+
+/*
+ * recv message handler called when MCAST message type received
+ */
+static int message_handler_mcast (
+ struct totemsrp_instance *instance,
+ const void *msg,
+ size_t msg_len,
+ int endian_conversion_needed)
+{
+ struct sort_queue_item sort_queue_item;
+ struct sq *sort_queue;
+ struct mcast mcast_header;
+ struct srp_addr aligned_system_from;
+
+ if (check_mcast_sanity(instance, msg, msg_len, endian_conversion_needed) == -1) {
+ return (0);
+ }
+
+ if (endian_conversion_needed) {
+ mcast_endian_convert (msg, &mcast_header);
+ } else {
+ memcpy (&mcast_header, msg, sizeof (struct mcast));
+ }
+
+ if (mcast_header.header.encapsulated == MESSAGE_ENCAPSULATED) {
+ sort_queue = &instance->recovery_sort_queue;
+ } else {
+ sort_queue = &instance->regular_sort_queue;
+ }
+
+ assert (msg_len <= FRAME_SIZE_MAX);
+
+#ifdef TEST_DROP_MCAST_PERCENTAGE
+ if (random()%100 < TEST_DROP_MCAST_PERCENTAGE) {
+ return (0);
+ }
+#endif
+
+ /*
+ * If the message is foreign execute the switch below
+ */
+ if (memcmp (&instance->my_ring_id, &mcast_header.ring_id,
+ sizeof (struct memb_ring_id)) != 0) {
+
+ aligned_system_from = mcast_header.system_from;
+
+ switch (instance->memb_state) {
+ case MEMB_STATE_OPERATIONAL:
+ memb_set_merge (
+ &aligned_system_from, 1,
+ instance->my_proc_list, &instance->my_proc_list_entries);
+ memb_state_gather_enter (instance, TOTEMSRP_GSFROM_FOREIGN_MESSAGE_IN_OPERATIONAL_STATE);
+ break;
+
+ case MEMB_STATE_GATHER:
+ if (!memb_set_subset (
+ &aligned_system_from,
+ 1,
+ instance->my_proc_list,
+ instance->my_proc_list_entries)) {
+
+ memb_set_merge (&aligned_system_from, 1,
+ instance->my_proc_list, &instance->my_proc_list_entries);
+ memb_state_gather_enter (instance, TOTEMSRP_GSFROM_FOREIGN_MESSAGE_IN_GATHER_STATE);
+ return (0);
+ }
+ break;
+
+ case MEMB_STATE_COMMIT:
+ /* discard message */
+ instance->stats.rx_msg_dropped++;
+ break;
+
+ case MEMB_STATE_RECOVERY:
+ /* discard message */
+ instance->stats.rx_msg_dropped++;
+ break;
+ }
+ return (0);
+ }
+
+ log_printf (instance->totemsrp_log_level_trace,
+ "Received ringid (" CS_PRI_RING_ID ") seq %x",
+ mcast_header.ring_id.rep,
+ (uint64_t)mcast_header.ring_id.seq,
+ mcast_header.seq);
+
+ /*
+ * Add mcast message to rtr queue if not already in rtr queue
+ * otherwise free io vectors
+ */
+ if (msg_len > 0 && msg_len <= FRAME_SIZE_MAX &&
+ sq_in_range (sort_queue, mcast_header.seq) &&
+ sq_item_inuse (sort_queue, mcast_header.seq) == 0) {
+
+ /*
+ * Allocate new multicast memory block
+ */
+// TODO LEAK
+ sort_queue_item.mcast = totemsrp_buffer_alloc (instance);
+ if (sort_queue_item.mcast == NULL) {
+ return (-1); /* error here is corrected by the algorithm */
+ }
+ memcpy (sort_queue_item.mcast, msg, msg_len);
+ sort_queue_item.msg_len = msg_len;
+
+ if (sq_lt_compare (instance->my_high_seq_received,
+ mcast_header.seq)) {
+ instance->my_high_seq_received = mcast_header.seq;
+ }
+
+ sq_item_add (sort_queue, &sort_queue_item, mcast_header.seq);
+ }
+
+ update_aru (instance);
+ if (instance->memb_state == MEMB_STATE_OPERATIONAL) {
+ messages_deliver_to_app (instance, 0, instance->my_high_seq_received);
+ }
+
+/* TODO remove from retrans message queue for old ring in recovery state */
+ return (0);
+}
+
+static int message_handler_memb_merge_detect (
+ struct totemsrp_instance *instance,
+ const void *msg,
+ size_t msg_len,
+ int endian_conversion_needed)
+{
+ struct memb_merge_detect memb_merge_detect;
+ struct srp_addr aligned_system_from;
+
+ if (check_memb_merge_detect_sanity(instance, msg, msg_len, endian_conversion_needed) == -1) {
+ return (0);
+ }
+
+ if (endian_conversion_needed) {
+ memb_merge_detect_endian_convert (msg, &memb_merge_detect);
+ } else {
+ memcpy (&memb_merge_detect, msg,
+ sizeof (struct memb_merge_detect));
+ }
+
+ /*
+ * do nothing if this is a merge detect from this configuration
+ */
+ if (memcmp (&instance->my_ring_id, &memb_merge_detect.ring_id,
+ sizeof (struct memb_ring_id)) == 0) {
+
+ return (0);
+ }
+
+ aligned_system_from = memb_merge_detect.system_from;
+
+ /*
+ * Execute merge operation
+ */
+ switch (instance->memb_state) {
+ case MEMB_STATE_OPERATIONAL:
+ memb_set_merge (&aligned_system_from, 1,
+ instance->my_proc_list, &instance->my_proc_list_entries);
+ memb_state_gather_enter (instance, TOTEMSRP_GSFROM_MERGE_DURING_OPERATIONAL_STATE);
+ break;
+
+ case MEMB_STATE_GATHER:
+ if (!memb_set_subset (
+ &aligned_system_from,
+ 1,
+ instance->my_proc_list,
+ instance->my_proc_list_entries)) {
+
+ memb_set_merge (&aligned_system_from, 1,
+ instance->my_proc_list, &instance->my_proc_list_entries);
+ memb_state_gather_enter (instance, TOTEMSRP_GSFROM_MERGE_DURING_GATHER_STATE);
+ return (0);
+ }
+ break;
+
+ case MEMB_STATE_COMMIT:
+ /* do nothing in commit */
+ break;
+
+ case MEMB_STATE_RECOVERY:
+ /* do nothing in recovery */
+ break;
+ }
+ return (0);
+}
+
+static void memb_join_process (
+ struct totemsrp_instance *instance,
+ const struct memb_join *memb_join)
+{
+ struct srp_addr *proc_list;
+ struct srp_addr *failed_list;
+ int gather_entered = 0;
+ int fail_minus_memb_entries = 0;
+ struct srp_addr fail_minus_memb[PROCESSOR_COUNT_MAX];
+ struct srp_addr aligned_system_from;
+
+ proc_list = (struct srp_addr *)memb_join->end_of_memb_join;
+ failed_list = proc_list + memb_join->proc_list_entries;
+ aligned_system_from = memb_join->system_from;
+
+ log_printf(instance->totemsrp_log_level_trace, "memb_join_process");
+ memb_set_log(instance, instance->totemsrp_log_level_trace,
+ "proclist", proc_list, memb_join->proc_list_entries);
+ memb_set_log(instance, instance->totemsrp_log_level_trace,
+ "faillist", failed_list, memb_join->failed_list_entries);
+ memb_set_log(instance, instance->totemsrp_log_level_trace,
+ "my_proclist", instance->my_proc_list, instance->my_proc_list_entries);
+ memb_set_log(instance, instance->totemsrp_log_level_trace,
+ "my_faillist", instance->my_failed_list, instance->my_failed_list_entries);
+
+ if (memb_join->header.type == MESSAGE_TYPE_MEMB_JOIN) {
+ if (instance->flushing) {
+ if (memb_join->header.nodeid == LEAVE_DUMMY_NODEID) {
+ log_printf (instance->totemsrp_log_level_warning,
+ "Discarding LEAVE message during flush, nodeid=" CS_PRI_NODE_ID,
+ memb_join->failed_list_entries > 0 ? failed_list[memb_join->failed_list_entries - 1 ].nodeid : LEAVE_DUMMY_NODEID);
+ if (memb_join->failed_list_entries > 0) {
+ my_leave_memb_set(instance, failed_list[memb_join->failed_list_entries - 1 ].nodeid);
+ }
+ } else {
+ log_printf (instance->totemsrp_log_level_warning,
+ "Discarding JOIN message during flush, nodeid=" CS_PRI_NODE_ID, memb_join->header.nodeid);
+ }
+ return;
+ } else {
+ if (memb_join->header.nodeid == LEAVE_DUMMY_NODEID) {
+ log_printf (instance->totemsrp_log_level_debug,
+ "Received LEAVE message from " CS_PRI_NODE_ID, memb_join->failed_list_entries > 0 ? failed_list[memb_join->failed_list_entries - 1 ].nodeid : LEAVE_DUMMY_NODEID);
+ if (memb_join->failed_list_entries > 0) {
+ my_leave_memb_set(instance, failed_list[memb_join->failed_list_entries - 1 ].nodeid);
+ }
+ }
+ }
+
+ }
+
+ if (memb_set_equal (proc_list,
+ memb_join->proc_list_entries,
+ instance->my_proc_list,
+ instance->my_proc_list_entries) &&
+
+ memb_set_equal (failed_list,
+ memb_join->failed_list_entries,
+ instance->my_failed_list,
+ instance->my_failed_list_entries)) {
+
+ if (memb_join->header.nodeid != LEAVE_DUMMY_NODEID) {
+ memb_consensus_set (instance, &aligned_system_from);
+ }
+
+ if (memb_consensus_agreed (instance) && instance->failed_to_recv == 1) {
+ instance->failed_to_recv = 0;
+ instance->my_proc_list[0] = instance->my_id;
+ instance->my_proc_list_entries = 1;
+ instance->my_failed_list_entries = 0;
+
+ memb_state_commit_token_create (instance);
+
+ memb_state_commit_enter (instance);
+ return;
+ }
+ if (memb_consensus_agreed (instance) &&
+ memb_lowest_in_config (instance)) {
+
+ memb_state_commit_token_create (instance);
+
+ memb_state_commit_enter (instance);
+ } else {
+ goto out;
+ }
+ } else
+ if (memb_set_subset (proc_list,
+ memb_join->proc_list_entries,
+ instance->my_proc_list,
+ instance->my_proc_list_entries) &&
+
+ memb_set_subset (failed_list,
+ memb_join->failed_list_entries,
+ instance->my_failed_list,
+ instance->my_failed_list_entries)) {
+
+ goto out;
+ } else
+ if (memb_set_subset (&aligned_system_from, 1,
+ instance->my_failed_list, instance->my_failed_list_entries)) {
+
+ goto out;
+ } else {
+ memb_set_merge (proc_list,
+ memb_join->proc_list_entries,
+ instance->my_proc_list, &instance->my_proc_list_entries);
+
+ if (memb_set_subset (
+ &instance->my_id, 1,
+ failed_list, memb_join->failed_list_entries)) {
+
+ memb_set_merge (
+ &aligned_system_from, 1,
+ instance->my_failed_list, &instance->my_failed_list_entries);
+ } else {
+ if (memb_set_subset (
+ &aligned_system_from, 1,
+ instance->my_memb_list,
+ instance->my_memb_entries)) {
+
+ if (memb_set_subset (
+ &aligned_system_from, 1,
+ instance->my_failed_list,
+ instance->my_failed_list_entries) == 0) {
+
+ memb_set_merge (failed_list,
+ memb_join->failed_list_entries,
+ instance->my_failed_list, &instance->my_failed_list_entries);
+ } else {
+ memb_set_subtract (fail_minus_memb,
+ &fail_minus_memb_entries,
+ failed_list,
+ memb_join->failed_list_entries,
+ instance->my_memb_list,
+ instance->my_memb_entries);
+
+ memb_set_merge (fail_minus_memb,
+ fail_minus_memb_entries,
+ instance->my_failed_list,
+ &instance->my_failed_list_entries);
+ }
+ }
+ }
+ memb_state_gather_enter (instance, TOTEMSRP_GSFROM_MERGE_DURING_JOIN);
+ gather_entered = 1;
+ }
+
+out:
+ if (gather_entered == 0 &&
+ instance->memb_state == MEMB_STATE_OPERATIONAL) {
+
+ memb_state_gather_enter (instance, TOTEMSRP_GSFROM_JOIN_DURING_OPERATIONAL_STATE);
+ }
+}
+
+static void memb_join_endian_convert (const struct memb_join *in, struct memb_join *out)
+{
+ int i;
+ struct srp_addr *in_proc_list;
+ struct srp_addr *in_failed_list;
+ struct srp_addr *out_proc_list;
+ struct srp_addr *out_failed_list;
+
+ out->header.magic = TOTEM_MH_MAGIC;
+ out->header.version = TOTEM_MH_VERSION;
+ out->header.type = in->header.type;
+ out->header.nodeid = swab32 (in->header.nodeid);
+ out->system_from = srp_addr_endian_convert(in->system_from);
+ out->proc_list_entries = swab32 (in->proc_list_entries);
+ out->failed_list_entries = swab32 (in->failed_list_entries);
+ out->ring_seq = swab64 (in->ring_seq);
+
+ in_proc_list = (struct srp_addr *)in->end_of_memb_join;
+ in_failed_list = in_proc_list + out->proc_list_entries;
+ out_proc_list = (struct srp_addr *)out->end_of_memb_join;
+ out_failed_list = out_proc_list + out->proc_list_entries;
+
+ for (i = 0; i < out->proc_list_entries; i++) {
+ out_proc_list[i] = srp_addr_endian_convert (in_proc_list[i]);
+ }
+ for (i = 0; i < out->failed_list_entries; i++) {
+ out_failed_list[i] = srp_addr_endian_convert (in_failed_list[i]);
+ }
+}
+
+static void memb_commit_token_endian_convert (const struct memb_commit_token *in, struct memb_commit_token *out)
+{
+ int i;
+ struct srp_addr *in_addr = (struct srp_addr *)in->end_of_commit_token;
+ struct srp_addr *out_addr = (struct srp_addr *)out->end_of_commit_token;
+ struct memb_commit_token_memb_entry *in_memb_list;
+ struct memb_commit_token_memb_entry *out_memb_list;
+
+ out->header.magic = TOTEM_MH_MAGIC;
+ out->header.version = TOTEM_MH_VERSION;
+ out->header.type = in->header.type;
+ out->header.nodeid = swab32 (in->header.nodeid);
+ out->token_seq = swab32 (in->token_seq);
+ out->ring_id.rep = swab32(in->ring_id.rep);
+ out->ring_id.seq = swab64 (in->ring_id.seq);
+ out->retrans_flg = swab32 (in->retrans_flg);
+ out->memb_index = swab32 (in->memb_index);
+ out->addr_entries = swab32 (in->addr_entries);
+
+ in_memb_list = (struct memb_commit_token_memb_entry *)(in_addr + out->addr_entries);
+ out_memb_list = (struct memb_commit_token_memb_entry *)(out_addr + out->addr_entries);
+ for (i = 0; i < out->addr_entries; i++) {
+ out_addr[i] = srp_addr_endian_convert (in_addr[i]);
+
+ /*
+ * Only convert the memb entry if it has been set
+ */
+ if (in_memb_list[i].ring_id.rep != 0) {
+ out_memb_list[i].ring_id.rep = swab32(in_memb_list[i].ring_id.rep);
+
+ out_memb_list[i].ring_id.seq =
+ swab64 (in_memb_list[i].ring_id.seq);
+ out_memb_list[i].aru = swab32 (in_memb_list[i].aru);
+ out_memb_list[i].high_delivered = swab32 (in_memb_list[i].high_delivered);
+ out_memb_list[i].received_flg = swab32 (in_memb_list[i].received_flg);
+ }
+ }
+}
+
+static void orf_token_endian_convert (const struct orf_token *in, struct orf_token *out)
+{
+ int i;
+
+ out->header.magic = TOTEM_MH_MAGIC;
+ out->header.version = TOTEM_MH_VERSION;
+ out->header.type = in->header.type;
+ out->header.nodeid = swab32 (in->header.nodeid);
+ out->seq = swab32 (in->seq);
+ out->token_seq = swab32 (in->token_seq);
+ out->aru = swab32 (in->aru);
+ out->ring_id.rep = swab32(in->ring_id.rep);
+ out->aru_addr = swab32(in->aru_addr);
+ out->ring_id.seq = swab64 (in->ring_id.seq);
+ out->fcc = swab32 (in->fcc);
+ out->backlog = swab32 (in->backlog);
+ out->retrans_flg = swab32 (in->retrans_flg);
+ out->rtr_list_entries = swab32 (in->rtr_list_entries);
+ for (i = 0; i < out->rtr_list_entries; i++) {
+ out->rtr_list[i].ring_id.rep = swab32(in->rtr_list[i].ring_id.rep);
+ out->rtr_list[i].ring_id.seq = swab64 (in->rtr_list[i].ring_id.seq);
+ out->rtr_list[i].seq = swab32 (in->rtr_list[i].seq);
+ }
+}
+
+static void mcast_endian_convert (const struct mcast *in, struct mcast *out)
+{
+ out->header.magic = TOTEM_MH_MAGIC;
+ out->header.version = TOTEM_MH_VERSION;
+ out->header.type = in->header.type;
+ out->header.nodeid = swab32 (in->header.nodeid);
+ out->header.encapsulated = in->header.encapsulated;
+
+ out->seq = swab32 (in->seq);
+ out->this_seqno = swab32 (in->this_seqno);
+ out->ring_id.rep = swab32(in->ring_id.rep);
+ out->ring_id.seq = swab64 (in->ring_id.seq);
+ out->node_id = swab32 (in->node_id);
+ out->guarantee = swab32 (in->guarantee);
+ out->system_from = srp_addr_endian_convert(in->system_from);
+}
+
+static void memb_merge_detect_endian_convert (
+ const struct memb_merge_detect *in,
+ struct memb_merge_detect *out)
+{
+ out->header.magic = TOTEM_MH_MAGIC;
+ out->header.version = TOTEM_MH_VERSION;
+ out->header.type = in->header.type;
+ out->header.nodeid = swab32 (in->header.nodeid);
+ out->ring_id.rep = swab32(in->ring_id.rep);
+ out->ring_id.seq = swab64 (in->ring_id.seq);
+ out->system_from = srp_addr_endian_convert (in->system_from);
+}
+
+static int ignore_join_under_operational (
+ struct totemsrp_instance *instance,
+ const struct memb_join *memb_join)
+{
+ struct srp_addr *proc_list;
+ struct srp_addr *failed_list;
+ unsigned long long ring_seq;
+ struct srp_addr aligned_system_from;
+
+ proc_list = (struct srp_addr *)memb_join->end_of_memb_join;
+ failed_list = proc_list + memb_join->proc_list_entries;
+ ring_seq = memb_join->ring_seq;
+ aligned_system_from = memb_join->system_from;
+
+ if (memb_set_subset (&instance->my_id, 1,
+ failed_list, memb_join->failed_list_entries)) {
+ return (1);
+ }
+
+ /*
+ * In operational state, my_proc_list is exactly the same as
+ * my_memb_list.
+ */
+ if ((memb_set_subset (&aligned_system_from, 1,
+ instance->my_memb_list, instance->my_memb_entries)) &&
+ (ring_seq < instance->my_ring_id.seq)) {
+ return (1);
+ }
+
+ return (0);
+}
+
+static int message_handler_memb_join (
+ struct totemsrp_instance *instance,
+ const void *msg,
+ size_t msg_len,
+ int endian_conversion_needed)
+{
+ const struct memb_join *memb_join;
+ struct memb_join *memb_join_convert = alloca (msg_len);
+ struct srp_addr aligned_system_from;
+
+ if (check_memb_join_sanity(instance, msg, msg_len, endian_conversion_needed) == -1) {
+ return (0);
+ }
+
+ if (endian_conversion_needed) {
+ memb_join = memb_join_convert;
+ memb_join_endian_convert (msg, memb_join_convert);
+
+ } else {
+ memb_join = msg;
+ }
+
+ aligned_system_from = memb_join->system_from;
+
+ /*
+ * If the process paused because it wasn't scheduled in a timely
+ * fashion, flush the join messages because they may be queued
+ * entries
+ */
+ if (pause_flush (instance)) {
+ return (0);
+ }
+
+ if (instance->token_ring_id_seq < memb_join->ring_seq) {
+ instance->token_ring_id_seq = memb_join->ring_seq;
+ }
+ switch (instance->memb_state) {
+ case MEMB_STATE_OPERATIONAL:
+ if (!ignore_join_under_operational (instance, memb_join)) {
+ memb_join_process (instance, memb_join);
+ }
+ break;
+
+ case MEMB_STATE_GATHER:
+ memb_join_process (instance, memb_join);
+ break;
+
+ case MEMB_STATE_COMMIT:
+ if (memb_set_subset (&aligned_system_from,
+ 1,
+ instance->my_new_memb_list,
+ instance->my_new_memb_entries) &&
+
+ memb_join->ring_seq >= instance->my_ring_id.seq) {
+
+ memb_join_process (instance, memb_join);
+ memb_state_gather_enter (instance, TOTEMSRP_GSFROM_JOIN_DURING_COMMIT_STATE);
+ }
+ break;
+
+ case MEMB_STATE_RECOVERY:
+ if (memb_set_subset (&aligned_system_from,
+ 1,
+ instance->my_new_memb_list,
+ instance->my_new_memb_entries) &&
+
+ memb_join->ring_seq >= instance->my_ring_id.seq) {
+
+ memb_join_process (instance, memb_join);
+ memb_recovery_state_token_loss (instance);
+ memb_state_gather_enter (instance, TOTEMSRP_GSFROM_JOIN_DURING_RECOVERY);
+ }
+ break;
+ }
+ return (0);
+}
+
+static int message_handler_memb_commit_token (
+ struct totemsrp_instance *instance,
+ const void *msg,
+ size_t msg_len,
+ int endian_conversion_needed)
+{
+ struct memb_commit_token *memb_commit_token_convert = alloca (msg_len);
+ struct memb_commit_token *memb_commit_token;
+ struct srp_addr sub[PROCESSOR_COUNT_MAX];
+ int sub_entries;
+
+ struct srp_addr *addr;
+
+ log_printf (instance->totemsrp_log_level_debug,
+ "got commit token");
+
+ if (check_memb_commit_token_sanity(instance, msg, msg_len, endian_conversion_needed) == -1) {
+ return (0);
+ }
+
+ if (endian_conversion_needed) {
+ memb_commit_token_endian_convert (msg, memb_commit_token_convert);
+ } else {
+ memcpy (memb_commit_token_convert, msg, msg_len);
+ }
+ memb_commit_token = memb_commit_token_convert;
+ addr = (struct srp_addr *)memb_commit_token->end_of_commit_token;
+
+#ifdef TEST_DROP_COMMIT_TOKEN_PERCENTAGE
+ if (random()%100 < TEST_DROP_COMMIT_TOKEN_PERCENTAGE) {
+ return (0);
+ }
+#endif
+ switch (instance->memb_state) {
+ case MEMB_STATE_OPERATIONAL:
+ /* discard token */
+ break;
+
+ case MEMB_STATE_GATHER:
+ memb_set_subtract (sub, &sub_entries,
+ instance->my_proc_list, instance->my_proc_list_entries,
+ instance->my_failed_list, instance->my_failed_list_entries);
+
+ if (memb_set_equal (addr,
+ memb_commit_token->addr_entries,
+ sub,
+ sub_entries) &&
+
+ memb_commit_token->ring_id.seq > instance->my_ring_id.seq) {
+ memcpy (instance->commit_token, memb_commit_token, msg_len);
+ memb_state_commit_enter (instance);
+ }
+ break;
+
+ case MEMB_STATE_COMMIT:
+ /*
+ * If retransmitted commit tokens are sent on this ring
+ * filter them out and only enter recovery once the
+ * commit token has traversed the array. This is
+ * determined by :
+ * memb_commit_token->memb_index == memb_commit_token->addr_entries) {
+ */
+ if (memb_commit_token->ring_id.seq == instance->my_ring_id.seq &&
+ memb_commit_token->memb_index == memb_commit_token->addr_entries) {
+ memb_state_recovery_enter (instance, memb_commit_token);
+ }
+ break;
+
+ case MEMB_STATE_RECOVERY:
+ if (instance->my_id.nodeid == instance->my_ring_id.rep) {
+
+ /* Filter out duplicated tokens */
+ if (instance->originated_orf_token) {
+ break;
+ }
+
+ instance->originated_orf_token = 1;
+
+ log_printf (instance->totemsrp_log_level_debug,
+ "Sending initial ORF token");
+
+ // TODO convert instead of initiate
+ orf_token_send_initial (instance);
+ reset_token_timeout (instance); // REVIEWED
+ reset_token_retransmit_timeout (instance); // REVIEWED
+ }
+ break;
+ }
+ return (0);
+}
+
+static int message_handler_token_hold_cancel (
+ struct totemsrp_instance *instance,
+ const void *msg,
+ size_t msg_len,
+ int endian_conversion_needed)
+{
+ const struct token_hold_cancel *token_hold_cancel = msg;
+
+ if (check_token_hold_cancel_sanity(instance, msg, msg_len, endian_conversion_needed) == -1) {
+ return (0);
+ }
+
+ if (memcmp (&token_hold_cancel->ring_id, &instance->my_ring_id,
+ sizeof (struct memb_ring_id)) == 0) {
+
+ instance->my_seq_unchanged = 0;
+ if (instance->my_ring_id.rep == instance->my_id.nodeid) {
+ timer_function_token_retransmit_timeout (instance);
+ }
+ }
+ return (0);
+}
+
+static int check_message_header_validity(
+ void *context,
+ const void *msg,
+ unsigned int msg_len,
+ const struct sockaddr_storage *system_from)
+{
+ struct totemsrp_instance *instance = context;
+ const struct totem_message_header *message_header = msg;
+ const char *guessed_str;
+ const char *msg_byte = msg;
+
+ if (msg_len < sizeof (struct totem_message_header)) {
+ log_printf (instance->totemsrp_log_level_security,
+ "Message received from %s is too short... Ignoring %u.",
+ totemip_sa_print((struct sockaddr *)system_from), (unsigned int)msg_len);
+ return (-1);
+ }
+
+ if (message_header->magic != TOTEM_MH_MAGIC &&
+ message_header->magic != swab16(TOTEM_MH_MAGIC)) {
+ /*
+ * We've received ether Knet, old version of Corosync,
+ * or something else. Do some guessing to display (hopefully)
+ * helpful message
+ */
+ guessed_str = NULL;
+
+ if (message_header->magic == 0xFFFF) {
+ /*
+ * Corosync 2.2 used header with two UINT8_MAX
+ */
+ guessed_str = "Corosync 2.2";
+ } else if (message_header->magic == 0xFEFE) {
+ /*
+ * Corosync 2.3+ used header with two UINT8_MAX - 1
+ */
+ guessed_str = "Corosync 2.3+";
+ } else if (msg_byte[0] == 0x01) {
+ /*
+ * Knet has stable1 with first byte of message == 1
+ */
+ guessed_str = "unencrypted Kronosnet";
+ } else if (msg_byte[0] >= 0 && msg_byte[0] <= 5) {
+ /*
+ * Unencrypted Corosync 1.x/OpenAIS has first byte
+ * 0-5. Collision with Knet (but still worth the try)
+ */
+ guessed_str = "unencrypted Corosync 2.0/2.1/1.x/OpenAIS";
+ } else {
+ /*
+ * Encrypted Kronosned packet has a hash at the end of
+ * the packet and nothing specific at the beginning of the
+ * packet (just encrypted data).
+ * Encrypted Corosync 1.x/OpenAIS is quite similar but hash_digest
+ * is in the beginning of the packet.
+ *
+ * So it's not possible to reliably detect ether of them.
+ */
+ guessed_str = "encrypted Kronosnet/Corosync 2.0/2.1/1.x/OpenAIS or unknown";
+ }
+
+ log_printf(instance->totemsrp_log_level_security,
+ "Message received from %s has bad magic number (probably sent by %s).. Ignoring",
+ totemip_sa_print((struct sockaddr *)system_from),
+ guessed_str);
+
+ return (-1);
+ }
+
+ if (message_header->version != TOTEM_MH_VERSION) {
+ log_printf(instance->totemsrp_log_level_security,
+ "Message received from %s has unsupported version %u... Ignoring",
+ totemip_sa_print((struct sockaddr *)system_from),
+ message_header->version);
+
+ return (-1);
+ }
+
+ return (0);
+}
+
+
+int main_deliver_fn (
+ void *context,
+ const void *msg,
+ unsigned int msg_len,
+ const struct sockaddr_storage *system_from)
+{
+ struct totemsrp_instance *instance = context;
+ const struct totem_message_header *message_header = msg;
+
+ if (check_message_header_validity(context, msg, msg_len, system_from) == -1) {
+ return -1;
+ }
+
+ switch (message_header->type) {
+ case MESSAGE_TYPE_ORF_TOKEN:
+ instance->stats.orf_token_rx++;
+ break;
+ case MESSAGE_TYPE_MCAST:
+ instance->stats.mcast_rx++;
+ break;
+ case MESSAGE_TYPE_MEMB_MERGE_DETECT:
+ instance->stats.memb_merge_detect_rx++;
+ break;
+ case MESSAGE_TYPE_MEMB_JOIN:
+ instance->stats.memb_join_rx++;
+ break;
+ case MESSAGE_TYPE_MEMB_COMMIT_TOKEN:
+ instance->stats.memb_commit_token_rx++;
+ break;
+ case MESSAGE_TYPE_TOKEN_HOLD_CANCEL:
+ instance->stats.token_hold_cancel_rx++;
+ break;
+ default:
+ log_printf (instance->totemsrp_log_level_security,
+ "Message received from %s has wrong type... ignoring %d.\n",
+ totemip_sa_print((struct sockaddr *)system_from),
+ (int)message_header->type);
+
+ instance->stats.rx_msg_dropped++;
+ return 0;
+ }
+ /*
+ * Handle incoming message
+ */
+ return totemsrp_message_handlers.handler_functions[(int)message_header->type] (
+ instance,
+ msg,
+ msg_len,
+ message_header->magic != TOTEM_MH_MAGIC);
+}
+
+int totemsrp_iface_set (
+ void *context,
+ const struct totem_ip_address *interface_addr,
+ unsigned short ip_port,
+ unsigned int iface_no)
+{
+ struct totemsrp_instance *instance = context;
+ int res;
+
+ totemip_copy(&instance->my_addrs[iface_no], interface_addr);
+
+ res = totemnet_iface_set (
+ instance->totemnet_context,
+ interface_addr,
+ ip_port,
+ iface_no);
+
+ return (res);
+}
+
+/* Contrary to its name, this only gets called when the interface is enabled */
+int main_iface_change_fn (
+ void *context,
+ const struct totem_ip_address *iface_addr,
+ unsigned int iface_no)
+{
+ struct totemsrp_instance *instance = context;
+ int num_interfaces;
+ int i;
+ int res = 0;
+
+ if (!instance->my_id.nodeid) {
+ instance->my_id.nodeid = iface_addr->nodeid;
+ }
+ totemip_copy (&instance->my_addrs[iface_no], iface_addr);
+
+ if (instance->iface_changes++ == 0) {
+ instance->memb_ring_id_create_or_load (&instance->my_ring_id, instance->my_id.nodeid);
+ /*
+ * Increase the ring_id sequence number. This doesn't follow specification.
+ * Solves problem with restarted leader node (node with lowest nodeid) before
+ * rest of the cluster forms new membership and guarantees unique ring_id for
+ * new singleton configuration.
+ */
+ instance->my_ring_id.seq++;
+
+ instance->token_ring_id_seq = instance->my_ring_id.seq;
+ log_printf (
+ instance->totemsrp_log_level_debug,
+ "Created or loaded sequence id " CS_PRI_RING_ID " for this ring.",
+ instance->my_ring_id.rep,
+ (uint64_t)instance->my_ring_id.seq);
+
+ if (instance->totemsrp_service_ready_fn) {
+ instance->totemsrp_service_ready_fn ();
+ }
+
+ }
+
+ num_interfaces = 0;
+ for (i = 0; i < INTERFACE_MAX; i++) {
+ if (instance->totem_config->interfaces[i].configured) {
+ num_interfaces++;
+ }
+ }
+
+ if (instance->iface_changes >= num_interfaces) {
+ /* We need to clear orig_interfaces so that 'commit' diffs against nothing */
+ instance->totem_config->orig_interfaces = malloc (sizeof (struct totem_interface) * INTERFACE_MAX);
+ assert(instance->totem_config->orig_interfaces != NULL);
+ memset(instance->totem_config->orig_interfaces, 0, sizeof (struct totem_interface) * INTERFACE_MAX);
+
+ res = totemconfig_commit_new_params(instance->totem_config, icmap_get_global_map());
+
+ memb_state_gather_enter (instance, TOTEMSRP_GSFROM_INTERFACE_CHANGE);
+ free(instance->totem_config->orig_interfaces);
+ }
+ return res;
+}
+
+void totemsrp_net_mtu_adjust (struct totem_config *totem_config) {
+ totem_config->net_mtu -= 2 * sizeof (struct mcast);
+}
+
+void totemsrp_service_ready_register (
+ void *context,
+ void (*totem_service_ready) (void))
+{
+ struct totemsrp_instance *instance = (struct totemsrp_instance *)context;
+
+ instance->totemsrp_service_ready_fn = totem_service_ready;
+}
+
+int totemsrp_member_add (
+ void *context,
+ const struct totem_ip_address *member,
+ int iface_no)
+{
+ struct totemsrp_instance *instance = (struct totemsrp_instance *)context;
+ int res;
+
+ res = totemnet_member_add (instance->totemnet_context, &instance->my_addrs[iface_no], member, iface_no);
+
+ return (res);
+}
+
+int totemsrp_member_remove (
+ void *context,
+ const struct totem_ip_address *member,
+ int iface_no)
+{
+ struct totemsrp_instance *instance = (struct totemsrp_instance *)context;
+ int res;
+
+ res = totemnet_member_remove (instance->totemnet_context, member, iface_no);
+
+ return (res);
+}
+
+void totemsrp_threaded_mode_enable (void *context)
+{
+ struct totemsrp_instance *instance = (struct totemsrp_instance *)context;
+
+ instance->threaded_mode_enabled = 1;
+}
+
+void totemsrp_trans_ack (void *context)
+{
+ struct totemsrp_instance *instance = (struct totemsrp_instance *)context;
+
+ instance->waiting_trans_ack = 0;
+ instance->totemsrp_waiting_trans_ack_cb_fn (0);
+}
+
+
+int totemsrp_reconfigure (void *context, struct totem_config *totem_config)
+{
+ struct totemsrp_instance *instance = (struct totemsrp_instance *)context;
+ int res;
+
+ res = totemnet_reconfigure (instance->totemnet_context, totem_config);
+ return (res);
+}
+
+int totemsrp_crypto_reconfigure_phase (void *context, struct totem_config *totem_config, cfg_message_crypto_reconfig_phase_t phase)
+{
+ struct totemsrp_instance *instance = (struct totemsrp_instance *)context;
+ int res;
+
+ res = totemnet_crypto_reconfigure_phase (instance->totemnet_context, totem_config, phase);
+ return (res);
+}
+
+void totemsrp_stats_clear (void *context, int flags)
+{
+ struct totemsrp_instance *instance = (struct totemsrp_instance *)context;
+
+ memset(&instance->stats, 0, sizeof(totemsrp_stats_t));
+ if (flags & TOTEMPG_STATS_CLEAR_TRANSPORT) {
+ totemnet_stats_clear (instance->totemnet_context);
+ }
+}
+
+void totemsrp_force_gather (void *context)
+{
+ timer_function_orf_token_timeout(context);
+}
diff --git a/exec/totemsrp.h b/exec/totemsrp.h
new file mode 100644
index 0000000..49e0095
--- /dev/null
+++ b/exec/totemsrp.h
@@ -0,0 +1,168 @@
+/*
+ * Copyright (c) 2003-2005 MontaVista Software, Inc.
+ * Copyright (c) 2006-2011 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Author: Steven Dake (sdake@redhat.com)
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of the MontaVista Software, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file
+ * Totem Single Ring Protocol
+ *
+ * depends on poll abstraction, POSIX, IPV4
+ */
+
+#ifndef TOTEMSRP_H_DEFINED
+#define TOTEMSRP_H_DEFINED
+
+#include <corosync/totem/totem.h>
+#include <qb/qbloop.h>
+
+/**
+ * Create a protocol instance
+ */
+int totemsrp_initialize (
+ qb_loop_t *poll_handle,
+ void **srp_context,
+ struct totem_config *totem_config,
+ totempg_stats_t *stats,
+
+ void (*deliver_fn) (
+ unsigned int nodeid,
+ const void *msg,
+ unsigned int msg_len,
+ int endian_conversion_required),
+ void (*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),
+ void (*waiting_trans_ack_cb_fn) (
+ int waiting_trans_ack));
+
+void totemsrp_finalize (void *srp_context);
+
+/**
+ * Multicast a message
+ */
+int totemsrp_mcast (
+ void *srp_context,
+ struct iovec *iovec,
+ unsigned int iov_len,
+ int priority);
+
+/**
+ * Return number of available messages that can be queued
+ */
+int totemsrp_avail (void *srp_context);
+
+int totemsrp_callback_token_create (
+ void *srp_context,
+ void **handle_out,
+ enum totem_callback_token_type type,
+ int delete,
+ int (*callback_fn) (enum totem_callback_token_type type, const void *),
+ const void *data);
+
+void totemsrp_callback_token_destroy (
+ void *srp_context,
+ void **handle_out);
+
+void totemsrp_event_signal (void *srp_context, enum totem_event_type type, int value);
+
+extern void totemsrp_net_mtu_adjust (struct totem_config *totem_config);
+
+extern int totemsrp_nodestatus_get (void *srp_context, unsigned int nodeid,
+ struct totem_node_status *node_status);
+
+extern int totemsrp_ifaces_get (
+ void *srp_context,
+ unsigned int nodeid,
+ unsigned int *interface_id,
+ struct totem_ip_address *interfaces,
+ unsigned int interfaces_size,
+ char ***status,
+ unsigned int *iface_count);
+
+extern unsigned int totemsrp_my_nodeid_get (
+ void *srp_context);
+
+extern int totemsrp_my_family_get (
+ void *srp_context);
+
+extern int totemsrp_crypto_set (
+ void *srp_context,
+ const char *cipher_type,
+ const char *hash_type);
+
+void totemsrp_service_ready_register (
+ void *srp_context,
+ void (*totem_service_ready) (void));
+
+extern int totemsrp_iface_set (
+ void *srp_context,
+ const struct totem_ip_address *interface_addr,
+ unsigned short ip_port,
+ unsigned int iface_no);
+
+extern int totemsrp_member_add (
+ void *srp_context,
+ const struct totem_ip_address *member,
+ int ring_no);
+
+extern int totemsrp_member_remove (
+ void *srp_context,
+ const struct totem_ip_address *member,
+ int ring_no);
+
+void totemsrp_threaded_mode_enable (
+ void *srp_context);
+
+void totemsrp_trans_ack (
+ void *srp_context);
+
+int totemsrp_reconfigure (
+ void *context,
+ struct totem_config *totem_config);
+
+int totemsrp_crypto_reconfigure_phase (
+ void *context,
+ struct totem_config *totem_config,
+ cfg_message_crypto_reconfig_phase_t phase);
+
+void totemsrp_stats_clear (
+ void *srp_context, int flags);
+
+void totemsrp_force_gather (
+ void *context);
+
+#endif /* TOTEMSRP_H_DEFINED */
diff --git a/exec/totemudp.c b/exec/totemudp.c
new file mode 100644
index 0000000..0ebe127
--- /dev/null
+++ b/exec/totemudp.c
@@ -0,0 +1,1549 @@
+/*
+ * Copyright (c) 2005 MontaVista Software, Inc.
+ * Copyright (c) 2006-2018 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Author: Steven Dake (sdake@redhat.com)
+
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of the MontaVista Software, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include <assert.h>
+#include <pthread.h>
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <sys/un.h>
+#include <sys/ioctl.h>
+#include <sys/param.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+#include <sched.h>
+#include <time.h>
+#include <sys/time.h>
+#include <sys/poll.h>
+#include <sys/uio.h>
+#include <limits.h>
+
+#include <corosync/sq.h>
+#include <corosync/swab.h>
+#include <qb/qbdefs.h>
+#include <qb/qbloop.h>
+#define LOGSYS_UTILS_ONLY 1
+#include <corosync/logsys.h>
+#include "totemudp.h"
+
+#include "util.h"
+
+#ifndef MSG_NOSIGNAL
+#define MSG_NOSIGNAL 0
+#endif
+
+#define MCAST_SOCKET_BUFFER_SIZE (TRANSMITS_ALLOWED * FRAME_SIZE_MAX)
+#define NETIF_STATE_REPORT_UP 1
+#define NETIF_STATE_REPORT_DOWN 2
+
+#define BIND_STATE_UNBOUND 0
+#define BIND_STATE_REGULAR 1
+#define BIND_STATE_LOOPBACK 2
+
+struct totemudp_member {
+ struct qb_list_head list;
+ struct totem_ip_address member;
+};
+
+struct totemudp_socket {
+ int mcast_recv;
+ int mcast_send;
+ int token;
+ /*
+ * Socket used for local multicast delivery. We don't rely on multicast
+ * loop and rather this UNIX DGRAM socket is used. Socket is created by
+ * socketpair call and they are used in same way as pipe (so [0] is read
+ * end and [1] is write end)
+ */
+ int local_mcast_loop[2];
+};
+
+struct totemudp_instance {
+ qb_loop_t *totemudp_poll_handle;
+
+ struct totem_interface *totem_interface;
+
+ int netif_state_report;
+
+ int netif_bind_state;
+
+ void *context;
+
+ int (*totemudp_deliver_fn) (
+ void *context,
+ const void *msg,
+ unsigned int msg_len,
+ const struct sockaddr_storage *system_from);
+
+ int (*totemudp_iface_change_fn) (
+ void *context,
+ const struct totem_ip_address *iface_address,
+ unsigned int ring_no);
+
+ void (*totemudp_target_set_completed) (void *context);
+
+ /*
+ * Function and data used to log messages
+ */
+ int totemudp_log_level_security;
+
+ int totemudp_log_level_error;
+
+ int totemudp_log_level_warning;
+
+ int totemudp_log_level_notice;
+
+ int totemudp_log_level_debug;
+
+ int totemudp_subsys_id;
+
+ void (*totemudp_log_printf) (
+ int level,
+ int subsys,
+ const char *function,
+ const char *file,
+ int line,
+ const char *format,
+ ...)__attribute__((format(printf, 6, 7)));
+
+ void *udp_context;
+
+ struct qb_list_head member_list;
+
+ char iov_buffer[UDP_RECEIVE_FRAME_SIZE_MAX];
+
+ char iov_buffer_flush[UDP_RECEIVE_FRAME_SIZE_MAX];
+
+ struct iovec totemudp_iov_recv;
+
+ struct iovec totemudp_iov_recv_flush;
+
+ struct totemudp_socket totemudp_sockets;
+
+ struct totem_ip_address mcast_address;
+
+ int stats_sent;
+
+ int stats_recv;
+
+ int stats_delv;
+
+ int stats_remcasts;
+
+ int stats_orf_token;
+
+ struct timeval stats_tv_start;
+
+ struct totem_ip_address my_id;
+
+ int firstrun;
+
+ qb_loop_timer_handle timer_netif_check_timeout;
+
+ unsigned int my_memb_entries;
+
+ int flushing;
+
+ struct totem_config *totem_config;
+
+ totemsrp_stats_t *stats;
+
+ struct totem_ip_address token_target;
+};
+
+struct work_item {
+ const void *msg;
+ unsigned int msg_len;
+ struct totemudp_instance *instance;
+};
+
+static int totemudp_build_sockets (
+ struct totemudp_instance *instance,
+ struct totem_ip_address *bindnet_address,
+ struct totem_ip_address *mcastaddress,
+ struct totemudp_socket *sockets,
+ struct totem_ip_address *bound_to);
+
+static struct totem_ip_address localhost;
+
+static void totemudp_instance_initialize (struct totemudp_instance *instance)
+{
+ memset (instance, 0, sizeof (struct totemudp_instance));
+
+ instance->netif_state_report = NETIF_STATE_REPORT_UP | NETIF_STATE_REPORT_DOWN;
+
+ instance->totemudp_iov_recv.iov_base = instance->iov_buffer;
+
+ instance->totemudp_iov_recv.iov_len = UDP_RECEIVE_FRAME_SIZE_MAX; //sizeof (instance->iov_buffer);
+ instance->totemudp_iov_recv_flush.iov_base = instance->iov_buffer_flush;
+
+ instance->totemudp_iov_recv_flush.iov_len = UDP_RECEIVE_FRAME_SIZE_MAX; //sizeof (instance->iov_buffer);
+
+ /*
+ * There is always atleast 1 processor
+ */
+ instance->my_memb_entries = 1;
+
+ qb_list_init (&instance->member_list);
+}
+
+#define log_printf(level, format, args...) \
+do { \
+ instance->totemudp_log_printf ( \
+ level, instance->totemudp_subsys_id, \
+ __FUNCTION__, __FILE__, __LINE__, \
+ (const char *)format, ##args); \
+} while (0);
+
+#define LOGSYS_PERROR(err_num, level, fmt, args...) \
+do { \
+ char _error_str[LOGSYS_MAX_PERROR_MSG_LEN]; \
+ const char *_error_ptr = qb_strerror_r(err_num, _error_str, sizeof(_error_str)); \
+ instance->totemudp_log_printf ( \
+ level, instance->totemudp_subsys_id, \
+ __FUNCTION__, __FILE__, __LINE__, \
+ fmt ": %s (%d)\n", ##args, _error_ptr, err_num); \
+ } while(0)
+
+int totemudp_crypto_set (
+ void *udp_context,
+ const char *cipher_type,
+ const char *hash_type)
+{
+
+ return (0);
+}
+
+
+static inline void ucast_sendmsg (
+ struct totemudp_instance *instance,
+ struct totem_ip_address *system_to,
+ const void *msg,
+ unsigned int msg_len)
+{
+ struct msghdr msg_ucast;
+ int res = 0;
+ struct sockaddr_storage sockaddr;
+ struct iovec iovec;
+ int addrlen;
+
+ iovec.iov_base = (void*)msg;
+ iovec.iov_len = msg_len;
+
+ /*
+ * Build unicast message
+ */
+ memset(&msg_ucast, 0, sizeof(msg_ucast));
+ totemip_totemip_to_sockaddr_convert(system_to,
+ instance->totem_interface->ip_port, &sockaddr, &addrlen);
+ msg_ucast.msg_name = &sockaddr;
+ msg_ucast.msg_namelen = addrlen;
+ msg_ucast.msg_iov = (void *)&iovec;
+ msg_ucast.msg_iovlen = 1;
+#ifdef HAVE_MSGHDR_CONTROL
+ msg_ucast.msg_control = 0;
+#endif
+#ifdef HAVE_MSGHDR_CONTROLLEN
+ msg_ucast.msg_controllen = 0;
+#endif
+#ifdef HAVE_MSGHDR_FLAGS
+ msg_ucast.msg_flags = 0;
+#endif
+#ifdef HAVE_MSGHDR_ACCRIGHTS
+ msg_ucast.msg_accrights = NULL;
+#endif
+#ifdef HAVE_MSGHDR_ACCRIGHTSLEN
+ msg_ucast.msg_accrightslen = 0;
+#endif
+
+
+ /*
+ * Transmit unicast message
+ * An error here is recovered by totemsrp
+ */
+ res = sendmsg (instance->totemudp_sockets.mcast_send, &msg_ucast,
+ MSG_NOSIGNAL);
+ if (res < 0) {
+ LOGSYS_PERROR (errno, instance->totemudp_log_level_debug,
+ "sendmsg(ucast) failed (non-critical)");
+ }
+}
+
+static inline void mcast_sendmsg (
+ struct totemudp_instance *instance,
+ const void *msg,
+ unsigned int msg_len)
+{
+ struct msghdr msg_mcast;
+ int res = 0;
+ struct iovec iovec;
+ struct sockaddr_storage sockaddr;
+ int addrlen;
+
+ iovec.iov_base = (void *)msg;
+ iovec.iov_len = msg_len;
+
+ /*
+ * Build multicast message
+ */
+ totemip_totemip_to_sockaddr_convert(&instance->mcast_address,
+ instance->totem_interface->ip_port, &sockaddr, &addrlen);
+ memset(&msg_mcast, 0, sizeof(msg_mcast));
+ msg_mcast.msg_name = &sockaddr;
+ msg_mcast.msg_namelen = addrlen;
+ msg_mcast.msg_iov = (void *)&iovec;
+ msg_mcast.msg_iovlen = 1;
+#ifdef HAVE_MSGHDR_CONTROL
+ msg_mcast.msg_control = 0;
+#endif
+#ifdef HAVE_MSGHDR_CONTROLLEN
+ msg_mcast.msg_controllen = 0;
+#endif
+#ifdef HAVE_MSGHDR_FLAGS
+ msg_mcast.msg_flags = 0;
+#endif
+#ifdef HAVE_MSGHDR_ACCRIGHTS
+ msg_mcast.msg_accrights = NULL;
+#endif
+#ifdef HAVE_MSGHDR_ACCRIGHTSLEN
+ msg_mcast.msg_accrightslen = 0;
+#endif
+
+ /*
+ * Transmit multicast message
+ * An error here is recovered by totemsrp
+ */
+ res = sendmsg (instance->totemudp_sockets.mcast_send, &msg_mcast,
+ MSG_NOSIGNAL);
+ if (res < 0) {
+ LOGSYS_PERROR (errno, instance->totemudp_log_level_debug,
+ "sendmsg(mcast) failed (non-critical)");
+ instance->stats->continuous_sendmsg_failures++;
+ } else {
+ instance->stats->continuous_sendmsg_failures = 0;
+ }
+
+ /*
+ * Transmit multicast message to local unix mcast loop
+ * An error here is recovered by totemsrp
+ */
+ msg_mcast.msg_name = NULL;
+ msg_mcast.msg_namelen = 0;
+
+ res = sendmsg (instance->totemudp_sockets.local_mcast_loop[1], &msg_mcast,
+ MSG_NOSIGNAL);
+ if (res < 0) {
+ LOGSYS_PERROR (errno, instance->totemudp_log_level_debug,
+ "sendmsg(local mcast loop) failed (non-critical)");
+ }
+}
+
+
+int totemudp_finalize (
+ void *udp_context)
+{
+ struct totemudp_instance *instance = (struct totemudp_instance *)udp_context;
+ int res = 0;
+
+ if (instance->totemudp_sockets.mcast_recv > 0) {
+ qb_loop_poll_del (instance->totemudp_poll_handle,
+ instance->totemudp_sockets.mcast_recv);
+ close (instance->totemudp_sockets.mcast_recv);
+ }
+ if (instance->totemudp_sockets.mcast_send > 0) {
+ close (instance->totemudp_sockets.mcast_send);
+ }
+ if (instance->totemudp_sockets.local_mcast_loop[0] > 0) {
+ qb_loop_poll_del (instance->totemudp_poll_handle,
+ instance->totemudp_sockets.local_mcast_loop[0]);
+ close (instance->totemudp_sockets.local_mcast_loop[0]);
+ close (instance->totemudp_sockets.local_mcast_loop[1]);
+ }
+ if (instance->totemudp_sockets.token > 0) {
+ qb_loop_poll_del (instance->totemudp_poll_handle,
+ instance->totemudp_sockets.token);
+ close (instance->totemudp_sockets.token);
+ }
+
+ return (res);
+}
+
+/*
+ * Only designed to work with a message with one iov
+ */
+
+static int net_deliver_fn (
+ int fd,
+ int revents,
+ void *data)
+{
+ struct totemudp_instance *instance = (struct totemudp_instance *)data;
+ struct msghdr msg_recv;
+ struct iovec *iovec;
+ struct sockaddr_storage system_from;
+ int bytes_received;
+ int truncated_packet;
+
+ if (instance->flushing == 1) {
+ iovec = &instance->totemudp_iov_recv_flush;
+ } else {
+ iovec = &instance->totemudp_iov_recv;
+ }
+
+ /*
+ * Receive datagram
+ */
+ msg_recv.msg_name = &system_from;
+ msg_recv.msg_namelen = sizeof (struct sockaddr_storage);
+ msg_recv.msg_iov = iovec;
+ msg_recv.msg_iovlen = 1;
+#ifdef HAVE_MSGHDR_CONTROL
+ msg_recv.msg_control = 0;
+#endif
+#ifdef HAVE_MSGHDR_CONTROLLEN
+ msg_recv.msg_controllen = 0;
+#endif
+#ifdef HAVE_MSGHDR_FLAGS
+ msg_recv.msg_flags = 0;
+#endif
+#ifdef HAVE_MSGHDR_ACCRIGHTS
+ msg_recv.msg_accrights = NULL;
+#endif
+#ifdef HAVE_MSGHDR_ACCRIGHTSLEN
+ msg_recv.msg_accrightslen = 0;
+#endif
+
+ bytes_received = recvmsg (fd, &msg_recv, MSG_NOSIGNAL | MSG_DONTWAIT);
+ if (bytes_received == -1) {
+ return (0);
+ } else {
+ instance->stats_recv += bytes_received;
+ }
+
+ truncated_packet = 0;
+
+#ifdef HAVE_MSGHDR_FLAGS
+ if (msg_recv.msg_flags & MSG_TRUNC) {
+ truncated_packet = 1;
+ }
+#else
+ /*
+ * We don't have MSGHDR_FLAGS, but we can (hopefully) safely make assumption that
+ * if bytes_received == UDP_RECIEVE_FRAME_SIZE_MAX then packet is truncated
+ */
+ if (bytes_received == UDP_RECEIVE_FRAME_SIZE_MAX) {
+ truncated_packet = 1;
+ }
+#endif
+
+ if (truncated_packet) {
+ log_printf (instance->totemudp_log_level_error,
+ "Received too big message. This may be because something bad is happening"
+ "on the network (attack?), or you tried join more nodes than corosync is"
+ "compiled with (%u) or bug in the code (bad estimation of "
+ "the UDP_RECEIVE_FRAME_SIZE_MAX). Dropping packet.", PROCESSOR_COUNT_MAX);
+ return (0);
+ }
+
+ iovec->iov_len = bytes_received;
+
+ /*
+ * Handle incoming message
+ */
+ instance->totemudp_deliver_fn (
+ instance->context,
+ iovec->iov_base,
+ iovec->iov_len,
+ &system_from);
+
+ iovec->iov_len = UDP_RECEIVE_FRAME_SIZE_MAX;
+ return (0);
+}
+
+static int netif_determine (
+ struct totemudp_instance *instance,
+ struct totem_ip_address *bindnet,
+ struct totem_ip_address *bound_to,
+ int *interface_up,
+ int *interface_num)
+{
+ int res;
+
+ res = totemip_iface_check (bindnet, bound_to,
+ interface_up, interface_num,
+ instance->totem_config->clear_node_high_bit);
+
+
+ return (res);
+}
+
+
+/*
+ * If the interface is up, the sockets for totem are built. If the interface is down
+ * this function is requeued in the timer list to retry building the sockets later.
+ */
+static void timer_function_netif_check_timeout (
+ void *data)
+{
+ struct totemudp_instance *instance = (struct totemudp_instance *)data;
+ int interface_up;
+ int interface_num;
+ struct totem_ip_address *bind_address;
+
+ /*
+ * Build sockets for every interface
+ */
+ netif_determine (instance,
+ &instance->totem_interface->bindnet,
+ &instance->totem_interface->boundto,
+ &interface_up, &interface_num);
+ /*
+ * If the network interface isn't back up and we are already
+ * in loopback mode, add timer to check again and return
+ */
+ if ((instance->netif_bind_state == BIND_STATE_LOOPBACK &&
+ interface_up == 0) ||
+
+ (instance->my_memb_entries == 1 &&
+ instance->netif_bind_state == BIND_STATE_REGULAR &&
+ interface_up == 1)) {
+
+ qb_loop_timer_add (instance->totemudp_poll_handle,
+ QB_LOOP_MED,
+ instance->totem_config->downcheck_timeout*QB_TIME_NS_IN_MSEC,
+ (void *)instance,
+ timer_function_netif_check_timeout,
+ &instance->timer_netif_check_timeout);
+
+ /*
+ * Add a timer to check for a downed regular interface
+ */
+ return;
+ }
+
+ if (instance->totemudp_sockets.mcast_recv > 0) {
+ qb_loop_poll_del (instance->totemudp_poll_handle,
+ instance->totemudp_sockets.mcast_recv);
+ close (instance->totemudp_sockets.mcast_recv);
+ }
+ if (instance->totemudp_sockets.mcast_send > 0) {
+ close (instance->totemudp_sockets.mcast_send);
+ }
+ if (instance->totemudp_sockets.local_mcast_loop[0] > 0) {
+ qb_loop_poll_del (instance->totemudp_poll_handle,
+ instance->totemudp_sockets.local_mcast_loop[0]);
+ close (instance->totemudp_sockets.local_mcast_loop[0]);
+ close (instance->totemudp_sockets.local_mcast_loop[1]);
+ }
+ if (instance->totemudp_sockets.token > 0) {
+ qb_loop_poll_del (instance->totemudp_poll_handle,
+ instance->totemudp_sockets.token);
+ close (instance->totemudp_sockets.token);
+ }
+
+ if (interface_up == 0) {
+ /*
+ * Interface is not up
+ */
+ instance->netif_bind_state = BIND_STATE_LOOPBACK;
+ bind_address = &localhost;
+
+ /*
+ * Add a timer to retry building interfaces and request memb_gather_enter
+ */
+ qb_loop_timer_add (instance->totemudp_poll_handle,
+ QB_LOOP_MED,
+ instance->totem_config->downcheck_timeout*QB_TIME_NS_IN_MSEC,
+ (void *)instance,
+ timer_function_netif_check_timeout,
+ &instance->timer_netif_check_timeout);
+ } else {
+ /*
+ * Interface is up
+ */
+ instance->netif_bind_state = BIND_STATE_REGULAR;
+ bind_address = &instance->totem_interface->bindnet;
+ }
+ /*
+ * Create and bind the multicast and unicast sockets
+ */
+ (void)totemudp_build_sockets (instance,
+ &instance->mcast_address,
+ bind_address,
+ &instance->totemudp_sockets,
+ &instance->totem_interface->boundto);
+
+ qb_loop_poll_add (
+ instance->totemudp_poll_handle,
+ QB_LOOP_MED,
+ instance->totemudp_sockets.mcast_recv,
+ POLLIN, instance, net_deliver_fn);
+
+ qb_loop_poll_add (
+ instance->totemudp_poll_handle,
+ QB_LOOP_MED,
+ instance->totemudp_sockets.local_mcast_loop[0],
+ POLLIN, instance, net_deliver_fn);
+
+ qb_loop_poll_add (
+ instance->totemudp_poll_handle,
+ QB_LOOP_MED,
+ instance->totemudp_sockets.token,
+ POLLIN, instance, net_deliver_fn);
+
+ totemip_copy (&instance->my_id, &instance->totem_interface->boundto);
+
+ /*
+ * This reports changes in the interface to the user and totemsrp
+ */
+ if (instance->netif_bind_state == BIND_STATE_REGULAR) {
+ if (instance->netif_state_report & NETIF_STATE_REPORT_UP) {
+ log_printf (instance->totemudp_log_level_notice,
+ "The network interface [%s] is now up.",
+ totemip_print (&instance->totem_interface->boundto));
+ instance->netif_state_report = NETIF_STATE_REPORT_DOWN;
+ instance->totemudp_iface_change_fn (instance->context, &instance->my_id, 0);
+ }
+ /*
+ * Add a timer to check for interface going down in single membership
+ */
+ if (instance->my_memb_entries == 1) {
+ qb_loop_timer_add (instance->totemudp_poll_handle,
+ QB_LOOP_MED,
+ instance->totem_config->downcheck_timeout*QB_TIME_NS_IN_MSEC,
+ (void *)instance,
+ timer_function_netif_check_timeout,
+ &instance->timer_netif_check_timeout);
+ }
+
+ } else {
+ if (instance->netif_state_report & NETIF_STATE_REPORT_DOWN) {
+ log_printf (instance->totemudp_log_level_notice,
+ "The network interface is down.");
+ instance->totemudp_iface_change_fn (instance->context, &instance->my_id, 0);
+ }
+ instance->netif_state_report = NETIF_STATE_REPORT_UP;
+
+ }
+}
+
+/* Set the socket priority to INTERACTIVE to ensure
+ that our messages don't get queued behind anything else */
+static void totemudp_traffic_control_set(struct totemudp_instance *instance, int sock)
+{
+#ifdef SO_PRIORITY
+ int prio = 6; /* TC_PRIO_INTERACTIVE */
+
+ if (setsockopt(sock, SOL_SOCKET, SO_PRIORITY, &prio, sizeof(int))) {
+ LOGSYS_PERROR (errno, instance->totemudp_log_level_warning, "Could not set traffic priority");
+ }
+#endif
+}
+
+static int totemudp_build_sockets_ip (
+ struct totemudp_instance *instance,
+ struct totem_ip_address *mcast_address,
+ struct totem_ip_address *bindnet_address,
+ struct totemudp_socket *sockets,
+ struct totem_ip_address *bound_to,
+ int interface_num)
+{
+ struct sockaddr_storage sockaddr;
+ struct ipv6_mreq mreq6;
+ struct ip_mreq mreq;
+ struct sockaddr_storage mcast_ss, boundto_ss;
+ struct sockaddr_in6 *mcast_sin6 = (struct sockaddr_in6 *)&mcast_ss;
+ struct sockaddr_in *mcast_sin = (struct sockaddr_in *)&mcast_ss;
+ struct sockaddr_in *boundto_sin = (struct sockaddr_in *)&boundto_ss;
+ unsigned int sendbuf_size;
+ unsigned int recvbuf_size;
+ unsigned int optlen = sizeof (sendbuf_size);
+ unsigned int retries;
+ int addrlen;
+ int res;
+ int flag;
+ uint8_t sflag;
+ int i;
+
+ /*
+ * Create multicast recv socket
+ */
+ sockets->mcast_recv = socket (bindnet_address->family, SOCK_DGRAM, 0);
+ if (sockets->mcast_recv == -1) {
+ LOGSYS_PERROR (errno, instance->totemudp_log_level_warning,
+ "socket() failed");
+ return (-1);
+ }
+
+ totemip_nosigpipe (sockets->mcast_recv);
+ res = fcntl (sockets->mcast_recv, F_SETFL, O_NONBLOCK);
+ if (res == -1) {
+ LOGSYS_PERROR (errno, instance->totemudp_log_level_warning,
+ "Could not set non-blocking operation on multicast socket");
+ return (-1);
+ }
+
+ /*
+ * Force reuse
+ */
+ flag = 1;
+ if ( setsockopt(sockets->mcast_recv, SOL_SOCKET, SO_REUSEADDR, (char *)&flag, sizeof (flag)) < 0) {
+ LOGSYS_PERROR (errno, instance->totemudp_log_level_warning,
+ "setsockopt(SO_REUSEADDR) failed");
+ return (-1);
+ }
+
+ /*
+ * Create local multicast loop socket
+ */
+ if (socketpair(AF_UNIX, SOCK_DGRAM, 0, sockets->local_mcast_loop) == -1) {
+ LOGSYS_PERROR (errno, instance->totemudp_log_level_warning,
+ "socket() failed");
+ return (-1);
+ }
+
+ for (i = 0; i < 2; i++) {
+ totemip_nosigpipe (sockets->local_mcast_loop[i]);
+ res = fcntl (sockets->local_mcast_loop[i], F_SETFL, O_NONBLOCK);
+ if (res == -1) {
+ LOGSYS_PERROR (errno, instance->totemudp_log_level_warning,
+ "Could not set non-blocking operation on multicast socket");
+ return (-1);
+ }
+ }
+
+
+
+ /*
+ * Setup mcast send socket
+ */
+ sockets->mcast_send = socket (bindnet_address->family, SOCK_DGRAM, 0);
+ if (sockets->mcast_send == -1) {
+ LOGSYS_PERROR (errno, instance->totemudp_log_level_warning,
+ "socket() failed");
+ return (-1);
+ }
+
+ totemip_nosigpipe (sockets->mcast_send);
+ res = fcntl (sockets->mcast_send, F_SETFL, O_NONBLOCK);
+ if (res == -1) {
+ LOGSYS_PERROR (errno, instance->totemudp_log_level_warning,
+ "Could not set non-blocking operation on multicast socket");
+ return (-1);
+ }
+
+ /*
+ * Force reuse
+ */
+ flag = 1;
+ if ( setsockopt(sockets->mcast_send, SOL_SOCKET, SO_REUSEADDR, (char *)&flag, sizeof (flag)) < 0) {
+ LOGSYS_PERROR (errno, instance->totemudp_log_level_warning,
+ "setsockopt(SO_REUSEADDR) failed");
+ return (-1);
+ }
+
+ totemip_totemip_to_sockaddr_convert(bound_to, instance->totem_interface->ip_port - 1,
+ &sockaddr, &addrlen);
+
+ retries = 0;
+ while (1) {
+ res = bind (sockets->mcast_send, (struct sockaddr *)&sockaddr, addrlen);
+ if (res == 0) {
+ break;
+ }
+ LOGSYS_PERROR (errno, instance->totemudp_log_level_warning,
+ "Unable to bind the socket to send multicast packets");
+ if (++retries > BIND_MAX_RETRIES) {
+ break;
+ }
+
+ /*
+ * Wait for a while
+ */
+ (void)poll(NULL, 0, BIND_RETRIES_INTERVAL * retries);
+ }
+ if (res == -1) {
+ return (-1);
+ }
+
+ /*
+ * Setup unicast socket
+ */
+ sockets->token = socket (bindnet_address->family, SOCK_DGRAM, 0);
+ if (sockets->token == -1) {
+ LOGSYS_PERROR (errno, instance->totemudp_log_level_warning,
+ "socket() failed");
+ return (-1);
+ }
+
+ totemip_nosigpipe (sockets->token);
+ res = fcntl (sockets->token, F_SETFL, O_NONBLOCK);
+ if (res == -1) {
+ LOGSYS_PERROR (errno, instance->totemudp_log_level_warning,
+ "Could not set non-blocking operation on token socket");
+ return (-1);
+ }
+
+ /*
+ * Force reuse
+ */
+ flag = 1;
+ if ( setsockopt(sockets->token, SOL_SOCKET, SO_REUSEADDR, (char *)&flag, sizeof (flag)) < 0) {
+ LOGSYS_PERROR (errno, instance->totemudp_log_level_warning,
+ "setsockopt(SO_REUSEADDR) failed");
+ return (-1);
+ }
+
+ /*
+ * Bind to unicast socket used for token send/receives
+ * This has the side effect of binding to the correct interface
+ */
+ totemip_totemip_to_sockaddr_convert(bound_to, instance->totem_interface->ip_port, &sockaddr, &addrlen);
+
+ retries = 0;
+ while (1) {
+ res = bind (sockets->token, (struct sockaddr *)&sockaddr, addrlen);
+ if (res == 0) {
+ break;
+ }
+ LOGSYS_PERROR (errno, instance->totemudp_log_level_warning,
+ "Unable to bind UDP unicast socket");
+ if (++retries > BIND_MAX_RETRIES) {
+ break;
+ }
+
+ /*
+ * Wait for a while
+ */
+ (void)poll(NULL, 0, BIND_RETRIES_INTERVAL * retries);
+ }
+ if (res == -1) {
+ return (-1);
+ }
+
+ recvbuf_size = MCAST_SOCKET_BUFFER_SIZE;
+ sendbuf_size = MCAST_SOCKET_BUFFER_SIZE;
+ /*
+ * Set buffer sizes to avoid overruns
+ */
+ res = setsockopt (sockets->mcast_recv, SOL_SOCKET, SO_RCVBUF, &recvbuf_size, optlen);
+ if (res == -1) {
+ LOGSYS_PERROR (errno, instance->totemudp_log_level_debug,
+ "Unable to set SO_RCVBUF size on UDP mcast socket");
+ return (-1);
+ }
+ res = setsockopt (sockets->mcast_send, SOL_SOCKET, SO_SNDBUF, &sendbuf_size, optlen);
+ if (res == -1) {
+ LOGSYS_PERROR (errno, instance->totemudp_log_level_debug,
+ "Unable to set SO_SNDBUF size on UDP mcast socket");
+ return (-1);
+ }
+ res = setsockopt (sockets->local_mcast_loop[0], SOL_SOCKET, SO_RCVBUF, &recvbuf_size, optlen);
+ if (res == -1) {
+ LOGSYS_PERROR (errno, instance->totemudp_log_level_debug,
+ "Unable to set SO_RCVBUF size on UDP local mcast loop socket");
+ return (-1);
+ }
+ res = setsockopt (sockets->local_mcast_loop[1], SOL_SOCKET, SO_SNDBUF, &sendbuf_size, optlen);
+ if (res == -1) {
+ LOGSYS_PERROR (errno, instance->totemudp_log_level_debug,
+ "Unable to set SO_SNDBUF size on UDP local mcast loop socket");
+ return (-1);
+ }
+
+ res = getsockopt (sockets->mcast_recv, SOL_SOCKET, SO_RCVBUF, &recvbuf_size, &optlen);
+ if (res == 0) {
+ log_printf (instance->totemudp_log_level_debug,
+ "Receive multicast socket recv buffer size (%d bytes).", recvbuf_size);
+ }
+
+ res = getsockopt (sockets->mcast_send, SOL_SOCKET, SO_SNDBUF, &sendbuf_size, &optlen);
+ if (res == 0) {
+ log_printf (instance->totemudp_log_level_debug,
+ "Transmit multicast socket send buffer size (%d bytes).", sendbuf_size);
+ }
+
+ res = getsockopt (sockets->local_mcast_loop[0], SOL_SOCKET, SO_RCVBUF, &recvbuf_size, &optlen);
+ if (res == 0) {
+ log_printf (instance->totemudp_log_level_debug,
+ "Local receive multicast loop socket recv buffer size (%d bytes).", recvbuf_size);
+ }
+
+ res = getsockopt (sockets->local_mcast_loop[1], SOL_SOCKET, SO_SNDBUF, &sendbuf_size, &optlen);
+ if (res == 0) {
+ log_printf (instance->totemudp_log_level_debug,
+ "Local transmit multicast loop socket send buffer size (%d bytes).", sendbuf_size);
+ }
+
+
+ /*
+ * Join group membership on socket
+ */
+ totemip_totemip_to_sockaddr_convert(mcast_address, instance->totem_interface->ip_port, &mcast_ss, &addrlen);
+ totemip_totemip_to_sockaddr_convert(bound_to, instance->totem_interface->ip_port, &boundto_ss, &addrlen);
+
+ if (instance->totem_config->broadcast_use == 1) {
+ unsigned int broadcast = 1;
+
+ if ((setsockopt(sockets->mcast_recv, SOL_SOCKET,
+ SO_BROADCAST, &broadcast, sizeof (broadcast))) == -1) {
+ LOGSYS_PERROR (errno, instance->totemudp_log_level_warning,
+ "setting broadcast option failed");
+ return (-1);
+ }
+ if ((setsockopt(sockets->mcast_send, SOL_SOCKET,
+ SO_BROADCAST, &broadcast, sizeof (broadcast))) == -1) {
+ LOGSYS_PERROR (errno, instance->totemudp_log_level_warning,
+ "setting broadcast option failed");
+ return (-1);
+ }
+ } else {
+ switch (bindnet_address->family) {
+ case AF_INET:
+ memset(&mreq, 0, sizeof(mreq));
+ mreq.imr_multiaddr.s_addr = mcast_sin->sin_addr.s_addr;
+ mreq.imr_interface.s_addr = boundto_sin->sin_addr.s_addr;
+ res = setsockopt (sockets->mcast_recv, IPPROTO_IP, IP_ADD_MEMBERSHIP,
+ &mreq, sizeof (mreq));
+ if (res == -1) {
+ LOGSYS_PERROR (errno, instance->totemudp_log_level_warning,
+ "join ipv4 multicast group failed");
+ return (-1);
+ }
+ break;
+ case AF_INET6:
+ memset(&mreq6, 0, sizeof(mreq6));
+ memcpy(&mreq6.ipv6mr_multiaddr, &mcast_sin6->sin6_addr, sizeof(struct in6_addr));
+ mreq6.ipv6mr_interface = interface_num;
+
+ res = setsockopt (sockets->mcast_recv, IPPROTO_IPV6, IPV6_JOIN_GROUP,
+ &mreq6, sizeof (mreq6));
+ if (res == -1) {
+ LOGSYS_PERROR (errno, instance->totemudp_log_level_warning,
+ "join ipv6 multicast group failed");
+ return (-1);
+ }
+ break;
+ }
+ }
+
+ /*
+ * Turn off multicast loopback
+ */
+
+ flag = 0;
+ switch ( bindnet_address->family ) {
+ case AF_INET:
+ sflag = 0;
+ res = setsockopt (sockets->mcast_send, IPPROTO_IP, IP_MULTICAST_LOOP,
+ &sflag, sizeof (sflag));
+ break;
+ case AF_INET6:
+ res = setsockopt (sockets->mcast_send, IPPROTO_IPV6, IPV6_MULTICAST_LOOP,
+ &flag, sizeof (flag));
+ }
+ if (res == -1) {
+ LOGSYS_PERROR (errno, instance->totemudp_log_level_warning,
+ "Unable to turn off multicast loopback");
+ return (-1);
+ }
+
+ /*
+ * Set multicast packets TTL
+ */
+ flag = instance->totem_interface->ttl;
+ if (bindnet_address->family == AF_INET6) {
+ res = setsockopt (sockets->mcast_send, IPPROTO_IPV6, IPV6_MULTICAST_HOPS,
+ &flag, sizeof (flag));
+ if (res == -1) {
+ LOGSYS_PERROR (errno, instance->totemudp_log_level_warning,
+ "set mcast v6 TTL failed");
+ return (-1);
+ }
+ } else {
+ sflag = flag;
+ res = setsockopt(sockets->mcast_send, IPPROTO_IP, IP_MULTICAST_TTL,
+ &sflag, sizeof(sflag));
+ if (res == -1) {
+ LOGSYS_PERROR (errno, instance->totemudp_log_level_warning,
+ "set mcast v4 TTL failed");
+ return (-1);
+ }
+ }
+
+ /*
+ * Bind to a specific interface for multicast send and receive
+ */
+ switch ( bindnet_address->family ) {
+ case AF_INET:
+ if (setsockopt (sockets->mcast_send, IPPROTO_IP, IP_MULTICAST_IF,
+ &boundto_sin->sin_addr, sizeof (boundto_sin->sin_addr)) < 0) {
+ LOGSYS_PERROR (errno, instance->totemudp_log_level_warning,
+ "cannot select interface for multicast packets (send)");
+ return (-1);
+ }
+ if (setsockopt (sockets->mcast_recv, IPPROTO_IP, IP_MULTICAST_IF,
+ &boundto_sin->sin_addr, sizeof (boundto_sin->sin_addr)) < 0) {
+ LOGSYS_PERROR (errno, instance->totemudp_log_level_warning,
+ "cannot select interface for multicast packets (recv)");
+ return (-1);
+ }
+ break;
+ case AF_INET6:
+ if (setsockopt (sockets->mcast_send, IPPROTO_IPV6, IPV6_MULTICAST_IF,
+ &interface_num, sizeof (interface_num)) < 0) {
+ LOGSYS_PERROR (errno, instance->totemudp_log_level_warning,
+ "cannot select interface for multicast packets (send v6)");
+ return (-1);
+ }
+ if (setsockopt (sockets->mcast_recv, IPPROTO_IPV6, IPV6_MULTICAST_IF,
+ &interface_num, sizeof (interface_num)) < 0) {
+ LOGSYS_PERROR (errno, instance->totemudp_log_level_warning,
+ "cannot select interface for multicast packets (recv v6)");
+ return (-1);
+ }
+ break;
+ }
+
+ /*
+ * Bind to multicast socket used for multicast receives
+ * This needs to happen after all of the multicast setsockopt() calls
+ * as the kernel seems to only put them into effect (for IPV6) when bind()
+ * is called.
+ */
+ totemip_totemip_to_sockaddr_convert(mcast_address,
+ instance->totem_interface->ip_port, &sockaddr, &addrlen);
+
+ retries = 0;
+ while (1) {
+ res = bind (sockets->mcast_recv, (struct sockaddr *)&sockaddr, addrlen);
+ if (res == 0) {
+ break;
+ }
+ LOGSYS_PERROR (errno, instance->totemudp_log_level_warning,
+ "Unable to bind the socket to receive multicast packets");
+ if (++retries > BIND_MAX_RETRIES) {
+ break;
+ }
+
+ /*
+ * Wait for a while
+ */
+ (void)poll(NULL, 0, BIND_RETRIES_INTERVAL * retries);
+ }
+
+ if (res == -1) {
+ return (-1);
+ }
+ return 0;
+}
+
+static int totemudp_build_sockets (
+ struct totemudp_instance *instance,
+ struct totem_ip_address *mcast_address,
+ struct totem_ip_address *bindnet_address,
+ struct totemudp_socket *sockets,
+ struct totem_ip_address *bound_to)
+{
+ int interface_num;
+ int interface_up;
+ int res;
+
+ /*
+ * Determine the ip address bound to and the interface name
+ */
+ res = netif_determine (instance,
+ bindnet_address,
+ bound_to,
+ &interface_up,
+ &interface_num);
+
+ if (res == -1) {
+ return (-1);
+ }
+
+ totemip_copy(&instance->my_id, bound_to);
+
+ res = totemudp_build_sockets_ip (instance, mcast_address,
+ bindnet_address, sockets, bound_to, interface_num);
+
+ if (res == -1) {
+ /* if we get here, corosync won't work anyway, so better leaving than faking to work */
+ LOGSYS_PERROR (errno, instance->totemudp_log_level_error,
+ "Unable to create sockets, exiting");
+ exit(EXIT_FAILURE);
+ }
+
+ /* We only send out of the token socket */
+ totemudp_traffic_control_set(instance, sockets->token);
+ return res;
+}
+
+/*
+ * Totem Network interface
+ * depends on poll abstraction, POSIX, IPV4
+ */
+
+/*
+ * Create an instance
+ */
+int totemudp_initialize (
+ qb_loop_t *poll_handle,
+ void **udp_context,
+ struct totem_config *totem_config,
+ totemsrp_stats_t *stats,
+
+ void *context,
+
+ int (*deliver_fn) (
+ void *context,
+ const void *msg,
+ unsigned int msg_len,
+ const struct sockaddr_storage *system_from),
+
+ int (*iface_change_fn) (
+ void *context,
+ const struct totem_ip_address *iface_address,
+ unsigned int ring_no),
+
+ void (*mtu_changed) (
+ void *context,
+ int net_mtu),
+
+ void (*target_set_completed) (
+ void *context))
+{
+ struct totemudp_instance *instance;
+
+ instance = malloc (sizeof (struct totemudp_instance));
+ if (instance == NULL) {
+ return (-1);
+ }
+
+ totemudp_instance_initialize (instance);
+
+ instance->totem_config = totem_config;
+ instance->stats = stats;
+
+ /*
+ * Configure logging
+ */
+ instance->totemudp_log_level_security = 1; //totem_config->totem_logging_configuration.log_level_security;
+ instance->totemudp_log_level_error = totem_config->totem_logging_configuration.log_level_error;
+ instance->totemudp_log_level_warning = totem_config->totem_logging_configuration.log_level_warning;
+ instance->totemudp_log_level_notice = totem_config->totem_logging_configuration.log_level_notice;
+ instance->totemudp_log_level_debug = totem_config->totem_logging_configuration.log_level_debug;
+ instance->totemudp_subsys_id = totem_config->totem_logging_configuration.log_subsys_id;
+ instance->totemudp_log_printf = totem_config->totem_logging_configuration.log_printf;
+
+ /*
+ * Initialize local variables for totemudp
+ */
+ instance->totem_interface = &totem_config->interfaces[0];
+ totemip_copy (&instance->mcast_address, &instance->totem_interface->mcast_addr);
+ memset (instance->iov_buffer, 0, UDP_RECEIVE_FRAME_SIZE_MAX);
+
+ instance->totemudp_poll_handle = poll_handle;
+
+ instance->totem_interface->bindnet.nodeid = instance->totem_config->node_id;
+
+ instance->context = context;
+ instance->totemudp_deliver_fn = deliver_fn;
+
+ instance->totemudp_iface_change_fn = iface_change_fn;
+
+ instance->totemudp_target_set_completed = target_set_completed;
+
+ totemip_localhost (instance->mcast_address.family, &localhost);
+ localhost.nodeid = instance->totem_config->node_id;
+
+ /*
+ * RRP layer isn't ready to receive message because it hasn't
+ * initialized yet. Add short timer to check the interfaces.
+ */
+ qb_loop_timer_add (instance->totemudp_poll_handle,
+ QB_LOOP_MED,
+ 100*QB_TIME_NS_IN_MSEC,
+ (void *)instance,
+ timer_function_netif_check_timeout,
+ &instance->timer_netif_check_timeout);
+
+ *udp_context = instance;
+ return (0);
+}
+
+void *totemudp_buffer_alloc (void)
+{
+ return malloc (FRAME_SIZE_MAX);
+}
+
+void totemudp_buffer_release (void *ptr)
+{
+ return free (ptr);
+}
+
+int totemudp_processor_count_set (
+ void *udp_context,
+ int processor_count)
+{
+ struct totemudp_instance *instance = (struct totemudp_instance *)udp_context;
+ int res = 0;
+
+ instance->my_memb_entries = processor_count;
+ qb_loop_timer_del (instance->totemudp_poll_handle,
+ instance->timer_netif_check_timeout);
+ if (processor_count == 1) {
+ qb_loop_timer_add (instance->totemudp_poll_handle,
+ QB_LOOP_MED,
+ instance->totem_config->downcheck_timeout*QB_TIME_NS_IN_MSEC,
+ (void *)instance,
+ timer_function_netif_check_timeout,
+ &instance->timer_netif_check_timeout);
+ }
+
+ return (res);
+}
+
+int totemudp_recv_flush (void *udp_context)
+{
+ struct totemudp_instance *instance = (struct totemudp_instance *)udp_context;
+ struct pollfd ufd;
+ int nfds;
+ int res = 0;
+ int i;
+ int sock;
+
+ instance->flushing = 1;
+
+ for (i = 0; i < 2; i++) {
+ sock = -1;
+ if (i == 0) {
+ sock = instance->totemudp_sockets.mcast_recv;
+ }
+ if (i == 1) {
+ sock = instance->totemudp_sockets.local_mcast_loop[0];
+ }
+ assert(sock != -1);
+
+ do {
+ ufd.fd = sock;
+ ufd.events = POLLIN;
+ nfds = poll (&ufd, 1, 0);
+ if (nfds == 1 && ufd.revents & POLLIN) {
+ net_deliver_fn (sock, ufd.revents, instance);
+ }
+ } while (nfds == 1);
+ }
+
+ instance->flushing = 0;
+
+ return (res);
+}
+
+int totemudp_send_flush (void *udp_context)
+{
+ return 0;
+}
+
+int totemudp_token_send (
+ void *udp_context,
+ const void *msg,
+ unsigned int msg_len)
+{
+ struct totemudp_instance *instance = (struct totemudp_instance *)udp_context;
+ int res = 0;
+
+ ucast_sendmsg (instance, &instance->token_target, msg, msg_len);
+
+ return (res);
+}
+int totemudp_mcast_flush_send (
+ void *udp_context,
+ const void *msg,
+ unsigned int msg_len)
+{
+ struct totemudp_instance *instance = (struct totemudp_instance *)udp_context;
+ int res = 0;
+
+ mcast_sendmsg (instance, msg, msg_len);
+
+ return (res);
+}
+
+int totemudp_mcast_noflush_send (
+ void *udp_context,
+ const void *msg,
+ unsigned int msg_len)
+{
+ struct totemudp_instance *instance = (struct totemudp_instance *)udp_context;
+ int res = 0;
+
+ mcast_sendmsg (instance, msg, msg_len);
+
+ return (res);
+}
+
+extern int totemudp_iface_check (void *udp_context)
+{
+ struct totemudp_instance *instance = (struct totemudp_instance *)udp_context;
+ int res = 0;
+
+ timer_function_netif_check_timeout (instance);
+
+ return (res);
+}
+
+int totemudp_nodestatus_get (void *udp_context, unsigned int nodeid,
+ struct totem_node_status *node_status)
+{
+ struct totemudp_instance *instance = (struct totemudp_instance *)udp_context;
+ struct qb_list_head *list;
+ struct totemudp_member *member;
+
+ qb_list_for_each(list, &(instance->member_list)) {
+ member = qb_list_entry (list,
+ struct totemudp_member,
+ list);
+
+ if (member->member.nodeid == nodeid) {
+ node_status->nodeid = nodeid;
+ /* reachable is filled in by totemsrp */
+ node_status->link_status[0].enabled = 1;
+ if (instance->netif_bind_state == BIND_STATE_REGULAR) {
+ node_status->link_status[0].enabled = 1;
+ } else {
+ node_status->link_status[0].enabled = 0;
+ }
+ node_status->link_status[0].connected = node_status->reachable;
+ node_status->link_status[0].mtu = instance->totem_config->net_mtu;
+ strncpy(node_status->link_status[0].src_ipaddr, totemip_print(&member->member), KNET_MAX_HOST_LEN-1);
+ }
+ }
+ return (0);
+}
+
+int totemudp_ifaces_get (
+ void *net_context,
+ char ***status,
+ unsigned int *iface_count)
+{
+ static char *statuses[INTERFACE_MAX] = {(char*)"OK"};
+
+ if (status) {
+ *status = statuses;
+ }
+ *iface_count = 1;
+
+ return (0);
+}
+
+extern void totemudp_net_mtu_adjust (void *udp_context, struct totem_config *totem_config)
+{
+ totem_config->net_mtu -= totemip_udpip_header_size(totem_config->interfaces[0].bindnet.family);
+}
+
+int totemudp_token_target_set (
+ void *udp_context,
+ unsigned int nodeid)
+{
+ struct totemudp_instance *instance = (struct totemudp_instance *)udp_context;
+ struct qb_list_head *list;
+ struct totemudp_member *member;
+ int res = 0;
+
+ qb_list_for_each(list, &(instance->member_list)) {
+ member = qb_list_entry (list,
+ struct totemudp_member,
+ list);
+
+ if (member->member.nodeid == nodeid) {
+ memcpy (&instance->token_target, &member->member,
+ sizeof (struct totem_ip_address));
+
+ instance->totemudp_target_set_completed (instance->context);
+ break;
+ }
+ }
+ return (res);
+}
+
+extern int totemudp_recv_mcast_empty (
+ void *udp_context)
+{
+ struct totemudp_instance *instance = (struct totemudp_instance *)udp_context;
+ unsigned int res;
+ struct sockaddr_storage system_from;
+ struct msghdr msg_recv;
+ struct pollfd ufd;
+ int nfds;
+ int msg_processed = 0;
+ int i;
+ int sock;
+
+ /*
+ * Receive datagram
+ */
+ msg_recv.msg_name = &system_from;
+ msg_recv.msg_namelen = sizeof (struct sockaddr_storage);
+ msg_recv.msg_iov = &instance->totemudp_iov_recv_flush;
+ msg_recv.msg_iovlen = 1;
+#ifdef HAVE_MSGHDR_CONTROL
+ msg_recv.msg_control = 0;
+#endif
+#ifdef HAVE_MSGHDR_CONTROLLEN
+ msg_recv.msg_controllen = 0;
+#endif
+#ifdef HAVE_MSGHDR_FLAGS
+ msg_recv.msg_flags = 0;
+#endif
+#ifdef HAVE_MSGHDR_ACCRIGHTS
+ msg_recv.msg_accrights = NULL;
+#endif
+#ifdef HAVE_MSGHDR_ACCRIGHTSLEN
+ msg_recv.msg_accrightslen = 0;
+#endif
+
+ for (i = 0; i < 2; i++) {
+ sock = -1;
+ if (i == 0) {
+ sock = instance->totemudp_sockets.mcast_recv;
+ }
+ if (i == 1) {
+ sock = instance->totemudp_sockets.local_mcast_loop[0];
+ }
+ assert(sock != -1);
+
+ do {
+ ufd.fd = sock;
+ ufd.events = POLLIN;
+ nfds = poll (&ufd, 1, 0);
+ if (nfds == 1 && ufd.revents & POLLIN) {
+ res = recvmsg (sock, &msg_recv, MSG_NOSIGNAL | MSG_DONTWAIT);
+ if (res != -1) {
+ msg_processed = 1;
+ } else {
+ msg_processed = -1;
+ }
+ }
+ } while (nfds == 1);
+ }
+
+ return (msg_processed);
+}
+
+
+int totemudp_member_add (
+ void *udp_context,
+ const struct totem_ip_address *local,
+ const struct totem_ip_address *member,
+ int ring_no)
+{
+ struct totemudp_instance *instance = (struct totemudp_instance *)udp_context;
+
+ struct totemudp_member *new_member;
+
+ new_member = malloc (sizeof (struct totemudp_member));
+ if (new_member == NULL) {
+ return (-1);
+ }
+
+ memset(new_member, 0, sizeof(*new_member));
+
+ qb_list_init (&new_member->list);
+ qb_list_add_tail (&new_member->list, &instance->member_list);
+ memcpy (&new_member->member, member, sizeof (struct totem_ip_address));
+
+ return (0);
+}
+
+int totemudp_member_remove (
+ void *udp_context,
+ const struct totem_ip_address *token_target,
+ int ring_no)
+{
+ int found = 0;
+ struct qb_list_head *list;
+ struct totemudp_member *member;
+ struct totemudp_instance *instance = (struct totemudp_instance *)udp_context;
+
+ /*
+ * Find the member to remove and close its socket
+ */
+ qb_list_for_each(list, &(instance->member_list)) {
+ member = qb_list_entry (list,
+ struct totemudp_member,
+ list);
+
+ if (totemip_compare (token_target, &member->member)==0) {
+ found = 1;
+ break;
+ }
+ }
+
+ /*
+ * Delete the member from the list
+ */
+ if (found) {
+ qb_list_del (list);
+ }
+
+ return (0);
+}
+
+int totemudp_iface_set (void *net_context,
+ const struct totem_ip_address *local_addr,
+ unsigned short ip_port,
+ unsigned int iface_no)
+{
+ /* Not supported */
+ return (-1);
+}
+
+int totemudp_reconfigure (
+ void *udp_context,
+ struct totem_config *totem_config)
+{
+ /* Not supported */
+ return (-1);
+}
diff --git a/exec/totemudp.h b/exec/totemudp.h
new file mode 100644
index 0000000..6642472
--- /dev/null
+++ b/exec/totemudp.h
@@ -0,0 +1,144 @@
+/*
+ * Copyright (c) 2005 MontaVista Software, Inc.
+ * Copyright (c) 2006-2011 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Author: Steven Dake (sdake@redhat.com)
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of the MontaVista Software, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef TOTEMUDP_H_DEFINED
+#define TOTEMUDP_H_DEFINED
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <qb/qbloop.h>
+
+#include <corosync/totem/totem.h>
+
+/**
+ * Create an instance
+ */
+extern int totemudp_initialize (
+ qb_loop_t* poll_handle,
+ void **udp_context,
+ struct totem_config *totem_config,
+ totemsrp_stats_t *stats,
+ void *context,
+
+ int (*deliver_fn) (
+ void *context,
+ const void *msg,
+ unsigned int msg_len,
+ const struct sockaddr_storage *system_from),
+
+ int (*iface_change_fn) (
+ void *context,
+ const struct totem_ip_address *iface_address,
+ unsigned int ring_no),
+
+ void (*mtu_changed) (
+ void *context,
+ int net_mtu),
+
+ void (*target_set_completed) (
+ void *context));
+
+extern void *totemudp_buffer_alloc (void);
+
+extern void totemudp_buffer_release (void *ptr);
+
+extern int totemudp_processor_count_set (
+ void *udp_context,
+ int processor_count);
+
+extern int totemudp_token_send (
+ void *udp_context,
+ const void *msg,
+ unsigned int msg_len);
+
+extern int totemudp_mcast_flush_send (
+ void *udp_context,
+ const void *msg,
+ unsigned int msg_len);
+
+extern int totemudp_mcast_noflush_send (
+ void *udp_context,
+ const void *msg,
+ unsigned int msg_len);
+
+extern int totemudp_nodestatus_get (void *net_context, unsigned int nodeid,
+ struct totem_node_status *node_status);
+
+extern int totemudp_ifaces_get (void *net_context,
+ char ***status,
+ unsigned int *iface_count);
+
+extern int totemudp_recv_flush (void *udp_context);
+
+extern int totemudp_send_flush (void *udp_context);
+
+extern int totemudp_iface_set (void *net_context,
+ const struct totem_ip_address *local_addr,
+ unsigned short ip_port,
+ unsigned int iface_no);
+
+extern int totemudp_iface_check (void *udp_context);
+
+extern int totemudp_finalize (void *udp_context);
+
+extern void totemudp_net_mtu_adjust (void *udp_context, struct totem_config *totem_config);
+
+extern int totemudp_token_target_set (
+ void *udp_context,
+ unsigned int nodeid);
+
+extern int totemudp_crypto_set (
+ void *udp_context,
+ const char *cipher_type,
+ const char *hash_type);
+
+extern int totemudp_recv_mcast_empty (
+ void *udp_context);
+
+extern int totemudp_member_add (
+ void *udpu_context,
+ const struct totem_ip_address *local,
+ const struct totem_ip_address *member,
+ int ring_no);
+
+extern int totemudp_member_remove (
+ void *udpu_context,
+ const struct totem_ip_address *member,
+ int ring_no);
+
+extern int totemudp_reconfigure (
+ void *udp_context,
+ struct totem_config *totem_config);
+
+#endif /* TOTEMUDP_H_DEFINED */
diff --git a/exec/totemudpu.c b/exec/totemudpu.c
new file mode 100644
index 0000000..399b47b
--- /dev/null
+++ b/exec/totemudpu.c
@@ -0,0 +1,1453 @@
+/*
+ * Copyright (c) 2005 MontaVista Software, Inc.
+ * Copyright (c) 2006-2018 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Author: Steven Dake (sdake@redhat.com)
+
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of the MontaVista Software, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include <assert.h>
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <sys/un.h>
+#include <sys/ioctl.h>
+#include <sys/param.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+#include <sched.h>
+#include <time.h>
+#include <sys/time.h>
+#include <sys/poll.h>
+#include <sys/uio.h>
+#include <limits.h>
+
+#include <qb/qblist.h>
+#include <qb/qbdefs.h>
+#include <qb/qbloop.h>
+
+#include <corosync/sq.h>
+#include <corosync/swab.h>
+#define LOGSYS_UTILS_ONLY 1
+#include <corosync/logsys.h>
+#include "totemudpu.h"
+
+#include "util.h"
+
+#ifndef MSG_NOSIGNAL
+#define MSG_NOSIGNAL 0
+#endif
+
+#define MCAST_SOCKET_BUFFER_SIZE (TRANSMITS_ALLOWED * UDP_RECEIVE_FRAME_SIZE_MAX)
+#define NETIF_STATE_REPORT_UP 1
+#define NETIF_STATE_REPORT_DOWN 2
+
+#define BIND_STATE_UNBOUND 0
+#define BIND_STATE_REGULAR 1
+#define BIND_STATE_LOOPBACK 2
+
+struct totemudpu_member {
+ struct qb_list_head list;
+ struct totem_ip_address member;
+ int fd;
+ int active;
+};
+
+struct totemudpu_instance {
+ qb_loop_t *totemudpu_poll_handle;
+
+ struct totem_interface *totem_interface;
+
+ int netif_state_report;
+
+ int netif_bind_state;
+
+ void *context;
+
+ int (*totemudpu_deliver_fn) (
+ void *context,
+ const void *msg,
+ unsigned int msg_len,
+ const struct sockaddr_storage *system_from);
+
+ int (*totemudpu_iface_change_fn) (
+ void *context,
+ const struct totem_ip_address *iface_address,
+ unsigned int ring_no);
+
+ void (*totemudpu_target_set_completed) (void *context);
+
+ /*
+ * Function and data used to log messages
+ */
+ int totemudpu_log_level_security;
+
+ int totemudpu_log_level_error;
+
+ int totemudpu_log_level_warning;
+
+ int totemudpu_log_level_notice;
+
+ int totemudpu_log_level_debug;
+
+ int totemudpu_subsys_id;
+
+ void (*totemudpu_log_printf) (
+ int level,
+ int subsys,
+ const char *function,
+ const char *file,
+ int line,
+ const char *format,
+ ...)__attribute__((format(printf, 6, 7)));
+
+ void *udpu_context;
+
+ char iov_buffer[UDP_RECEIVE_FRAME_SIZE_MAX];
+
+ struct iovec totemudpu_iov_recv;
+
+ struct qb_list_head member_list;
+
+ int stats_sent;
+
+ int stats_recv;
+
+ int stats_delv;
+
+ int stats_remcasts;
+
+ int stats_orf_token;
+
+ struct timeval stats_tv_start;
+
+ struct totem_ip_address my_id;
+
+ int firstrun;
+
+ qb_loop_timer_handle timer_netif_check_timeout;
+
+ unsigned int my_memb_entries;
+
+ struct totem_config *totem_config;
+
+ totemsrp_stats_t *stats;
+
+ struct totem_ip_address token_target;
+
+ int token_socket;
+
+ int local_loop_sock[2];
+
+ qb_loop_timer_handle timer_merge_detect_timeout;
+
+ int send_merge_detect_message;
+
+ unsigned int merge_detect_messages_sent_before_timeout;
+};
+
+struct work_item {
+ const void *msg;
+ unsigned int msg_len;
+ struct totemudpu_instance *instance;
+};
+
+static int totemudpu_build_sockets (
+ struct totemudpu_instance *instance,
+ struct totem_ip_address *bindnet_address,
+ struct totem_ip_address *bound_to);
+
+static int totemudpu_create_sending_socket(
+ void *udpu_context,
+ const struct totem_ip_address *member);
+
+int totemudpu_member_list_rebind_ip (
+ void *udpu_context);
+
+static void totemudpu_start_merge_detect_timeout(
+ void *udpu_context);
+
+static void totemudpu_stop_merge_detect_timeout(
+ void *udpu_context);
+
+static void totemudpu_instance_initialize (struct totemudpu_instance *instance)
+{
+ memset (instance, 0, sizeof (struct totemudpu_instance));
+
+ instance->netif_state_report = NETIF_STATE_REPORT_UP | NETIF_STATE_REPORT_DOWN;
+
+ instance->totemudpu_iov_recv.iov_base = instance->iov_buffer;
+
+ instance->totemudpu_iov_recv.iov_len = UDP_RECEIVE_FRAME_SIZE_MAX; //sizeof (instance->iov_buffer);
+
+ /*
+ * There is always atleast 1 processor
+ */
+ instance->my_memb_entries = 1;
+
+ qb_list_init (&instance->member_list);
+}
+
+#define log_printf(level, format, args...) \
+do { \
+ instance->totemudpu_log_printf ( \
+ level, instance->totemudpu_subsys_id, \
+ __FUNCTION__, __FILE__, __LINE__, \
+ (const char *)format, ##args); \
+} while (0);
+#define LOGSYS_PERROR(err_num, level, fmt, args...) \
+do { \
+ char _error_str[LOGSYS_MAX_PERROR_MSG_LEN]; \
+ const char *_error_ptr = qb_strerror_r(err_num, _error_str, sizeof(_error_str)); \
+ instance->totemudpu_log_printf ( \
+ level, instance->totemudpu_subsys_id, \
+ __FUNCTION__, __FILE__, __LINE__, \
+ fmt ": %s (%d)", ##args, _error_ptr, err_num); \
+ } while(0)
+
+int totemudpu_crypto_set (
+ void *udpu_context,
+ const char *cipher_type,
+ const char *hash_type)
+{
+
+ return (0);
+}
+
+
+static inline void ucast_sendmsg (
+ struct totemudpu_instance *instance,
+ struct totem_ip_address *system_to,
+ const void *msg,
+ unsigned int msg_len)
+{
+ struct msghdr msg_ucast;
+ int res = 0;
+ struct sockaddr_storage sockaddr;
+ struct iovec iovec;
+ int addrlen;
+ int send_sock;
+
+ iovec.iov_base = (void *)msg;
+ iovec.iov_len = msg_len;
+
+ /*
+ * Build unicast message
+ */
+ totemip_totemip_to_sockaddr_convert(system_to,
+ instance->totem_interface->ip_port, &sockaddr, &addrlen);
+ memset(&msg_ucast, 0, sizeof(msg_ucast));
+ msg_ucast.msg_name = &sockaddr;
+ msg_ucast.msg_namelen = addrlen;
+ msg_ucast.msg_iov = (void *)&iovec;
+ msg_ucast.msg_iovlen = 1;
+#ifdef HAVE_MSGHDR_CONTROL
+ msg_ucast.msg_control = 0;
+#endif
+#ifdef HAVE_MSGHDR_CONTROLLEN
+ msg_ucast.msg_controllen = 0;
+#endif
+#ifdef HAVE_MSGHDR_FLAGS
+ msg_ucast.msg_flags = 0;
+#endif
+#ifdef HAVE_MSGHDR_ACCRIGHTS
+ msg_ucast.msg_accrights = NULL;
+#endif
+#ifdef HAVE_MSGHDR_ACCRIGHTSLEN
+ msg_ucast.msg_accrightslen = 0;
+#endif
+
+ if (instance->netif_bind_state == BIND_STATE_REGULAR) {
+ send_sock = instance->token_socket;
+ } else {
+ send_sock = instance->local_loop_sock[1];
+ msg_ucast.msg_name = NULL;
+ msg_ucast.msg_namelen = 0;
+ }
+
+
+ /*
+ * Transmit unicast message
+ * An error here is recovered by totemsrp
+ */
+ res = sendmsg (send_sock, &msg_ucast, MSG_NOSIGNAL);
+ if (res < 0) {
+ LOGSYS_PERROR (errno, instance->totemudpu_log_level_debug,
+ "sendmsg(ucast) failed (non-critical)");
+ }
+}
+
+static inline void mcast_sendmsg (
+ struct totemudpu_instance *instance,
+ const void *msg,
+ unsigned int msg_len,
+ int only_active)
+{
+ struct msghdr msg_mcast;
+ int res = 0;
+ struct iovec iovec;
+ struct sockaddr_storage sockaddr;
+ int addrlen;
+ struct qb_list_head *list;
+ struct totemudpu_member *member;
+
+ iovec.iov_base = (void *)msg;
+ iovec.iov_len = msg_len;
+
+ memset(&msg_mcast, 0, sizeof(msg_mcast));
+ /*
+ * Build multicast message
+ */
+ if (instance->netif_bind_state == BIND_STATE_REGULAR) {
+ qb_list_for_each(list, &(instance->member_list)) {
+ member = qb_list_entry (list,
+ struct totemudpu_member,
+ list);
+ /*
+ * Do not send multicast message if message is not "flush", member
+ * is inactive and timeout for sending merge message didn't expired.
+ */
+ if (only_active && !member->active && !instance->send_merge_detect_message)
+ continue ;
+
+ totemip_totemip_to_sockaddr_convert(&member->member,
+ instance->totem_interface->ip_port, &sockaddr, &addrlen);
+ msg_mcast.msg_name = &sockaddr;
+ msg_mcast.msg_namelen = addrlen;
+ msg_mcast.msg_iov = (void *)&iovec;
+ msg_mcast.msg_iovlen = 1;
+ #ifdef HAVE_MSGHDR_CONTROL
+ msg_mcast.msg_control = 0;
+ #endif
+ #ifdef HAVE_MSGHDR_CONTROLLEN
+ msg_mcast.msg_controllen = 0;
+ #endif
+ #ifdef HAVE_MSGHDR_FLAGS
+ msg_mcast.msg_flags = 0;
+ #endif
+ #ifdef HAVE_MSGHDR_ACCRIGHTS
+ msg_mcast.msg_accrights = NULL;
+ #endif
+ #ifdef HAVE_MSGHDR_ACCRIGHTSLEN
+ msg_mcast.msg_accrightslen = 0;
+ #endif
+
+ /*
+ * Transmit multicast message
+ * An error here is recovered by totemsrp
+ */
+ res = sendmsg (member->fd, &msg_mcast, MSG_NOSIGNAL);
+ if (res < 0) {
+ LOGSYS_PERROR (errno, instance->totemudpu_log_level_debug,
+ "sendmsg(mcast) failed (non-critical)");
+ }
+ }
+
+ if (!only_active || instance->send_merge_detect_message) {
+ /*
+ * Current message was sent to all nodes
+ */
+ instance->merge_detect_messages_sent_before_timeout++;
+ instance->send_merge_detect_message = 0;
+ }
+ } else {
+ /*
+ * Transmit multicast message to local unix mcast loop
+ * An error here is recovered by totemsrp
+ */
+ msg_mcast.msg_name = NULL;
+ msg_mcast.msg_namelen = 0;
+ msg_mcast.msg_iov = (void *)&iovec;
+ msg_mcast.msg_iovlen = 1;
+ #ifdef HAVE_MSGHDR_CONTROL
+ msg_mcast.msg_control = 0;
+ #endif
+ #ifdef HAVE_MSGHDR_CONTROLLEN
+ msg_mcast.msg_controllen = 0;
+ #endif
+ #ifdef HAVE_MSGHDR_FLAGS
+ msg_mcast.msg_flags = 0;
+ #endif
+ #ifdef HAVE_MSGHDR_ACCRIGHTS
+ msg_mcast.msg_accrights = NULL;
+ #endif
+ #ifdef HAVE_MSGHDR_ACCRIGHTSLEN
+ msg_mcast.msg_accrightslen = 0;
+ #endif
+
+ res = sendmsg (instance->local_loop_sock[1], &msg_mcast,
+ MSG_NOSIGNAL);
+ if (res < 0) {
+ LOGSYS_PERROR (errno, instance->totemudpu_log_level_debug,
+ "sendmsg(local mcast loop) failed (non-critical)");
+ }
+ }
+}
+
+int totemudpu_finalize (
+ void *udpu_context)
+{
+ struct totemudpu_instance *instance = (struct totemudpu_instance *)udpu_context;
+ int res = 0;
+
+ if (instance->token_socket > 0) {
+ qb_loop_poll_del (instance->totemudpu_poll_handle,
+ instance->token_socket);
+ close (instance->token_socket);
+ }
+
+ if (instance->local_loop_sock[0] > 0) {
+ qb_loop_poll_del (instance->totemudpu_poll_handle,
+ instance->local_loop_sock[0]);
+ close (instance->local_loop_sock[0]);
+ close (instance->local_loop_sock[1]);
+ }
+
+ totemudpu_stop_merge_detect_timeout(instance);
+
+ return (res);
+}
+
+static struct totemudpu_member *find_member_by_sockaddr(
+ const void *udpu_context,
+ const struct sockaddr *sa)
+{
+ struct qb_list_head *list;
+ struct totemudpu_member *member;
+ struct totemudpu_member *res_member;
+ const struct totemudpu_instance *instance = (const struct totemudpu_instance *)udpu_context;
+
+ res_member = NULL;
+
+ qb_list_for_each(list, &(instance->member_list)) {
+ member = qb_list_entry (list,
+ struct totemudpu_member,
+ list);
+
+ if (totemip_sa_equal(&member->member, sa)) {
+ res_member = member;
+ break ;
+ }
+ }
+
+ return (res_member);
+}
+
+
+static int net_deliver_fn (
+ int fd,
+ int revents,
+ void *data)
+{
+ struct totemudpu_instance *instance = (struct totemudpu_instance *)data;
+ struct msghdr msg_recv;
+ struct iovec *iovec;
+ struct sockaddr_storage system_from;
+ int bytes_received;
+ int truncated_packet;
+
+ iovec = &instance->totemudpu_iov_recv;
+
+ /*
+ * Receive datagram
+ */
+ msg_recv.msg_name = &system_from;
+ msg_recv.msg_namelen = sizeof (struct sockaddr_storage);
+ msg_recv.msg_iov = iovec;
+ msg_recv.msg_iovlen = 1;
+#ifdef HAVE_MSGHDR_CONTROL
+ msg_recv.msg_control = 0;
+#endif
+#ifdef HAVE_MSGHDR_CONTROLLEN
+ msg_recv.msg_controllen = 0;
+#endif
+#ifdef HAVE_MSGHDR_FLAGS
+ msg_recv.msg_flags = 0;
+#endif
+#ifdef HAVE_MSGHDR_ACCRIGHTS
+ msg_recv.msg_accrights = NULL;
+#endif
+#ifdef HAVE_MSGHDR_ACCRIGHTSLEN
+ msg_recv.msg_accrightslen = 0;
+#endif
+
+ bytes_received = recvmsg (fd, &msg_recv, MSG_NOSIGNAL | MSG_DONTWAIT);
+ if (bytes_received == -1) {
+ return (0);
+ } else {
+ instance->stats_recv += bytes_received;
+ }
+
+ truncated_packet = 0;
+
+#ifdef HAVE_MSGHDR_FLAGS
+ if (msg_recv.msg_flags & MSG_TRUNC) {
+ truncated_packet = 1;
+ }
+#else
+ /*
+ * We don't have MSGHDR_FLAGS, but we can (hopefully) safely make assumption that
+ * if bytes_received == UDP_RECEIVE_FRAME_SIZE_MAX then packet is truncated
+ */
+ if (bytes_received == UDP_RECEIVE_FRAME_SIZE_MAX) {
+ truncated_packet = 1;
+ }
+#endif
+
+ if (truncated_packet) {
+ log_printf (instance->totemudpu_log_level_error,
+ "Received too big message. This may be because something bad is happening"
+ "on the network (attack?), or you tried join more nodes than corosync is"
+ "compiled with (%u) or bug in the code (bad estimation of "
+ "the UDP_RECEIVE_FRAME_SIZE_MAX). Dropping packet.", PROCESSOR_COUNT_MAX);
+ return (0);
+ }
+
+ if (instance->totem_config->block_unlisted_ips &&
+ instance->netif_bind_state == BIND_STATE_REGULAR &&
+ find_member_by_sockaddr(instance, (const struct sockaddr *)&system_from) == NULL) {
+ log_printf(instance->totemudpu_log_level_debug, "Packet rejected from %s",
+ totemip_sa_print((const struct sockaddr *)&system_from));
+
+ return (0);
+ }
+
+ iovec->iov_len = bytes_received;
+
+ /*
+ * Handle incoming message
+ */
+ instance->totemudpu_deliver_fn (
+ instance->context,
+ iovec->iov_base,
+ iovec->iov_len,
+ &system_from);
+
+ iovec->iov_len = UDP_RECEIVE_FRAME_SIZE_MAX;
+ return (0);
+}
+
+static int netif_determine (
+ struct totemudpu_instance *instance,
+ struct totem_ip_address *bindnet,
+ struct totem_ip_address *bound_to,
+ int *interface_up,
+ int *interface_num)
+{
+ int res;
+
+ res = totemip_iface_check (bindnet, bound_to,
+ interface_up, interface_num,
+ instance->totem_config->clear_node_high_bit);
+
+
+ return (res);
+}
+
+
+/*
+ * If the interface is up, the sockets for totem are built. If the interface is down
+ * this function is requeued in the timer list to retry building the sockets later.
+ */
+static void timer_function_netif_check_timeout (
+ void *data)
+{
+ struct totemudpu_instance *instance = (struct totemudpu_instance *)data;
+ int interface_up;
+ int interface_num;
+
+ /*
+ * Build sockets for every interface
+ */
+ netif_determine (instance,
+ &instance->totem_interface->bindnet,
+ &instance->totem_interface->boundto,
+ &interface_up, &interface_num);
+ /*
+ * If the network interface isn't back up and we are already
+ * in loopback mode, add timer to check again and return
+ */
+ if ((instance->netif_bind_state == BIND_STATE_LOOPBACK &&
+ interface_up == 0) ||
+
+ (instance->my_memb_entries == 1 &&
+ instance->netif_bind_state == BIND_STATE_REGULAR &&
+ interface_up == 1)) {
+
+ qb_loop_timer_add (instance->totemudpu_poll_handle,
+ QB_LOOP_MED,
+ instance->totem_config->downcheck_timeout*QB_TIME_NS_IN_MSEC,
+ (void *)instance,
+ timer_function_netif_check_timeout,
+ &instance->timer_netif_check_timeout);
+
+ /*
+ * Add a timer to check for a downed regular interface
+ */
+ return;
+ }
+
+ if (instance->token_socket > 0) {
+ qb_loop_poll_del (instance->totemudpu_poll_handle,
+ instance->token_socket);
+ close (instance->token_socket);
+ instance->token_socket = -1;
+ }
+
+ if (interface_up == 0) {
+ if (instance->netif_bind_state == BIND_STATE_UNBOUND) {
+ log_printf (instance->totemudpu_log_level_error,
+ "One of your ip addresses are now bound to localhost. "
+ "Corosync would not work correctly.");
+ exit(COROSYNC_DONE_FATAL_ERR);
+ }
+
+ /*
+ * Interface is not up
+ */
+ instance->netif_bind_state = BIND_STATE_LOOPBACK;
+
+ /*
+ * Add a timer to retry building interfaces and request memb_gather_enter
+ */
+ qb_loop_timer_add (instance->totemudpu_poll_handle,
+ QB_LOOP_MED,
+ instance->totem_config->downcheck_timeout*QB_TIME_NS_IN_MSEC,
+ (void *)instance,
+ timer_function_netif_check_timeout,
+ &instance->timer_netif_check_timeout);
+ } else {
+ /*
+ * Interface is up
+ */
+ instance->netif_bind_state = BIND_STATE_REGULAR;
+ }
+ /*
+ * Create and bind the multicast and unicast sockets
+ */
+ totemudpu_build_sockets (instance,
+ &instance->totem_interface->bindnet,
+ &instance->totem_interface->boundto);
+
+ if (instance->netif_bind_state == BIND_STATE_REGULAR) {
+ qb_loop_poll_add (instance->totemudpu_poll_handle,
+ QB_LOOP_MED,
+ instance->token_socket,
+ POLLIN, instance, net_deliver_fn);
+ }
+
+ totemip_copy (&instance->my_id, &instance->totem_interface->boundto);
+
+ /*
+ * This reports changes in the interface to the user and totemsrp
+ */
+ if (instance->netif_bind_state == BIND_STATE_REGULAR) {
+ if (instance->netif_state_report & NETIF_STATE_REPORT_UP) {
+ log_printf (instance->totemudpu_log_level_notice,
+ "The network interface [%s] is now up.",
+ totemip_print (&instance->totem_interface->boundto));
+ instance->netif_state_report = NETIF_STATE_REPORT_DOWN;
+ instance->totemudpu_iface_change_fn (instance->context, &instance->my_id, 0);
+ }
+ /*
+ * Add a timer to check for interface going down in single membership
+ */
+ if (instance->my_memb_entries == 1) {
+ qb_loop_timer_add (instance->totemudpu_poll_handle,
+ QB_LOOP_MED,
+ instance->totem_config->downcheck_timeout*QB_TIME_NS_IN_MSEC,
+ (void *)instance,
+ timer_function_netif_check_timeout,
+ &instance->timer_netif_check_timeout);
+ }
+
+ } else {
+ if (instance->netif_state_report & NETIF_STATE_REPORT_DOWN) {
+ log_printf (instance->totemudpu_log_level_notice,
+ "The network interface is down.");
+ instance->totemudpu_iface_change_fn (instance->context, &instance->my_id, 0);
+ }
+ instance->netif_state_report = NETIF_STATE_REPORT_UP;
+
+ }
+}
+
+/* Set the socket priority to INTERACTIVE to ensure
+ that our messages don't get queued behind anything else */
+static void totemudpu_traffic_control_set(struct totemudpu_instance *instance, int sock)
+{
+#ifdef SO_PRIORITY
+ int prio = 6; /* TC_PRIO_INTERACTIVE */
+
+ if (setsockopt(sock, SOL_SOCKET, SO_PRIORITY, &prio, sizeof(int))) {
+ LOGSYS_PERROR (errno, instance->totemudpu_log_level_warning,
+ "Could not set traffic priority");
+ }
+#endif
+}
+
+static int totemudpu_build_sockets_ip (
+ struct totemudpu_instance *instance,
+ struct totem_ip_address *bindnet_address,
+ struct totem_ip_address *bound_to,
+ int interface_num)
+{
+ struct sockaddr_storage sockaddr;
+ int addrlen;
+ int res;
+ unsigned int recvbuf_size;
+ unsigned int optlen = sizeof (recvbuf_size);
+ unsigned int retries = 0;
+
+ /*
+ * Setup unicast socket
+ */
+ instance->token_socket = socket (bindnet_address->family, SOCK_DGRAM, 0);
+ if (instance->token_socket == -1) {
+ LOGSYS_PERROR (errno, instance->totemudpu_log_level_warning,
+ "socket() failed");
+ return (-1);
+ }
+
+ totemip_nosigpipe (instance->token_socket);
+ res = fcntl (instance->token_socket, F_SETFL, O_NONBLOCK);
+ if (res == -1) {
+ LOGSYS_PERROR (errno, instance->totemudpu_log_level_warning,
+ "Could not set non-blocking operation on token socket");
+ return (-1);
+ }
+
+ /*
+ * Bind to unicast socket used for token send/receives
+ * This has the side effect of binding to the correct interface
+ */
+ totemip_totemip_to_sockaddr_convert(bound_to, instance->totem_interface->ip_port, &sockaddr, &addrlen);
+ while (1) {
+ res = bind (instance->token_socket, (struct sockaddr *)&sockaddr, addrlen);
+ if (res == 0) {
+ break;
+ }
+ LOGSYS_PERROR (errno, instance->totemudpu_log_level_warning,
+ "bind token socket failed");
+ if (++retries > BIND_MAX_RETRIES) {
+ break;
+ }
+
+ /*
+ * Wait for a while
+ */
+ (void)poll(NULL, 0, BIND_RETRIES_INTERVAL * retries);
+ }
+
+ if (res == -1) {
+ return (-1);
+ }
+
+ /*
+ * the token_socket can receive many messages. Allow a large number
+ * of receive messages on this socket
+ */
+ recvbuf_size = MCAST_SOCKET_BUFFER_SIZE;
+ res = setsockopt (instance->token_socket, SOL_SOCKET, SO_RCVBUF,
+ &recvbuf_size, optlen);
+ if (res == -1) {
+ LOGSYS_PERROR (errno, instance->totemudpu_log_level_notice,
+ "Could not set recvbuf size");
+ }
+
+ return 0;
+}
+
+int totemudpu_nodestatus_get (void *udpu_context, unsigned int nodeid,
+ struct totem_node_status *node_status)
+{
+ struct totemudpu_instance *instance = (struct totemudpu_instance *)udpu_context;
+ struct qb_list_head *list;
+ struct totemudpu_member *member;
+
+ qb_list_for_each(list, &(instance->member_list)) {
+ member = qb_list_entry (list,
+ struct totemudpu_member,
+ list);
+
+ if (member->member.nodeid == nodeid) {
+ node_status->nodeid = nodeid;
+ /* reachable is filled in by totemsrp */
+ if (instance->netif_bind_state == BIND_STATE_REGULAR) {
+ node_status->link_status[0].enabled = 1;
+ } else {
+ node_status->link_status[0].enabled = 0;
+ }
+ node_status->link_status[0].connected = node_status->reachable;
+ node_status->link_status[0].mtu = instance->totem_config->net_mtu;
+ strncpy(node_status->link_status[0].src_ipaddr, totemip_print(&member->member), KNET_MAX_HOST_LEN-1);
+ }
+ }
+ return (0);
+}
+
+int totemudpu_ifaces_get (
+ void *net_context,
+ char ***status,
+ unsigned int *iface_count)
+{
+ static char *statuses[INTERFACE_MAX] = {(char*)"OK"};
+
+ if (status) {
+ *status = statuses;
+ }
+ *iface_count = 1;
+
+ return (0);
+}
+
+
+static int totemudpu_build_local_sockets(
+ struct totemudpu_instance *instance)
+{
+ int i;
+ unsigned int sendbuf_size;
+ unsigned int recvbuf_size;
+ unsigned int optlen = sizeof (sendbuf_size);
+ int res;
+
+ /*
+ * Create local multicast loop socket
+ */
+ if (socketpair(AF_UNIX, SOCK_DGRAM, 0, instance->local_loop_sock) == -1) {
+ LOGSYS_PERROR (errno, instance->totemudpu_log_level_warning,
+ "socket() failed");
+ return (-1);
+ }
+
+ for (i = 0; i < 2; i++) {
+ totemip_nosigpipe (instance->local_loop_sock[i]);
+ res = fcntl (instance->local_loop_sock[i], F_SETFL, O_NONBLOCK);
+ if (res == -1) {
+ LOGSYS_PERROR (errno, instance->totemudpu_log_level_warning,
+ "Could not set non-blocking operation on multicast socket");
+ return (-1);
+ }
+ }
+
+ recvbuf_size = MCAST_SOCKET_BUFFER_SIZE;
+ sendbuf_size = MCAST_SOCKET_BUFFER_SIZE;
+
+ res = setsockopt (instance->local_loop_sock[0], SOL_SOCKET, SO_RCVBUF, &recvbuf_size, optlen);
+ if (res == -1) {
+ LOGSYS_PERROR (errno, instance->totemudpu_log_level_debug,
+ "Unable to set SO_RCVBUF size on UDP local mcast loop socket");
+ return (-1);
+ }
+ res = setsockopt (instance->local_loop_sock[1], SOL_SOCKET, SO_SNDBUF, &sendbuf_size, optlen);
+ if (res == -1) {
+ LOGSYS_PERROR (errno, instance->totemudpu_log_level_debug,
+ "Unable to set SO_SNDBUF size on UDP local mcast loop socket");
+ return (-1);
+ }
+
+ res = getsockopt (instance->local_loop_sock[0], SOL_SOCKET, SO_RCVBUF, &recvbuf_size, &optlen);
+ if (res == 0) {
+ log_printf (instance->totemudpu_log_level_debug,
+ "Local receive multicast loop socket recv buffer size (%d bytes).", recvbuf_size);
+ }
+
+ res = getsockopt (instance->local_loop_sock[1], SOL_SOCKET, SO_SNDBUF, &sendbuf_size, &optlen);
+ if (res == 0) {
+ log_printf (instance->totemudpu_log_level_debug,
+ "Local transmit multicast loop socket send buffer size (%d bytes).", sendbuf_size);
+ }
+
+ return (0);
+}
+
+static int totemudpu_build_sockets (
+ struct totemudpu_instance *instance,
+ struct totem_ip_address *bindnet_address,
+ struct totem_ip_address *bound_to)
+{
+ int interface_num;
+ int interface_up;
+ int res;
+
+ /*
+ * Determine the ip address bound to and the interface name
+ */
+ res = netif_determine (instance,
+ bindnet_address,
+ bound_to,
+ &interface_up,
+ &interface_num);
+
+ if (res == -1) {
+ return (-1);
+ }
+
+ totemip_copy(&instance->my_id, bound_to);
+
+ res = totemudpu_build_sockets_ip (instance,
+ bindnet_address, bound_to, interface_num);
+
+ if (res == -1) {
+ /* if we get here, corosync won't work anyway, so better leaving than faking to work */
+ LOGSYS_PERROR (errno, instance->totemudpu_log_level_error,
+ "Unable to create sockets, exiting");
+ exit(EXIT_FAILURE);
+ }
+
+ /* We only send out of the token socket */
+ totemudpu_traffic_control_set(instance, instance->token_socket);
+
+ /*
+ * Rebind all members to new ips
+ */
+ totemudpu_member_list_rebind_ip(instance);
+
+ return res;
+}
+
+/*
+ * Totem Network interface
+ * depends on poll abstraction, POSIX, IPV4
+ */
+
+/*
+ * Create an instance
+ */
+int totemudpu_initialize (
+ qb_loop_t *poll_handle,
+ void **udpu_context,
+ struct totem_config *totem_config,
+ totemsrp_stats_t *stats,
+ void *context,
+
+ int (*deliver_fn) (
+ void *context,
+ const void *msg,
+ unsigned int msg_len,
+ const struct sockaddr_storage *system_from),
+
+ int (*iface_change_fn) (
+ void *context,
+ const struct totem_ip_address *iface_address,
+ unsigned int ring_no),
+
+ void (*mtu_changed) (
+ void *context,
+ int net_mtu),
+
+ void (*target_set_completed) (
+ void *context))
+{
+ struct totemudpu_instance *instance;
+
+ instance = malloc (sizeof (struct totemudpu_instance));
+ if (instance == NULL) {
+ return (-1);
+ }
+
+ totemudpu_instance_initialize (instance);
+
+ instance->totem_config = totem_config;
+ instance->stats = stats;
+
+ /*
+ * Configure logging
+ */
+ instance->totemudpu_log_level_security = 1; //totem_config->totem_logging_configuration.log_level_security;
+ instance->totemudpu_log_level_error = totem_config->totem_logging_configuration.log_level_error;
+ instance->totemudpu_log_level_warning = totem_config->totem_logging_configuration.log_level_warning;
+ instance->totemudpu_log_level_notice = totem_config->totem_logging_configuration.log_level_notice;
+ instance->totemudpu_log_level_debug = totem_config->totem_logging_configuration.log_level_debug;
+ instance->totemudpu_subsys_id = totem_config->totem_logging_configuration.log_subsys_id;
+ instance->totemudpu_log_printf = totem_config->totem_logging_configuration.log_printf;
+
+ /*
+ * Initialize local variables for totemudpu
+ */
+ instance->totem_interface = &totem_config->interfaces[0];
+ memset (instance->iov_buffer, 0, UDP_RECEIVE_FRAME_SIZE_MAX);
+
+ instance->totemudpu_poll_handle = poll_handle;
+
+ instance->totem_interface->bindnet.nodeid = instance->totem_config->node_id;
+
+ instance->context = context;
+ instance->totemudpu_deliver_fn = deliver_fn;
+
+ instance->totemudpu_iface_change_fn = iface_change_fn;
+
+ instance->totemudpu_target_set_completed = target_set_completed;
+
+ /*
+ * Create static local mcast sockets
+ */
+ if (totemudpu_build_local_sockets(instance) == -1) {
+ free(instance);
+ return (-1);
+ }
+
+ qb_loop_poll_add (
+ instance->totemudpu_poll_handle,
+ QB_LOOP_MED,
+ instance->local_loop_sock[0],
+ POLLIN, instance, net_deliver_fn);
+
+ /*
+ * RRP layer isn't ready to receive message because it hasn't
+ * initialized yet. Add short timer to check the interfaces.
+ */
+ qb_loop_timer_add (instance->totemudpu_poll_handle,
+ QB_LOOP_MED,
+ 100*QB_TIME_NS_IN_MSEC,
+ (void *)instance,
+ timer_function_netif_check_timeout,
+ &instance->timer_netif_check_timeout);
+
+ totemudpu_start_merge_detect_timeout((void*)instance);
+
+ *udpu_context = instance;
+ return (0);
+}
+
+void *totemudpu_buffer_alloc (void)
+{
+ return malloc (FRAME_SIZE_MAX);
+}
+
+void totemudpu_buffer_release (void *ptr)
+{
+ return free (ptr);
+}
+
+int totemudpu_processor_count_set (
+ void *udpu_context,
+ int processor_count)
+{
+ struct totemudpu_instance *instance = (struct totemudpu_instance *)udpu_context;
+ int res = 0;
+
+ instance->my_memb_entries = processor_count;
+ qb_loop_timer_del (instance->totemudpu_poll_handle,
+ instance->timer_netif_check_timeout);
+ if (processor_count == 1) {
+ qb_loop_timer_add (instance->totemudpu_poll_handle,
+ QB_LOOP_MED,
+ instance->totem_config->downcheck_timeout*QB_TIME_NS_IN_MSEC,
+ (void *)instance,
+ timer_function_netif_check_timeout,
+ &instance->timer_netif_check_timeout);
+ }
+
+ return (res);
+}
+
+int totemudpu_recv_flush (void *udpu_context)
+{
+ int res = 0;
+
+ return (res);
+}
+
+int totemudpu_send_flush (void *udpu_context)
+{
+ int res = 0;
+
+ return (res);
+}
+
+int totemudpu_token_send (
+ void *udpu_context,
+ const void *msg,
+ unsigned int msg_len)
+{
+ struct totemudpu_instance *instance = (struct totemudpu_instance *)udpu_context;
+ int res = 0;
+
+ ucast_sendmsg (instance, &instance->token_target, msg, msg_len);
+
+ return (res);
+}
+int totemudpu_mcast_flush_send (
+ void *udpu_context,
+ const void *msg,
+ unsigned int msg_len)
+{
+ struct totemudpu_instance *instance = (struct totemudpu_instance *)udpu_context;
+ int res = 0;
+
+ mcast_sendmsg (instance, msg, msg_len, 0);
+
+ return (res);
+}
+
+int totemudpu_mcast_noflush_send (
+ void *udpu_context,
+ const void *msg,
+ unsigned int msg_len)
+{
+ struct totemudpu_instance *instance = (struct totemudpu_instance *)udpu_context;
+ int res = 0;
+
+ mcast_sendmsg (instance, msg, msg_len, 1);
+
+ return (res);
+}
+
+extern int totemudpu_iface_check (void *udpu_context)
+{
+ struct totemudpu_instance *instance = (struct totemudpu_instance *)udpu_context;
+ int res = 0;
+
+ timer_function_netif_check_timeout (instance);
+
+ return (res);
+}
+
+extern void totemudpu_net_mtu_adjust (void *udpu_context, struct totem_config *totem_config)
+{
+ totem_config->net_mtu -= totemip_udpip_header_size(totem_config->interfaces[0].bindnet.family);
+}
+
+
+int totemudpu_token_target_set (
+ void *udpu_context,
+ unsigned int nodeid)
+{
+
+ struct totemudpu_instance *instance = (struct totemudpu_instance *)udpu_context;
+ struct qb_list_head *list;
+ struct totemudpu_member *member;
+ int res = 0;
+
+ qb_list_for_each(list, &(instance->member_list)) {
+ member = qb_list_entry (list,
+ struct totemudpu_member,
+ list);
+
+ if (member->member.nodeid == nodeid) {
+ memcpy (&instance->token_target, &member->member,
+ sizeof (struct totem_ip_address));
+
+ instance->totemudpu_target_set_completed (instance->context);
+ break;
+ }
+ }
+ return (res);
+}
+
+extern int totemudpu_recv_mcast_empty (
+ void *udpu_context)
+{
+ struct totemudpu_instance *instance = (struct totemudpu_instance *)udpu_context;
+ unsigned int res;
+ struct sockaddr_storage system_from;
+ struct msghdr msg_recv;
+ struct pollfd ufd;
+ int nfds, i;
+ int msg_processed = 0;
+ int sock;
+
+ /*
+ * Receive datagram
+ */
+ msg_recv.msg_name = &system_from;
+ msg_recv.msg_namelen = sizeof (struct sockaddr_storage);
+ msg_recv.msg_iov = &instance->totemudpu_iov_recv;
+ msg_recv.msg_iovlen = 1;
+#ifdef HAVE_MSGHDR_CONTROL
+ msg_recv.msg_control = 0;
+#endif
+#ifdef HAVE_MSGHDR_CONTROLLEN
+ msg_recv.msg_controllen = 0;
+#endif
+#ifdef HAVE_MSGHDR_FLAGS
+ msg_recv.msg_flags = 0;
+#endif
+#ifdef HAVE_MSGHDR_ACCRIGHTS
+ msg_recv.msg_accrights = NULL;
+#endif
+#ifdef HAVE_MSGHDR_ACCRIGHTSLEN
+ msg_recv.msg_accrightslen = 0;
+#endif
+
+ for (i = 0; i < 2; i++) {
+ sock = -1;
+ if (i == 0) {
+ if (instance->netif_bind_state == BIND_STATE_REGULAR) {
+ sock = instance->token_socket;
+ } else {
+ continue;
+ }
+ }
+ if (i == 1) {
+ sock = instance->local_loop_sock[0];
+ }
+ assert(sock != -1);
+
+ do {
+ ufd.fd = sock;
+ ufd.events = POLLIN;
+ nfds = poll (&ufd, 1, 0);
+ if (nfds == 1 && ufd.revents & POLLIN) {
+ res = recvmsg (sock, &msg_recv, MSG_NOSIGNAL | MSG_DONTWAIT);
+ if (res != -1) {
+ msg_processed = 1;
+ } else {
+ msg_processed = -1;
+ }
+ }
+ } while (nfds == 1);
+ }
+
+ return (msg_processed);
+}
+
+static int totemudpu_create_sending_socket(
+ void *udpu_context,
+ const struct totem_ip_address *member)
+{
+ struct totemudpu_instance *instance = (struct totemudpu_instance *)udpu_context;
+ int fd;
+ int res;
+ unsigned int sendbuf_size;
+ unsigned int optlen = sizeof (sendbuf_size);
+ struct sockaddr_storage sockaddr;
+ int addrlen;
+
+ fd = socket (member->family, SOCK_DGRAM, 0);
+ if (fd == -1) {
+ LOGSYS_PERROR (errno, instance->totemudpu_log_level_warning,
+ "Could not create socket for new member");
+ return (-1);
+ }
+ totemip_nosigpipe (fd);
+ res = fcntl (fd, F_SETFL, O_NONBLOCK);
+ if (res == -1) {
+ LOGSYS_PERROR (errno, instance->totemudpu_log_level_warning,
+ "Could not set non-blocking operation on token socket");
+ goto error_close_fd;
+ }
+
+ /*
+ * These sockets are used to send multicast messages, so their buffers
+ * should be large
+ */
+ sendbuf_size = MCAST_SOCKET_BUFFER_SIZE;
+ res = setsockopt (fd, SOL_SOCKET, SO_SNDBUF,
+ &sendbuf_size, optlen);
+ if (res == -1) {
+ LOGSYS_PERROR (errno, instance->totemudpu_log_level_notice,
+ "Could not set sendbuf size");
+ /*
+ * Fail in setting sendbuf size is not fatal -> don't exit
+ */
+ }
+
+ /*
+ * Bind to sending interface
+ */
+ totemip_totemip_to_sockaddr_convert(&instance->my_id, 0, &sockaddr, &addrlen);
+ res = bind (fd, (struct sockaddr *)&sockaddr, addrlen);
+ if (res == -1) {
+ LOGSYS_PERROR (errno, instance->totemudpu_log_level_warning,
+ "bind token socket failed");
+ goto error_close_fd;
+ }
+
+ return (fd);
+
+error_close_fd:
+ close(fd);
+ return (-1);
+}
+
+int totemudpu_iface_set (void *net_context,
+ const struct totem_ip_address *local_addr,
+ unsigned short ip_port,
+ unsigned int iface_no)
+{
+ /* Not supported */
+ return (-1);
+}
+
+int totemudpu_member_add (
+ void *udpu_context,
+ const struct totem_ip_address *local,
+ const struct totem_ip_address *member,
+ int ring_no)
+{
+ struct totemudpu_instance *instance = (struct totemudpu_instance *)udpu_context;
+
+ struct totemudpu_member *new_member;
+
+ new_member = malloc (sizeof (struct totemudpu_member));
+ if (new_member == NULL) {
+ return (-1);
+ }
+
+ memset(new_member, 0, sizeof(*new_member));
+
+ log_printf (LOGSYS_LEVEL_NOTICE, "adding new UDPU member {%s}",
+ totemip_print(member));
+ qb_list_init (&new_member->list);
+ qb_list_add_tail (&new_member->list, &instance->member_list);
+ memcpy (&new_member->member, member, sizeof (struct totem_ip_address));
+ new_member->fd = totemudpu_create_sending_socket(udpu_context, member);
+ new_member->active = 1;
+
+ return (0);
+}
+
+int totemudpu_member_remove (
+ void *udpu_context,
+ const struct totem_ip_address *token_target,
+ int ring_no)
+{
+ int found = 0;
+ struct qb_list_head *list;
+ struct totemudpu_member *member;
+
+ struct totemudpu_instance *instance = (struct totemudpu_instance *)udpu_context;
+
+ /*
+ * Find the member to remove and close its socket
+ */
+ qb_list_for_each(list, &(instance->member_list)) {
+ member = qb_list_entry (list,
+ struct totemudpu_member,
+ list);
+
+ if (totemip_compare (token_target, &member->member)==0) {
+ log_printf(LOGSYS_LEVEL_NOTICE,
+ "removing UDPU member {%s}",
+ totemip_print(&member->member));
+
+ if (member->fd > 0) {
+ log_printf(LOGSYS_LEVEL_DEBUG,
+ "Closing socket to: {%s}",
+ totemip_print(&member->member));
+ qb_loop_poll_del (instance->totemudpu_poll_handle,
+ member->fd);
+ close (member->fd);
+ }
+ found = 1;
+ break;
+ }
+ }
+
+ /*
+ * Delete the member from the list
+ */
+ if (found) {
+ qb_list_del (list);
+ }
+
+ instance = NULL;
+ return (0);
+}
+
+int totemudpu_member_list_rebind_ip (
+ void *udpu_context)
+{
+ struct qb_list_head *list;
+ struct totemudpu_member *member;
+
+ struct totemudpu_instance *instance = (struct totemudpu_instance *)udpu_context;
+
+ qb_list_for_each(list, &(instance->member_list)) {
+ member = qb_list_entry (list,
+ struct totemudpu_member,
+ list);
+
+ if (member->fd > 0) {
+ close (member->fd);
+ }
+
+ member->fd = totemudpu_create_sending_socket(udpu_context, &member->member);
+ }
+
+ return (0);
+}
+
+
+static void timer_function_merge_detect_timeout (
+ void *data)
+{
+ struct totemudpu_instance *instance = (struct totemudpu_instance *)data;
+
+ if (instance->merge_detect_messages_sent_before_timeout == 0) {
+ instance->send_merge_detect_message = 1;
+ }
+
+ instance->merge_detect_messages_sent_before_timeout = 0;
+
+ totemudpu_start_merge_detect_timeout(instance);
+}
+
+static void totemudpu_start_merge_detect_timeout(
+ void *udpu_context)
+{
+ struct totemudpu_instance *instance = (struct totemudpu_instance *)udpu_context;
+
+ qb_loop_timer_add(instance->totemudpu_poll_handle,
+ QB_LOOP_MED,
+ instance->totem_config->merge_timeout * 2 * QB_TIME_NS_IN_MSEC,
+ (void *)instance,
+ timer_function_merge_detect_timeout,
+ &instance->timer_merge_detect_timeout);
+
+}
+
+static void totemudpu_stop_merge_detect_timeout(
+ void *udpu_context)
+{
+ struct totemudpu_instance *instance = (struct totemudpu_instance *)udpu_context;
+
+ qb_loop_timer_del(instance->totemudpu_poll_handle,
+ instance->timer_merge_detect_timeout);
+}
+
+int totemudpu_reconfigure (
+ void *udpu_context,
+ struct totem_config *totem_config)
+{
+ /* Not supported */
+ return (-1);
+}
diff --git a/exec/totemudpu.h b/exec/totemudpu.h
new file mode 100644
index 0000000..fe530ca
--- /dev/null
+++ b/exec/totemudpu.h
@@ -0,0 +1,144 @@
+/*
+ * Copyright (c) 2005 MontaVista Software, Inc.
+ * Copyright (c) 2006-2011 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Author: Steven Dake (sdake@redhat.com)
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of the MontaVista Software, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef TOTEMUDPU_H_DEFINED
+#define TOTEMUDPU_H_DEFINED
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <qb/qbloop.h>
+
+#include <corosync/totem/totem.h>
+
+/**
+ * Create an instance
+ */
+extern int totemudpu_initialize (
+ qb_loop_t *poll_handle,
+ void **udpu_context,
+ struct totem_config *totem_config,
+ totemsrp_stats_t *stats,
+ void *context,
+
+ int (*deliver_fn) (
+ void *context,
+ const void *msg,
+ unsigned int msg_len,
+ const struct sockaddr_storage *system_from),
+
+ int (*iface_change_fn) (
+ void *context,
+ const struct totem_ip_address *iface_address,
+ unsigned int ring_no),
+
+ void (*mtu_changed) (
+ void *context,
+ int net_mtu),
+
+ void (*target_set_completed) (
+ void *context));
+
+extern void *totemudpu_buffer_alloc (void);
+
+extern void totemudpu_buffer_release (void *ptr);
+
+extern int totemudpu_processor_count_set (
+ void *udpu_context,
+ int processor_count);
+
+extern int totemudpu_token_send (
+ void *udpu_context,
+ const void *msg,
+ unsigned int msg_len);
+
+extern int totemudpu_mcast_flush_send (
+ void *udpu_context,
+ const void *msg,
+ unsigned int msg_len);
+
+extern int totemudpu_mcast_noflush_send (
+ void *udpu_context,
+ const void *msg,
+ unsigned int msg_len);
+
+extern int totemudpu_nodestatus_get (void *net_context, unsigned int nodeid,
+ struct totem_node_status *node_status);
+
+extern int totemudpu_ifaces_get (void *net_context,
+ char ***status,
+ unsigned int *iface_count);
+
+extern int totemudpu_recv_flush (void *udpu_context);
+
+extern int totemudpu_send_flush (void *udpu_context);
+
+extern int totemudpu_iface_set (void *net_context,
+ const struct totem_ip_address *local_addr,
+ unsigned short ip_port,
+ unsigned int iface_no);
+
+extern int totemudpu_iface_check (void *udpu_context);
+
+extern int totemudpu_finalize (void *udpu_context);
+
+extern void totemudpu_net_mtu_adjust (void *udpu_context, struct totem_config *totem_config);
+
+extern int totemudpu_token_target_set (
+ void *udpu_context,
+ unsigned int nodeid);
+
+extern int totemudpu_crypto_set (
+ void *udpu_context,
+ const char *cipher_type,
+ const char *hash_type);
+
+extern int totemudpu_recv_mcast_empty (
+ void *udpu_context);
+
+extern int totemudpu_member_add (
+ void *udpu_context,
+ const struct totem_ip_address *local,
+ const struct totem_ip_address *member,
+ int ring_no);
+
+extern int totemudpu_member_remove (
+ void *udpu_context,
+ const struct totem_ip_address *member,
+ int ring_no);
+
+extern int totemudpu_reconfigure (
+ void *udpu_context,
+ struct totem_config *totem_config);
+
+#endif /* TOTEMUDPU_H_DEFINED */
diff --git a/exec/util.c b/exec/util.c
new file mode 100644
index 0000000..8988ab2
--- /dev/null
+++ b/exec/util.c
@@ -0,0 +1,343 @@
+/*
+ * Copyright (c) 2002-2004 MontaVista Software, Inc.
+ * Copyright (c) 2004 Open Source Development Lab
+ * Copyright (c) 2006-2012 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Author: Steven Dake (sdake@redhat.com), Mark Haverkamp (markh@osdl.org)
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of the MontaVista Software, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <sys/time.h>
+#include <assert.h>
+
+#include <libknet.h>
+
+#include <corosync/corotypes.h>
+#include <corosync/corodefs.h>
+#include <corosync/icmap.h>
+#include <corosync/logsys.h>
+#include "util.h"
+
+LOGSYS_DECLARE_SUBSYS ("MAIN");
+
+struct service_names {
+ const char *c_name;
+ int32_t c_val;
+};
+
+static struct service_names servicenames[] =
+{
+ { "CFG", CFG_SERVICE },
+ { "CPG", CPG_SERVICE },
+ { "QUORUM", QUORUM_SERVICE },
+ { "PLOAD", PLOAD_SERVICE },
+ { "VOTEQUORUM", VOTEQUORUM_SERVICE },
+ { "MON", MON_SERVICE },
+ { "WD", WD_SERVICE },
+ { "CMAP", CMAP_SERVICE },
+ { NULL, -1 }
+};
+
+const char * short_service_name_get(uint32_t service_id,
+ char *buf, size_t buf_size)
+{
+ uint32_t i;
+
+ for (i = 0; servicenames[i].c_name != NULL; i++) {
+ if (service_id == servicenames[i].c_val) {
+ return (servicenames[i].c_name);
+ }
+ }
+ snprintf(buf, buf_size, "%d", service_id);
+ return buf;
+}
+
+/*
+ * Compare two names. returns non-zero on match.
+ */
+int name_match(cs_name_t *name1, cs_name_t *name2)
+{
+ if (name1->length == name2->length) {
+ return ((strncmp ((char *)name1->value, (char *)name2->value,
+ name1->length)) == 0);
+ }
+ return 0;
+}
+
+/*
+ * Get the time of day and convert to nanoseconds
+ */
+cs_time_t clust_time_now(void)
+{
+ struct timeval tv;
+ cs_time_t time_now;
+
+ if (gettimeofday(&tv, 0)) {
+ return 0ULL;
+ }
+
+ time_now = (cs_time_t)(tv.tv_sec) * 1000000000ULL;
+ time_now += (cs_time_t)(tv.tv_usec) * 1000ULL;
+
+ return time_now;
+}
+
+void _corosync_out_of_memory_error (void) __attribute__((noreturn));
+void _corosync_out_of_memory_error (void)
+{
+ assert (0==1);
+ exit (EXIT_FAILURE);
+}
+
+void _corosync_exit_error (
+ enum e_corosync_done err, const char *file, unsigned int line) __attribute__((noreturn));
+
+void _corosync_exit_error (
+ enum e_corosync_done err, const char *file, unsigned int line)
+{
+ if (err == COROSYNC_DONE_EXIT) {
+ log_printf (LOGSYS_LEVEL_NOTICE,
+ "Corosync Cluster Engine exiting normally");
+ } else {
+ log_printf (LOGSYS_LEVEL_ERROR, "Corosync Cluster Engine exiting "
+ "with status %d at %s:%u.", err, file, line);
+ }
+ logsys_system_fini ();
+ exit (err);
+}
+
+char *getcs_name_t (cs_name_t *name)
+{
+ static char ret_name[CS_MAX_NAME_LENGTH];
+
+ /* if string is corrupt (non-terminated), ensure it's displayed safely */
+ if (name->length >= CS_MAX_NAME_LENGTH || name->value[name->length] != '\0') {
+ memset (ret_name, 0, sizeof (ret_name));
+ memcpy (ret_name, name->value, min(name->length, CS_MAX_NAME_LENGTH -1));
+ return (ret_name);
+ }
+ return ((char *)name->value);
+}
+
+void setcs_name_t (cs_name_t *name, char *str) {
+ strncpy ((char *)name->value, str, sizeof (name->value) - 1);
+ ((char *)name->value)[sizeof (name->value) - 1] = '\0';
+ if (strlen ((char *)name->value) > CS_MAX_NAME_LENGTH) {
+ name->length = CS_MAX_NAME_LENGTH;
+ } else {
+ name->length = strlen (str);
+ }
+}
+
+int cs_name_tisEqual (cs_name_t *str1, char *str2) {
+ if (str1->length == strlen (str2)) {
+ return ((strncmp ((char *)str1->value, (char *)str2,
+ str1->length)) == 0);
+ } else {
+ return 0;
+ }
+}
+
+const char *get_state_dir(void)
+{
+ static char path[PATH_MAX] = {'\0'};
+ char *cmap_state_dir;
+ int res;
+
+ if (path[0] == '\0') {
+ if (icmap_get_string("system.state_dir", &cmap_state_dir) == CS_OK) {
+ res = snprintf(path, PATH_MAX, "%s", cmap_state_dir);
+ free(cmap_state_dir);
+ } else {
+ res = snprintf(path, PATH_MAX, "%s/%s", LOCALSTATEDIR, "lib/corosync");
+ }
+
+ assert(res < PATH_MAX);
+ }
+
+ return (path);
+}
+
+static int safe_strcat(char *dst, size_t dst_len, const char *src)
+{
+
+ if (strlen(dst) + strlen(src) >= dst_len - 1) {
+ return (-1);
+ }
+
+ strcat(dst, src);
+
+ return (0);
+}
+
+/*
+ * val - knet crypto model to find
+ * crypto_list_str - string with concatenated list of available crypto models - can be NULL
+ * machine_parseable_str - 0 - split strings by space, 1 - use human form (split by "," and last item with "or")
+ * error_string_prefix - Prefix to add into error string
+ * error_string - Complete error string
+ */
+int util_is_valid_knet_crypto_model(const char *val,
+ const char **list_str, int machine_parseable_str,
+ const char *error_string_prefix, const char **error_string)
+{
+ size_t entries;
+ struct knet_crypto_info crypto_list[16];
+ size_t zi;
+ static char local_error_str[512];
+ static char local_list_str[256];
+ int model_found = 0;
+
+ if (list_str != NULL) {
+ *list_str = local_list_str;
+ }
+
+ memset(local_error_str, 0, sizeof(local_error_str));
+ memset(local_list_str, 0, sizeof(local_list_str));
+
+ safe_strcat(local_error_str, sizeof(local_error_str), error_string_prefix);
+
+ if (knet_get_crypto_list(NULL, &entries) != 0) {
+ *error_string = "internal error - cannot get knet crypto list";
+ return (-1);
+ }
+
+ if (entries > sizeof(crypto_list) / sizeof(crypto_list[0])) {
+ *error_string = "internal error - too many knet crypto list entries";
+ return (-1);
+ }
+
+ if (knet_get_crypto_list(crypto_list, &entries) != 0) {
+ *error_string = "internal error - cannot get knet crypto list";
+ return (-1);
+ }
+
+ for (zi = 0; zi < entries; zi++) {
+ if (zi == 0) {
+ } else if (zi == entries - 1) {
+ if (machine_parseable_str) {
+ (void)safe_strcat(local_list_str, sizeof(local_list_str), " ");
+ } else {
+ (void)safe_strcat(local_list_str, sizeof(local_list_str), " or ");
+ }
+ } else {
+ if (machine_parseable_str) {
+ (void)safe_strcat(local_list_str, sizeof(local_list_str), " ");
+ } else {
+ (void)safe_strcat(local_list_str, sizeof(local_list_str), ", ");
+ }
+ }
+
+ (void)safe_strcat(local_list_str, sizeof(local_list_str), crypto_list[zi].name);
+
+ if (val != NULL && strcmp(val, crypto_list[zi].name) == 0) {
+ model_found = 1;
+ }
+ }
+
+ if (!model_found) {
+ (void)safe_strcat(local_error_str, sizeof(local_error_str), local_list_str);
+ *error_string = local_error_str;
+ }
+
+ return (model_found);
+}
+
+int util_is_valid_knet_compress_model(const char *val,
+ const char **list_str, int machine_parseable_str,
+ const char *error_string_prefix, const char **error_string)
+{
+ size_t entries;
+ struct knet_compress_info compress_list[16];
+ size_t zi;
+ static char local_error_str[512];
+ static char local_list_str[256];
+ int model_found = 0;
+
+ if (list_str != NULL) {
+ *list_str = local_list_str;
+ }
+
+ memset(local_error_str, 0, sizeof(local_error_str));
+ memset(local_list_str, 0, sizeof(local_list_str));
+
+ safe_strcat(local_error_str, sizeof(local_error_str), error_string_prefix);
+
+ if (knet_get_compress_list(NULL, &entries) != 0) {
+ *error_string = "internal error - cannot get knet compress list";
+ return (-1);
+ }
+
+ if (entries > sizeof(compress_list) / sizeof(compress_list[0])) {
+ *error_string = "internal error - too many knet compress list entries";
+ return (-1);
+ }
+
+ if (knet_get_compress_list(compress_list, &entries) != 0) {
+ *error_string = "internal error - cannot get knet compress list";
+ return (-1);
+ }
+
+ for (zi = 0; zi < entries; zi++) {
+ if (zi == 0) {
+ } else if (zi == entries - 1) {
+ if (machine_parseable_str) {
+ (void)safe_strcat(local_list_str, sizeof(local_list_str), " ");
+ } else {
+ (void)safe_strcat(local_list_str, sizeof(local_list_str), " or ");
+ }
+ } else {
+ if (machine_parseable_str) {
+ (void)safe_strcat(local_list_str, sizeof(local_list_str), " ");
+ } else {
+ (void)safe_strcat(local_list_str, sizeof(local_list_str), ", ");
+ }
+ }
+
+ (void)safe_strcat(local_list_str, sizeof(local_list_str), compress_list[zi].name);
+
+ if (val != NULL && strcmp(val, compress_list[zi].name) == 0) {
+ model_found = 1;
+ }
+ }
+
+ if (!model_found) {
+ (void)safe_strcat(local_error_str, sizeof(local_error_str), local_list_str);
+ *error_string = local_error_str;
+ }
+
+ return (model_found);
+}
diff --git a/exec/util.h b/exec/util.h
new file mode 100644
index 0000000..e6e12af
--- /dev/null
+++ b/exec/util.h
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2002-2004 MontaVista Software, Inc.
+ * Copyright (c) 2004 Open Source Development Lab
+ * Copyright (c) 2006-2017 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Author: Steven Dake (sdake@redhat.com), Mark Haverkamp (markh@osdl.org)
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of the MontaVista Software, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef UTIL_H_DEFINED
+#define UTIL_H_DEFINED
+
+#include <sys/time.h>
+#include <corosync/corotypes.h>
+
+/**
+ * Get the time of day and convert to nanoseconds
+ */
+extern cs_time_t clust_time_now(void);
+
+enum e_corosync_done {
+ COROSYNC_DONE_EXIT = 0,
+ COROSYNC_DONE_FORK = 4,
+ COROSYNC_DONE_LOGCONFIGREAD = 7,
+ COROSYNC_DONE_MAINCONFIGREAD = 8,
+ COROSYNC_DONE_LOGSETUP = 9,
+ COROSYNC_DONE_ICMAP = 12,
+ COROSYNC_DONE_INIT_SERVICES = 13,
+ COROSYNC_DONE_FATAL_ERR = 15,
+ COROSYNC_DONE_DIR_NOT_PRESENT = 16,
+ COROSYNC_DONE_ACQUIRE_LOCK = 17,
+ COROSYNC_DONE_ALREADY_RUNNING = 18,
+ COROSYNC_DONE_STD_TO_NULL_REDIR = 19,
+ COROSYNC_DONE_SERVICE_ENGINE_INIT = 20,
+ COROSYNC_DONE_STORE_RINGID = 21,
+ COROSYNC_DONE_STATS = 22,
+ COROSYNC_DONE_PLOAD = 99
+};
+
+#define min(a,b) ((a) < (b) ? (a) : (b))
+
+/**
+ * Compare two names. returns non-zero on match.
+ */
+extern int name_match(cs_name_t *name1, cs_name_t *name2);
+#define corosync_exit_error(err) _corosync_exit_error ((err), __FILE__, __LINE__)
+extern void _corosync_exit_error (enum e_corosync_done err, const char *file,
+ unsigned int line) __attribute__((noreturn));
+void _corosync_out_of_memory_error (void) __attribute__((noreturn));
+extern char *getcs_name_t (cs_name_t *name);
+extern void setcs_name_t (cs_name_t *name, char *str);
+extern int cs_name_tisEqual (cs_name_t *str1, char *str2);
+/**
+ * Get the short name of a service from the service_id.
+ */
+const char * short_service_name_get(uint32_t service_id,
+ char *buf, size_t buf_size);
+
+/*
+ * Return state directory (ether icmap system.state_dir or LOCALSTATEDIR/lib/corosync)
+ */
+const char *get_state_dir(void);
+
+extern int util_is_valid_knet_crypto_model(const char *val,
+ const char **list_str, int machine_parseable_str,
+ const char *error_string_prefix, const char **error_string);
+
+extern int util_is_valid_knet_compress_model(const char *val,
+ const char **list_str, int machine_parseable_str,
+ const char *error_string_prefix, const char **error_string);
+
+#endif /* UTIL_H_DEFINED */
diff --git a/exec/votequorum.c b/exec/votequorum.c
new file mode 100644
index 0000000..7c6ed3b
--- /dev/null
+++ b/exec/votequorum.c
@@ -0,0 +1,3082 @@
+/*
+ * Copyright (c) 2009-2020 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Authors: Christine Caulfield (ccaulfie@redhat.com)
+ * Fabio M. Di Nitto (fdinitto@redhat.com)
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of the MontaVista Software, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdint.h>
+#include <unistd.h>
+
+#include <qb/qblist.h>
+#include <qb/qbipc_common.h>
+
+#include "quorum.h"
+#include <corosync/corodefs.h>
+#include <corosync/logsys.h>
+#include <corosync/coroapi.h>
+#include <corosync/icmap.h>
+#include <corosync/votequorum.h>
+#include <corosync/ipc_votequorum.h>
+
+#include "service.h"
+#include "util.h"
+
+LOGSYS_DECLARE_SUBSYS ("VOTEQ");
+
+/*
+ * interface with corosync
+ */
+
+static struct corosync_api_v1 *corosync_api;
+
+/*
+ * votequorum global config vars
+ */
+
+
+static char qdevice_name[VOTEQUORUM_QDEVICE_MAX_NAME_LEN];
+static struct cluster_node *qdevice = NULL;
+static unsigned int qdevice_timeout = VOTEQUORUM_QDEVICE_DEFAULT_TIMEOUT;
+static unsigned int qdevice_sync_timeout = VOTEQUORUM_QDEVICE_DEFAULT_SYNC_TIMEOUT;
+static uint8_t qdevice_can_operate = 1;
+static void *qdevice_reg_conn = NULL;
+static uint8_t qdevice_master_wins = 0;
+
+static uint8_t two_node = 0;
+
+static uint8_t wait_for_all = 0;
+static uint8_t wait_for_all_status = 0;
+static uint8_t wait_for_all_autoset = 0; /* Wait for all is not set explicitly and follows two_node */
+
+static enum {ATB_NONE, ATB_LOWEST, ATB_HIGHEST, ATB_LIST} auto_tie_breaker = ATB_NONE, initial_auto_tie_breaker = ATB_NONE;
+static int lowest_node_id = -1;
+static int highest_node_id = -1;
+
+#define DEFAULT_LMS_WIN 10000
+static uint8_t last_man_standing = 0;
+static uint32_t last_man_standing_window = DEFAULT_LMS_WIN;
+
+static uint8_t allow_downscale = 0;
+static uint32_t ev_barrier = 0;
+
+static uint8_t ev_tracking = 0;
+static uint32_t ev_tracking_barrier = 0;
+static int ev_tracking_fd = -1;
+
+/*
+ * votequorum_exec defines/structs/forward definitions
+ */
+
+struct req_exec_quorum_nodeinfo {
+ struct qb_ipc_request_header header __attribute__((aligned(8)));
+ uint32_t nodeid;
+ uint32_t votes;
+ uint32_t expected_votes;
+ uint32_t flags;
+} __attribute__((packed));
+
+struct req_exec_quorum_reconfigure {
+ struct qb_ipc_request_header header __attribute__((aligned(8)));
+ uint32_t nodeid;
+ uint32_t value;
+ uint8_t param;
+ uint8_t _pad0;
+ uint8_t _pad1;
+ uint8_t _pad2;
+} __attribute__((packed));
+
+struct req_exec_quorum_qdevice_reg {
+ struct qb_ipc_request_header header __attribute__((aligned(8)));
+ uint32_t operation;
+ char qdevice_name[VOTEQUORUM_QDEVICE_MAX_NAME_LEN];
+} __attribute__((packed));
+
+struct req_exec_quorum_qdevice_reconfigure {
+ struct qb_ipc_request_header header __attribute__((aligned(8)));
+ char oldname[VOTEQUORUM_QDEVICE_MAX_NAME_LEN];
+ char newname[VOTEQUORUM_QDEVICE_MAX_NAME_LEN];
+} __attribute__((packed));
+
+/*
+ * votequorum_exec onwire version (via totem)
+ */
+
+#include "votequorum.h"
+
+/*
+ * votequorum_exec onwire messages (via totem)
+ */
+
+#define MESSAGE_REQ_EXEC_VOTEQUORUM_NODEINFO 0
+#define MESSAGE_REQ_EXEC_VOTEQUORUM_RECONFIGURE 1
+#define MESSAGE_REQ_EXEC_VOTEQUORUM_QDEVICE_REG 2
+#define MESSAGE_REQ_EXEC_VOTEQUORUM_QDEVICE_RECONFIGURE 3
+
+static void votequorum_exec_send_expectedvotes_notification(void);
+static int votequorum_exec_send_quorum_notification(void *conn, uint64_t context);
+static int votequorum_exec_send_nodelist_notification(void *conn, uint64_t context);
+
+#define VOTEQUORUM_RECONFIG_PARAM_EXPECTED_VOTES 1
+#define VOTEQUORUM_RECONFIG_PARAM_NODE_VOTES 2
+#define VOTEQUORUM_RECONFIG_PARAM_CANCEL_WFA 3
+
+static int votequorum_exec_send_reconfigure(uint8_t param, unsigned int nodeid, uint32_t value);
+
+/*
+ * used by req_exec_quorum_qdevice_reg
+ */
+#define VOTEQUORUM_QDEVICE_OPERATION_UNREGISTER 0
+#define VOTEQUORUM_QDEVICE_OPERATION_REGISTER 1
+
+/*
+ * votequorum internal node status/view
+ */
+
+#define NODE_FLAGS_QUORATE 1
+#define NODE_FLAGS_LEAVING 2
+#define NODE_FLAGS_WFASTATUS 4
+#define NODE_FLAGS_FIRST 8
+#define NODE_FLAGS_QDEVICE_REGISTERED 16
+#define NODE_FLAGS_QDEVICE_ALIVE 32
+#define NODE_FLAGS_QDEVICE_CAST_VOTE 64
+#define NODE_FLAGS_QDEVICE_MASTER_WINS 128
+
+typedef enum {
+ NODESTATE_MEMBER=1,
+ NODESTATE_DEAD,
+ NODESTATE_LEAVING
+} nodestate_t;
+
+struct cluster_node {
+ int node_id;
+ nodestate_t state;
+ uint32_t votes;
+ uint32_t expected_votes;
+ uint32_t flags;
+ struct qb_list_head list;
+};
+
+/*
+ * votequorum internal quorum status
+ */
+
+static uint8_t quorum;
+static uint8_t cluster_is_quorate;
+
+/*
+ * votequorum membership data
+ */
+
+static struct cluster_node *us;
+static struct qb_list_head cluster_members_list;
+static unsigned int quorum_members[PROCESSOR_COUNT_MAX];
+static unsigned int previous_quorum_members[PROCESSOR_COUNT_MAX];
+static unsigned int atb_nodelist[PROCESSOR_COUNT_MAX];
+static int quorum_members_entries = 0;
+static int previous_quorum_members_entries = 0;
+static int atb_nodelist_entries = 0;
+static struct memb_ring_id quorum_ringid;
+
+/*
+ * pre allocate all cluster_nodes + one for qdevice
+ */
+static struct cluster_node cluster_nodes[PROCESSOR_COUNT_MAX+2];
+static int cluster_nodes_entries = 0;
+
+/*
+ * votequorum tracking
+ */
+struct quorum_pd {
+ unsigned char track_flags;
+ int tracking_enabled;
+ uint64_t tracking_context;
+ struct qb_list_head list;
+ void *conn;
+};
+
+static struct qb_list_head trackers_list;
+
+/*
+ * votequorum timers
+ */
+
+static corosync_timer_handle_t qdevice_timer;
+static int qdevice_timer_set = 0;
+static corosync_timer_handle_t last_man_standing_timer;
+static int last_man_standing_timer_set = 0;
+static int sync_nodeinfo_sent = 0;
+static int sync_wait_for_poll_or_timeout = 0;
+
+/*
+ * Service Interfaces required by service_message_handler struct
+ */
+
+static int sync_in_progress = 0;
+
+static void votequorum_sync_init (
+ const unsigned int *trans_list,
+ size_t trans_list_entries,
+ const unsigned int *member_list,
+ size_t member_list_entries,
+ const struct memb_ring_id *ring_id);
+
+static int votequorum_sync_process (void);
+static void votequorum_sync_activate (void);
+static void votequorum_sync_abort (void);
+
+static quorum_set_quorate_fn_t quorum_callback;
+
+/*
+ * votequorum_exec handler and definitions
+ */
+
+static char *votequorum_exec_init_fn (struct corosync_api_v1 *api);
+static int votequorum_exec_exit_fn (void);
+static int votequorum_exec_send_nodeinfo(uint32_t nodeid);
+
+static void message_handler_req_exec_votequorum_nodeinfo (
+ const void *message,
+ unsigned int nodeid);
+static void exec_votequorum_nodeinfo_endian_convert (void *message);
+
+static void message_handler_req_exec_votequorum_reconfigure (
+ const void *message,
+ unsigned int nodeid);
+static void exec_votequorum_reconfigure_endian_convert (void *message);
+
+static void message_handler_req_exec_votequorum_qdevice_reg (
+ const void *message,
+ unsigned int nodeid);
+static void exec_votequorum_qdevice_reg_endian_convert (void *message);
+
+static void message_handler_req_exec_votequorum_qdevice_reconfigure (
+ const void *message,
+ unsigned int nodeid);
+static void exec_votequorum_qdevice_reconfigure_endian_convert (void *message);
+
+static struct corosync_exec_handler votequorum_exec_engine[] =
+{
+ { /* 0 */
+ .exec_handler_fn = message_handler_req_exec_votequorum_nodeinfo,
+ .exec_endian_convert_fn = exec_votequorum_nodeinfo_endian_convert
+ },
+ { /* 1 */
+ .exec_handler_fn = message_handler_req_exec_votequorum_reconfigure,
+ .exec_endian_convert_fn = exec_votequorum_reconfigure_endian_convert
+ },
+ { /* 2 */
+ .exec_handler_fn = message_handler_req_exec_votequorum_qdevice_reg,
+ .exec_endian_convert_fn = exec_votequorum_qdevice_reg_endian_convert
+ },
+ { /* 3 */
+ .exec_handler_fn = message_handler_req_exec_votequorum_qdevice_reconfigure,
+ .exec_endian_convert_fn = exec_votequorum_qdevice_reconfigure_endian_convert
+ },
+};
+
+/*
+ * Library Handler and Functions Definitions
+ */
+
+static int quorum_lib_init_fn (void *conn);
+
+static int quorum_lib_exit_fn (void *conn);
+
+static void qdevice_timer_fn(void *arg);
+
+static void message_handler_req_lib_votequorum_getinfo (void *conn,
+ const void *message);
+
+static void message_handler_req_lib_votequorum_setexpected (void *conn,
+ const void *message);
+
+static void message_handler_req_lib_votequorum_setvotes (void *conn,
+ const void *message);
+
+static void message_handler_req_lib_votequorum_trackstart (void *conn,
+ const void *message);
+
+static void message_handler_req_lib_votequorum_trackstop (void *conn,
+ const void *message);
+
+static void message_handler_req_lib_votequorum_qdevice_register (void *conn,
+ const void *message);
+
+static void message_handler_req_lib_votequorum_qdevice_unregister (void *conn,
+ const void *message);
+
+static void message_handler_req_lib_votequorum_qdevice_update (void *conn,
+ const void *message);
+
+static void message_handler_req_lib_votequorum_qdevice_poll (void *conn,
+ const void *message);
+
+static void message_handler_req_lib_votequorum_qdevice_master_wins (void *conn,
+ const void *message);
+
+static struct corosync_lib_handler quorum_lib_service[] =
+{
+ { /* 0 */
+ .lib_handler_fn = message_handler_req_lib_votequorum_getinfo,
+ .flow_control = COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED
+ },
+ { /* 1 */
+ .lib_handler_fn = message_handler_req_lib_votequorum_setexpected,
+ .flow_control = COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED
+ },
+ { /* 2 */
+ .lib_handler_fn = message_handler_req_lib_votequorum_setvotes,
+ .flow_control = COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED
+ },
+ { /* 3 */
+ .lib_handler_fn = message_handler_req_lib_votequorum_trackstart,
+ .flow_control = COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED
+ },
+ { /* 4 */
+ .lib_handler_fn = message_handler_req_lib_votequorum_trackstop,
+ .flow_control = COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED
+ },
+ { /* 5 */
+ .lib_handler_fn = message_handler_req_lib_votequorum_qdevice_register,
+ .flow_control = COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED
+ },
+ { /* 6 */
+ .lib_handler_fn = message_handler_req_lib_votequorum_qdevice_unregister,
+ .flow_control = COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED
+ },
+ { /* 7 */
+ .lib_handler_fn = message_handler_req_lib_votequorum_qdevice_update,
+ .flow_control = COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED
+ },
+ { /* 8 */
+ .lib_handler_fn = message_handler_req_lib_votequorum_qdevice_poll,
+ .flow_control = COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED
+ },
+ { /* 9 */
+ .lib_handler_fn = message_handler_req_lib_votequorum_qdevice_master_wins,
+ .flow_control = COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED
+ }
+};
+
+static struct corosync_service_engine votequorum_service_engine = {
+ .name = "corosync vote quorum service v1.0",
+ .id = VOTEQUORUM_SERVICE,
+ .priority = 2,
+ .private_data_size = sizeof (struct quorum_pd),
+ .allow_inquorate = CS_LIB_ALLOW_INQUORATE,
+ .flow_control = COROSYNC_LIB_FLOW_CONTROL_REQUIRED,
+ .lib_init_fn = quorum_lib_init_fn,
+ .lib_exit_fn = quorum_lib_exit_fn,
+ .lib_engine = quorum_lib_service,
+ .lib_engine_count = sizeof (quorum_lib_service) / sizeof (struct corosync_lib_handler),
+ .exec_init_fn = votequorum_exec_init_fn,
+ .exec_exit_fn = votequorum_exec_exit_fn,
+ .exec_engine = votequorum_exec_engine,
+ .exec_engine_count = sizeof (votequorum_exec_engine) / sizeof (struct corosync_exec_handler),
+ .sync_init = votequorum_sync_init,
+ .sync_process = votequorum_sync_process,
+ .sync_activate = votequorum_sync_activate,
+ .sync_abort = votequorum_sync_abort
+};
+
+struct corosync_service_engine *votequorum_get_service_engine_ver0 (void)
+{
+ return (&votequorum_service_engine);
+}
+
+static struct default_service votequorum_service[] = {
+ {
+ .name = "corosync_votequorum",
+ .ver = 0,
+ .loader = votequorum_get_service_engine_ver0
+ },
+};
+
+/*
+ * common/utility macros/functions
+ */
+
+#define max(a,b) (((a) > (b)) ? (a) : (b))
+
+static void node_add_ordered(struct cluster_node *newnode)
+{
+ struct cluster_node *node = NULL;
+ struct qb_list_head *tmp;
+
+ ENTER();
+
+ qb_list_for_each(tmp, &cluster_members_list) {
+ node = qb_list_entry(tmp, struct cluster_node, list);
+ if (newnode->node_id < node->node_id) {
+ break;
+ }
+ }
+
+ if (!node) {
+ qb_list_add(&newnode->list, &cluster_members_list);
+ } else {
+ qb_list_add_tail(&newnode->list, &node->list);
+ }
+
+ LEAVE();
+}
+
+static struct cluster_node *allocate_node(unsigned int nodeid)
+{
+ struct cluster_node *cl = NULL;
+ struct qb_list_head *tmp;
+
+ ENTER();
+
+ if (cluster_nodes_entries <= PROCESSOR_COUNT_MAX + 1) {
+ cl = (struct cluster_node *)&cluster_nodes[cluster_nodes_entries];
+ cluster_nodes_entries++;
+ } else {
+ qb_list_for_each(tmp, &cluster_members_list) {
+ cl = qb_list_entry(tmp, struct cluster_node, list);
+ if (cl->state == NODESTATE_DEAD) {
+ break;
+ }
+ }
+ /*
+ * this should never happen
+ */
+ if (!cl) {
+ log_printf(LOGSYS_LEVEL_CRIT, "Unable to find memory for node " CS_PRI_NODE_ID " data!!", nodeid);
+ goto out;
+ }
+ qb_list_del(tmp);
+ }
+
+ memset(cl, 0, sizeof(struct cluster_node));
+ cl->node_id = nodeid;
+ if (nodeid != VOTEQUORUM_QDEVICE_NODEID) {
+ node_add_ordered(cl);
+ }
+
+out:
+ LEAVE();
+
+ return cl;
+}
+
+static struct cluster_node *find_node_by_nodeid(unsigned int nodeid)
+{
+ struct cluster_node *node;
+ struct qb_list_head *tmp;
+
+ ENTER();
+
+ if (nodeid == us->node_id) {
+ LEAVE();
+ return us;
+ }
+
+ if (nodeid == VOTEQUORUM_QDEVICE_NODEID) {
+ LEAVE();
+ return qdevice;
+ }
+
+ qb_list_for_each(tmp, &cluster_members_list) {
+ node = qb_list_entry(tmp, struct cluster_node, list);
+ if (node->node_id == nodeid) {
+ LEAVE();
+ return node;
+ }
+ }
+
+ LEAVE();
+ return NULL;
+}
+
+static void get_lowest_node_id(void)
+{
+ struct cluster_node *node = NULL;
+ struct qb_list_head *tmp;
+
+ ENTER();
+
+ lowest_node_id = us->node_id;
+
+ qb_list_for_each(tmp, &cluster_members_list) {
+ node = qb_list_entry(tmp, struct cluster_node, list);
+ if ((node->state == NODESTATE_MEMBER) &&
+ (node->node_id < lowest_node_id)) {
+ lowest_node_id = node->node_id;
+ }
+ }
+ log_printf(LOGSYS_LEVEL_DEBUG, "lowest node id: " CS_PRI_NODE_ID " us: " CS_PRI_NODE_ID, lowest_node_id, us->node_id);
+ icmap_set_uint32("runtime.votequorum.lowest_node_id", lowest_node_id);
+
+ LEAVE();
+}
+
+static void get_highest_node_id(void)
+{
+ struct cluster_node *node = NULL;
+ struct qb_list_head *tmp;
+
+ ENTER();
+
+ highest_node_id = us->node_id;
+
+ qb_list_for_each(tmp, &cluster_members_list) {
+ node = qb_list_entry(tmp, struct cluster_node, list);
+ if ((node->state == NODESTATE_MEMBER) &&
+ (node->node_id > highest_node_id)) {
+ highest_node_id = node->node_id;
+ }
+ }
+ log_printf(LOGSYS_LEVEL_DEBUG, "highest node id: " CS_PRI_NODE_ID " us: " CS_PRI_NODE_ID, highest_node_id, us->node_id);
+ icmap_set_uint32("runtime.votequorum.highest_node_id", highest_node_id);
+
+ LEAVE();
+}
+
+static int check_low_node_id_partition(void)
+{
+ struct cluster_node *node = NULL;
+ struct qb_list_head *tmp;
+ int found = 0;
+
+ ENTER();
+
+ qb_list_for_each(tmp, &cluster_members_list) {
+ node = qb_list_entry(tmp, struct cluster_node, list);
+ if ((node->state == NODESTATE_MEMBER) &&
+ (node->node_id == lowest_node_id)) {
+ found = 1;
+ }
+ }
+
+ LEAVE();
+ return found;
+}
+
+static int check_high_node_id_partition(void)
+{
+ struct cluster_node *node = NULL;
+ struct qb_list_head *tmp;
+ int found = 0;
+
+ ENTER();
+
+ qb_list_for_each(tmp, &cluster_members_list) {
+ node = qb_list_entry(tmp, struct cluster_node, list);
+ if ((node->state == NODESTATE_MEMBER) &&
+ (node->node_id == highest_node_id)) {
+ found = 1;
+ }
+ }
+
+ LEAVE();
+ return found;
+}
+
+static int is_in_nodelist(int nodeid, unsigned int *members, int entries)
+{
+ int i;
+ ENTER();
+
+ for (i=0; i<entries; i++) {
+ if (nodeid == members[i]) {
+ LEAVE();
+ return 1;
+ }
+ }
+ LEAVE();
+ return 0;
+}
+
+/*
+ * The algorithm for a list of tie-breaker nodes is:
+ * travel the list of nodes in the auto_tie_breaker list,
+ * if the node IS in our current partition, check if the
+ * nodes earlier in the atb list are in the 'previous' partition;
+ * If none are found then we are safe to be quorate, if any are
+ * then we cannot be as we don't know if that node is up or down.
+ * If we don't have a node in the current list we are NOT quorate.
+ * Obviously if we find the first node in the atb list in our
+ * partition then we are quorate.
+ *
+ * Special cases lowest nodeid, and highest nodeid are handled separately.
+ */
+static int check_auto_tie_breaker(void)
+{
+ int i, j;
+ int res;
+ ENTER();
+
+ if (auto_tie_breaker == ATB_LOWEST) {
+ res = check_low_node_id_partition();
+ log_printf(LOGSYS_LEVEL_DEBUG, "ATB_LOWEST decision: %d", res);
+ LEAVE();
+ return res;
+ }
+ if (auto_tie_breaker == ATB_HIGHEST) {
+ res = check_high_node_id_partition();
+ log_printf(LOGSYS_LEVEL_DEBUG, "ATB_HIGHEST decision: %d", res);
+ LEAVE();
+ return res;
+ }
+
+ /* Assume ATB_LIST, we should never be called for ATB_NONE */
+ for (i=0; i < atb_nodelist_entries; i++) {
+ if (is_in_nodelist(atb_nodelist[i], quorum_members, quorum_members_entries)) {
+ /*
+ * Node is in our partition, if any of its predecessors are
+ * in the previous quorum partition then it might be in the
+ * 'other half' (as we've got this far without seeing it here)
+ * and so we can't be quorate.
+ */
+ for (j=0; j<i; j++) {
+ if (is_in_nodelist(atb_nodelist[j], previous_quorum_members, previous_quorum_members_entries)) {
+ log_printf(LOGSYS_LEVEL_DEBUG, "ATB_LIST found node " CS_PRI_NODE_ID " in previous partition but not here, quorum denied", atb_nodelist[j]);
+ LEAVE();
+ return 0;
+ }
+ }
+
+ /*
+ * None of the other list nodes were in the previous partition, if there
+ * are enough votes, we can be quorate
+ */
+ log_printf(LOGSYS_LEVEL_DEBUG, "ATB_LIST found node " CS_PRI_NODE_ID " in current partition, we can be quorate", atb_nodelist[i]);
+ LEAVE();
+ return 1;
+ }
+ }
+ log_printf(LOGSYS_LEVEL_DEBUG, "ATB_LIST found no list nodes in current partition, we cannot be quorate");
+ LEAVE();
+ return 0;
+}
+
+/*
+ * atb_string can be either:
+ * 'lowest'
+ * 'highest'
+ * a list of nodeids
+ */
+static void parse_atb_string(char *atb_string)
+{
+ char *ptr;
+ long num;
+
+ ENTER();
+ auto_tie_breaker = ATB_NONE;
+
+ if (!strcmp(atb_string, "lowest"))
+ auto_tie_breaker = ATB_LOWEST;
+
+ if (!strcmp(atb_string, "highest"))
+ auto_tie_breaker = ATB_HIGHEST;
+
+ if (atoi(atb_string)) {
+
+ atb_nodelist_entries = 0;
+ ptr = atb_string;
+ do {
+ num = strtol(ptr, &ptr, 10);
+ if (num) {
+ log_printf(LOGSYS_LEVEL_DEBUG, "ATB nodelist[%d] = %d", atb_nodelist_entries, num);
+ atb_nodelist[atb_nodelist_entries++] = num;
+ }
+ } while (num);
+
+ if (atb_nodelist_entries) {
+ auto_tie_breaker = ATB_LIST;
+ }
+ }
+ icmap_set_uint32("runtime.votequorum.atb_type", auto_tie_breaker);
+ log_printf(LOGSYS_LEVEL_DEBUG, "ATB type = %d", auto_tie_breaker);
+
+ /* Make sure we got something */
+ if (auto_tie_breaker == ATB_NONE) {
+ log_printf(LOGSYS_LEVEL_WARNING, "auto_tie_breaker_nodes is not valid. It must be 'lowest', 'highest' or a space-separated list of node IDs. auto_tie_breaker is disabled");
+ auto_tie_breaker = ATB_NONE;
+ }
+ LEAVE();
+}
+
+static int check_qdevice_master(void)
+{
+ struct cluster_node *node = NULL;
+ struct qb_list_head *tmp;
+ int found = 0;
+
+ ENTER();
+
+ qb_list_for_each(tmp, &cluster_members_list) {
+ node = qb_list_entry(tmp, struct cluster_node, list);
+ if ((node->state == NODESTATE_MEMBER) &&
+ (node->flags & NODE_FLAGS_QDEVICE_MASTER_WINS) &&
+ (node->flags & NODE_FLAGS_QDEVICE_CAST_VOTE)) {
+ found = 1;
+ }
+ }
+
+ LEAVE();
+ return found;
+}
+
+static void decode_flags(uint32_t flags)
+{
+ ENTER();
+
+ log_printf(LOGSYS_LEVEL_DEBUG,
+ "flags: quorate: %s Leaving: %s WFA Status: %s First: %s Qdevice: %s QdeviceAlive: %s QdeviceCastVote: %s QdeviceMasterWins: %s",
+ (flags & NODE_FLAGS_QUORATE)?"Yes":"No",
+ (flags & NODE_FLAGS_LEAVING)?"Yes":"No",
+ (flags & NODE_FLAGS_WFASTATUS)?"Yes":"No",
+ (flags & NODE_FLAGS_FIRST)?"Yes":"No",
+ (flags & NODE_FLAGS_QDEVICE_REGISTERED)?"Yes":"No",
+ (flags & NODE_FLAGS_QDEVICE_ALIVE)?"Yes":"No",
+ (flags & NODE_FLAGS_QDEVICE_CAST_VOTE)?"Yes":"No",
+ (flags & NODE_FLAGS_QDEVICE_MASTER_WINS)?"Yes":"No");
+
+ LEAVE();
+}
+
+/*
+ * load/save are copied almost pristine from totemsrp,c
+ */
+static int load_ev_tracking_barrier(void)
+{
+ int res = 0;
+ char filename[PATH_MAX];
+
+ ENTER();
+
+ snprintf(filename, sizeof(filename) - 1, "%s/ev_tracking", get_state_dir());
+
+ ev_tracking_fd = open(filename, O_RDWR, 0700);
+ if (ev_tracking_fd != -1) {
+ res = read (ev_tracking_fd, &ev_tracking_barrier, sizeof(uint32_t));
+ close(ev_tracking_fd);
+ if (res == sizeof (uint32_t)) {
+ LEAVE();
+ return 0;
+ }
+ }
+
+ ev_tracking_barrier = 0;
+ umask(0);
+ ev_tracking_fd = open (filename, O_CREAT|O_RDWR, 0700);
+ if (ev_tracking_fd != -1) {
+ res = write (ev_tracking_fd, &ev_tracking_barrier, sizeof (uint32_t));
+ if ((res == -1) || (res != sizeof (uint32_t))) {
+ log_printf(LOGSYS_LEVEL_WARNING,
+ "Unable to write to %s", filename);
+ }
+ close(ev_tracking_fd);
+ LEAVE();
+ return 0;
+ }
+ log_printf(LOGSYS_LEVEL_WARNING,
+ "Unable to create %s file", filename);
+
+ LEAVE();
+
+ return -1;
+}
+
+static void update_wait_for_all_status(uint8_t wfa_status)
+{
+ ENTER();
+
+ wait_for_all_status = wfa_status;
+ if (wait_for_all_status) {
+ us->flags |= NODE_FLAGS_WFASTATUS;
+ } else {
+ us->flags &= ~NODE_FLAGS_WFASTATUS;
+ }
+ icmap_set_uint8("runtime.votequorum.wait_for_all_status",
+ wait_for_all_status);
+
+ LEAVE();
+}
+
+static void update_two_node(void)
+{
+ ENTER();
+
+ icmap_set_uint8("runtime.votequorum.two_node", two_node);
+
+ LEAVE();
+}
+
+static void update_ev_barrier(uint32_t expected_votes)
+{
+ ENTER();
+
+ ev_barrier = expected_votes;
+ icmap_set_uint32("runtime.votequorum.ev_barrier", ev_barrier);
+
+ LEAVE();
+}
+
+static void update_qdevice_can_operate(uint8_t status)
+{
+ ENTER();
+
+ qdevice_can_operate = status;
+ icmap_set_uint8("runtime.votequorum.qdevice_can_operate", qdevice_can_operate);
+
+ LEAVE();
+}
+
+static void update_qdevice_master_wins(uint8_t allow)
+{
+ ENTER();
+
+ qdevice_master_wins = allow;
+ icmap_set_uint8("runtime.votequorum.qdevice_master_wins", qdevice_master_wins);
+
+ LEAVE();
+}
+
+static void update_ev_tracking_barrier(uint32_t ev_t_barrier)
+{
+ int res;
+
+ ENTER();
+
+ ev_tracking_barrier = ev_t_barrier;
+ icmap_set_uint32("runtime.votequorum.ev_tracking_barrier", ev_tracking_barrier);
+
+ if (lseek (ev_tracking_fd, 0, SEEK_SET) != 0) {
+ log_printf(LOGSYS_LEVEL_WARNING,
+ "Unable to update ev_tracking_barrier on disk data!!!");
+ LEAVE();
+ return;
+ }
+
+ res = write (ev_tracking_fd, &ev_tracking_barrier, sizeof (uint32_t));
+ if (res != sizeof (uint32_t)) {
+ log_printf(LOGSYS_LEVEL_WARNING,
+ "Unable to update ev_tracking_barrier on disk data!!!");
+ }
+#ifdef HAVE_FDATASYNC
+ fdatasync(ev_tracking_fd);
+#else
+ fsync(ev_tracking_fd);
+#endif
+
+ LEAVE();
+}
+
+/*
+ * quorum calculation core bits
+ */
+
+static int calculate_quorum(int allow_decrease, unsigned int max_expected, unsigned int *ret_total_votes)
+{
+ struct qb_list_head *nodelist;
+ struct cluster_node *node;
+ unsigned int total_votes = 0;
+ unsigned int highest_expected = 0;
+ unsigned int newquorum, q1, q2;
+ unsigned int total_nodes = 0;
+
+ ENTER();
+
+ if ((allow_downscale) && (allow_decrease) && (max_expected)) {
+ max_expected = max(ev_barrier, max_expected);
+ }
+
+ qb_list_for_each(nodelist, &cluster_members_list) {
+ node = qb_list_entry(nodelist, struct cluster_node, list);
+
+ log_printf(LOGSYS_LEVEL_DEBUG, "node " CS_PRI_NODE_ID " state=%d, votes=%u, expected=%u",
+ node->node_id, node->state, node->votes, node->expected_votes);
+
+ if (node->state == NODESTATE_MEMBER) {
+ highest_expected = max(highest_expected, node->expected_votes);
+ total_votes += node->votes;
+ total_nodes++;
+ }
+ }
+
+ if (us->flags & NODE_FLAGS_QDEVICE_CAST_VOTE) {
+ log_printf(LOGSYS_LEVEL_DEBUG, "node 0 state=1, votes=%u", qdevice->votes);
+ total_votes += qdevice->votes;
+ total_nodes++;
+ }
+
+ if (max_expected > 0) {
+ highest_expected = max_expected;
+ }
+
+ /*
+ * This quorum calculation is taken from the OpenVMS Cluster Systems
+ * manual, but, then, you guessed that didn't you
+ */
+ q1 = (highest_expected + 2) / 2;
+ q2 = (total_votes + 2) / 2;
+ newquorum = max(q1, q2);
+
+ /*
+ * Normally quorum never decreases but the system administrator can
+ * force it down by setting expected votes to a maximum value
+ */
+ if (!allow_decrease) {
+ newquorum = max(quorum, newquorum);
+ }
+
+ /*
+ * The special two_node mode allows each of the two nodes to retain
+ * quorum if the other fails. Only one of the two should live past
+ * fencing (as both nodes try to fence each other in split-brain.)
+ * Also: if there are more than two nodes, force us inquorate to avoid
+ * any damage or confusion.
+ */
+ if (two_node && total_nodes <= 2) {
+ newquorum = 1;
+ }
+
+ if (ret_total_votes) {
+ *ret_total_votes = total_votes;
+ }
+
+ LEAVE();
+ return newquorum;
+}
+
+static void update_node_expected_votes(int new_expected_votes)
+{
+ struct qb_list_head *nodelist;
+ struct cluster_node *node;
+
+ if (new_expected_votes) {
+ qb_list_for_each(nodelist, &cluster_members_list) {
+ node = qb_list_entry(nodelist, struct cluster_node, list);
+
+ if (node->state == NODESTATE_MEMBER) {
+ node->expected_votes = new_expected_votes;
+ }
+ }
+ }
+}
+
+static void are_we_quorate(unsigned int total_votes)
+{
+ int quorate;
+ int quorum_change = 0;
+
+ ENTER();
+
+ /*
+ * wait for all nodes to show up before granting quorum
+ */
+
+ if ((wait_for_all) && (wait_for_all_status)) {
+ if (total_votes != us->expected_votes) {
+ log_printf(LOGSYS_LEVEL_NOTICE,
+ "Waiting for all cluster members. "
+ "Current votes: %d expected_votes: %d",
+ total_votes, us->expected_votes);
+ assert(!cluster_is_quorate);
+ return;
+ }
+ update_wait_for_all_status(0);
+ }
+
+ if (quorum > total_votes) {
+ quorate = 0;
+ } else {
+ quorate = 1;
+ get_lowest_node_id();
+ get_highest_node_id();
+ }
+
+ if ((auto_tie_breaker != ATB_NONE) &&
+ /* Must be a half (or half-1) split */
+ (total_votes == (us->expected_votes / 2)) &&
+ /* If the 'other' partition in a split might have quorum then we can't run ATB */
+ (previous_quorum_members_entries - quorum_members_entries < quorum) &&
+ (check_auto_tie_breaker() == 1)) {
+ quorate = 1;
+ }
+
+ if ((qdevice_master_wins) &&
+ (!quorate) &&
+ (check_qdevice_master() == 1)) {
+ log_printf(LOGSYS_LEVEL_DEBUG, "node is quorate as part of master_wins partition");
+ quorate = 1;
+ }
+
+ if (cluster_is_quorate && !quorate) {
+ quorum_change = 1;
+ log_printf(LOGSYS_LEVEL_DEBUG, "quorum lost, blocking activity");
+ }
+ if (!cluster_is_quorate && quorate) {
+ quorum_change = 1;
+ log_printf(LOGSYS_LEVEL_DEBUG, "quorum regained, resuming activity");
+ }
+
+ cluster_is_quorate = quorate;
+ if (cluster_is_quorate) {
+ us->flags |= NODE_FLAGS_QUORATE;
+ } else {
+ us->flags &= ~NODE_FLAGS_QUORATE;
+ }
+
+ if (wait_for_all) {
+ if (quorate) {
+ update_wait_for_all_status(0);
+ } else {
+ update_wait_for_all_status(1);
+ }
+ }
+
+ if ((quorum_change) &&
+ (sync_in_progress == 0)) {
+ quorum_callback(quorum_members, quorum_members_entries,
+ cluster_is_quorate, &quorum_ringid);
+ votequorum_exec_send_quorum_notification(NULL, 0L);
+ }
+
+ LEAVE();
+}
+
+static void get_total_votes(unsigned int *totalvotes, unsigned int *current_members)
+{
+ unsigned int total_votes = 0;
+ unsigned int cluster_members = 0;
+ struct qb_list_head *nodelist;
+ struct cluster_node *node;
+
+ ENTER();
+
+ qb_list_for_each(nodelist, &cluster_members_list) {
+ node = qb_list_entry(nodelist, struct cluster_node, list);
+ if (node->state == NODESTATE_MEMBER) {
+ cluster_members++;
+ total_votes += node->votes;
+ }
+ }
+
+ if (qdevice->votes) {
+ total_votes += qdevice->votes;
+ cluster_members++;
+ }
+
+ *totalvotes = total_votes;
+ *current_members = cluster_members;
+
+ LEAVE();
+}
+
+/*
+ * Recalculate cluster quorum, set quorate and notify changes
+ */
+static void recalculate_quorum(int allow_decrease, int by_current_nodes)
+{
+ unsigned int total_votes = 0;
+ unsigned int cluster_members = 0;
+
+ ENTER();
+
+ get_total_votes(&total_votes, &cluster_members);
+
+ if (!by_current_nodes) {
+ cluster_members = 0;
+ }
+
+ /*
+ * Keep expected_votes at the highest number of votes in the cluster
+ */
+ log_printf(LOGSYS_LEVEL_DEBUG, "total_votes=%d, expected_votes=%d", total_votes, us->expected_votes);
+ if (total_votes > us->expected_votes) {
+ us->expected_votes = total_votes;
+ votequorum_exec_send_expectedvotes_notification();
+ }
+
+ if ((ev_tracking) &&
+ (us->expected_votes > ev_tracking_barrier)) {
+ update_ev_tracking_barrier(us->expected_votes);
+ }
+
+ quorum = calculate_quorum(allow_decrease, cluster_members, &total_votes);
+ update_node_expected_votes(cluster_members);
+
+ are_we_quorate(total_votes);
+
+ LEAVE();
+}
+
+/*
+ * configuration bits and pieces
+ */
+
+static int votequorum_read_nodelist_configuration(uint32_t *votes,
+ uint32_t *nodes,
+ uint32_t *expected_votes)
+{
+ icmap_iter_t iter;
+ const char *iter_key;
+ char tmp_key[ICMAP_KEYNAME_MAXLEN];
+ uint32_t our_pos, node_pos, last_node_pos=-1;
+ uint32_t nodecount = 0;
+ uint32_t nodelist_expected_votes = 0;
+ uint32_t node_votes = 0;
+ int res = 0;
+
+ ENTER();
+
+ if (icmap_get_uint32("nodelist.local_node_pos", &our_pos) != CS_OK) {
+ log_printf(LOGSYS_LEVEL_DEBUG,
+ "No nodelist defined or our node is not in the nodelist");
+ return 0;
+ }
+
+ iter = icmap_iter_init("nodelist.node.");
+
+ while ((iter_key = icmap_iter_next(iter, NULL, NULL)) != NULL) {
+
+ res = sscanf(iter_key, "nodelist.node.%u.%s", &node_pos, tmp_key);
+ if (res != 2) {
+ continue;
+ }
+
+ /*
+ * If current node_pos is the same as the last_node_pos then skip it
+ * so we only do the code below once per node.
+ * (icmap keys are always in order)
+ */
+ if (last_node_pos == node_pos) {
+ continue;
+ }
+ last_node_pos = node_pos;
+
+ nodecount++;
+
+ snprintf(tmp_key, ICMAP_KEYNAME_MAXLEN, "nodelist.node.%u.quorum_votes", node_pos);
+ if (icmap_get_uint32(tmp_key, &node_votes) != CS_OK) {
+ node_votes = 1;
+ }
+
+ nodelist_expected_votes = nodelist_expected_votes + node_votes;
+
+ if (node_pos == our_pos) {
+ *votes = node_votes;
+ }
+ }
+
+ *expected_votes = nodelist_expected_votes;
+ *nodes = nodecount;
+
+ icmap_iter_finalize(iter);
+
+ LEAVE();
+
+ return 1;
+}
+
+static int votequorum_qdevice_is_configured(uint32_t *qdevice_votes)
+{
+ char *qdevice_model = NULL;
+ int ret = 0;
+
+ ENTER();
+
+ if (icmap_get_string("quorum.device.model", &qdevice_model) == CS_OK) {
+ if (strlen(qdevice_model)) {
+ if (icmap_get_uint32("quorum.device.votes", qdevice_votes) != CS_OK) {
+ *qdevice_votes = -1;
+ }
+ if (icmap_get_uint32("quorum.device.timeout", &qdevice_timeout) != CS_OK) {
+ qdevice_timeout = VOTEQUORUM_QDEVICE_DEFAULT_TIMEOUT;
+ }
+ if (icmap_get_uint32("quorum.device.sync_timeout", &qdevice_sync_timeout) != CS_OK) {
+ qdevice_sync_timeout = VOTEQUORUM_QDEVICE_DEFAULT_SYNC_TIMEOUT;
+ }
+ update_qdevice_can_operate(1);
+ ret = 1;
+ }
+
+ free(qdevice_model);
+ }
+
+ LEAVE();
+
+ return ret;
+}
+
+#define VOTEQUORUM_READCONFIG_STARTUP 0
+#define VOTEQUORUM_READCONFIG_RUNTIME 1
+
+static char *votequorum_readconfig(int runtime)
+{
+ uint32_t node_votes = 0, qdevice_votes = 0;
+ uint32_t node_expected_votes = 0, expected_votes = 0;
+ uint32_t node_count = 0;
+ uint8_t atb = 0;
+ int have_nodelist, have_qdevice;
+ char *atb_string = NULL;
+ char *error = NULL;
+
+ ENTER();
+
+ log_printf(LOGSYS_LEVEL_DEBUG, "Reading configuration (runtime: %d)", runtime);
+
+ /*
+ * Set the few things we re-read at runtime back to their defaults
+ */
+ if (runtime) {
+ two_node = 0;
+ expected_votes = 0;
+ /* auto_tie_breaker cannot be changed by config reload, but
+ * we automatically disable it on odd-sized clusters without
+ * wait_for_all.
+ * We may need to re-enable it when membership changes to ensure
+ * that auto_tie_breaker is consistent across all nodes */
+ auto_tie_breaker = initial_auto_tie_breaker;
+ icmap_set_uint32("runtime.votequorum.atb_type", auto_tie_breaker);
+ }
+
+ /*
+ * gather basic data here
+ */
+ (void)icmap_get_uint32("quorum.expected_votes", &expected_votes);
+ have_nodelist = votequorum_read_nodelist_configuration(&node_votes, &node_count, &node_expected_votes);
+ have_qdevice = votequorum_qdevice_is_configured(&qdevice_votes);
+ (void)icmap_get_uint8("quorum.two_node", &two_node);
+
+ /*
+ * do config verification and enablement
+ */
+
+ if ((!have_nodelist) && (!expected_votes)) {
+ if (!runtime) {
+ error = (char *)"configuration error: nodelist or quorum.expected_votes must be configured!";
+ } else {
+ log_printf(LOGSYS_LEVEL_CRIT, "configuration error: nodelist or quorum.expected_votes must be configured!");
+ log_printf(LOGSYS_LEVEL_CRIT, "will continue with current runtime data");
+ }
+ goto out;
+ }
+
+ /*
+ * two_node and qdevice are not compatible in the same config.
+ * try to make an educated guess of what to do
+ */
+
+ if ((two_node) && (have_qdevice)) {
+ if (!runtime) {
+ error = (char *)"configuration error: two_node and quorum device cannot be configured at the same time!";
+ goto out;
+ } else {
+ log_printf(LOGSYS_LEVEL_CRIT, "configuration error: two_node and quorum device cannot be configured at the same time!");
+ if (us->flags & NODE_FLAGS_QDEVICE_REGISTERED) {
+ log_printf(LOGSYS_LEVEL_CRIT, "quorum device is registered, disabling two_node");
+ two_node = 0;
+ } else {
+ log_printf(LOGSYS_LEVEL_CRIT, "quorum device is not registered, allowing two_node");
+ update_qdevice_can_operate(0);
+ }
+ }
+ }
+
+ /*
+ * Enable special features
+ */
+ if (!runtime) {
+ (void)icmap_get_uint8("quorum.allow_downscale", &allow_downscale);
+ if (icmap_get_uint8("quorum.wait_for_all", &wait_for_all) != CS_OK) {
+ wait_for_all_autoset = 1;
+ }
+ (void)icmap_get_uint8("quorum.last_man_standing", &last_man_standing);
+ (void)icmap_get_uint32("quorum.last_man_standing_window", &last_man_standing_window);
+ (void)icmap_get_uint8("quorum.expected_votes_tracking", &ev_tracking);
+ (void)icmap_get_uint8("quorum.auto_tie_breaker", &atb);
+ (void)icmap_get_string("quorum.auto_tie_breaker_node", &atb_string);
+
+ /* auto_tie_breaker defaults to LOWEST */
+ if (atb) {
+ auto_tie_breaker = ATB_LOWEST;
+ icmap_set_uint32("runtime.votequorum.atb_type", auto_tie_breaker);
+ }
+ else {
+ auto_tie_breaker = ATB_NONE;
+ if (atb_string) {
+ log_printf(LOGSYS_LEVEL_WARNING,
+ "auto_tie_breaker_node: is meaningless if auto_tie_breaker is set to 0");
+ }
+ }
+
+ if (atb && atb_string) {
+ parse_atb_string(atb_string);
+ }
+ free(atb_string);
+ initial_auto_tie_breaker = auto_tie_breaker;
+
+ /* allow_downscale requires ev_tracking */
+ if (allow_downscale) {
+ ev_tracking = 1;
+ }
+
+ if (ev_tracking) {
+ if (load_ev_tracking_barrier() < 0) {
+ LEAVE();
+ return ((char *)"Unable to load ev_tracking file!");
+ }
+ update_ev_tracking_barrier(ev_tracking_barrier);
+ }
+
+ }
+
+ /*
+ * Changing of wait_for_all during runtime is not supported, but changing of two_node is
+ * and two_node may set wfa if not configured explicitly. It is safe to unset it
+ * (or set it back) when two_node changes.
+ */
+ if (wait_for_all_autoset) {
+ wait_for_all = two_node;
+ }
+
+ /* two_node and auto_tie_breaker are not compatible as two_node uses
+ * a fence race to decide quorum whereas ATB decides based on node id
+ */
+ if (two_node && auto_tie_breaker != ATB_NONE) {
+ log_printf(LOGSYS_LEVEL_CRIT, "two_node and auto_tie_breaker are both specified but are not compatible.");
+ log_printf(LOGSYS_LEVEL_CRIT, "two_node has been disabled, please fix your corosync.conf");
+ two_node = 0;
+ }
+
+ /* If ATB is set and the cluster has an odd number of nodes then wait_for_all needs
+ * to be set so that an isolated half+1 without the tie breaker node
+ * does not have quorum on reboot.
+ */
+ if ((auto_tie_breaker != ATB_NONE) && (node_expected_votes % 2) &&
+ (!wait_for_all)) {
+ if (last_man_standing) {
+ /* if LMS is set too, it's a fatal configuration error. We can't dictate to the user what
+ * they might want so we'll just quit.
+ */
+ log_printf(LOGSYS_LEVEL_CRIT, "auto_tie_breaker is set, the cluster has an odd number of nodes\n");
+ log_printf(LOGSYS_LEVEL_CRIT, "and last_man_standing is also set. With this situation a better\n");
+ log_printf(LOGSYS_LEVEL_CRIT, "solution would be to disable LMS, leave ATB enabled, and also\n");
+ log_printf(LOGSYS_LEVEL_CRIT, "enable wait_for_all (mandatory for ATB in odd-numbered clusters).\n");
+ log_printf(LOGSYS_LEVEL_CRIT, "Due to this ambiguity, corosync will fail to start. Please fix your corosync.conf\n");
+ error = (char *)"configuration error: auto_tie_breaker & last_man_standing not available in odd sized cluster";
+ goto out;
+ }
+ else {
+ log_printf(LOGSYS_LEVEL_CRIT, "auto_tie_breaker is set and the cluster has an odd number of nodes.\n");
+ log_printf(LOGSYS_LEVEL_CRIT, "wait_for_all needs to be set for this configuration but it is missing\n");
+ log_printf(LOGSYS_LEVEL_CRIT, "Therefore auto_tie_breaker has been disabled. Please fix your corosync.conf\n");
+ auto_tie_breaker = ATB_NONE;
+ icmap_set_uint32("runtime.votequorum.atb_type", auto_tie_breaker);
+ }
+ }
+
+ /*
+ * quorum device is not compatible with last_man_standing and auto_tie_breaker
+ * neither lms or atb can be set at runtime, so there is no need to check for
+ * runtime incompatibilities, but qdevice can be configured _after_ LMS and ATB have
+ * been enabled at startup.
+ */
+
+ if ((have_qdevice) && (last_man_standing)) {
+ if (!runtime) {
+ error = (char *)"configuration error: quorum.device is not compatible with last_man_standing";
+ goto out;
+ } else {
+ log_printf(LOGSYS_LEVEL_CRIT, "configuration error: quorum.device is not compatible with last_man_standing");
+ log_printf(LOGSYS_LEVEL_CRIT, "disabling quorum device operations");
+ update_qdevice_can_operate(0);
+ }
+ }
+
+ if ((have_qdevice) && (auto_tie_breaker != ATB_NONE)) {
+ if (!runtime) {
+ error = (char *)"configuration error: quorum.device is not compatible with auto_tie_breaker";
+ goto out;
+ } else {
+ log_printf(LOGSYS_LEVEL_CRIT, "configuration error: quorum.device is not compatible with auto_tie_breaker");
+ log_printf(LOGSYS_LEVEL_CRIT, "disabling quorum device operations");
+ update_qdevice_can_operate(0);
+ }
+ }
+
+ if ((have_qdevice) && (allow_downscale)) {
+ if (!runtime) {
+ error = (char *)"configuration error: quorum.device is not compatible with allow_downscale";
+ goto out;
+ } else {
+ log_printf(LOGSYS_LEVEL_CRIT, "configuration error: quorum.device is not compatible with allow_downscale");
+ log_printf(LOGSYS_LEVEL_CRIT, "disabling quorum device operations");
+ update_qdevice_can_operate(0);
+ }
+ }
+
+ /*
+ * if user specifies quorum.expected_votes + quorum.device but NOT the device.votes
+ * we don't know what the quorum device should vote.
+ */
+
+ if ((expected_votes) && (have_qdevice) && (qdevice_votes == -1)) {
+ if (!runtime) {
+ error = (char *)"configuration error: quorum.device.votes must be specified when quorum.expected_votes is set";
+ goto out;
+ } else {
+ log_printf(LOGSYS_LEVEL_CRIT, "configuration error: quorum.device.votes must be specified when quorum.expected_votes is set");
+ log_printf(LOGSYS_LEVEL_CRIT, "disabling quorum device operations");
+ update_qdevice_can_operate(0);
+ }
+ }
+
+ /*
+ * if user specifies a node list with uneven votes and no device.votes
+ * we cannot autocalculate the votes
+ */
+
+ if ((have_qdevice) &&
+ (qdevice_votes == -1) &&
+ (have_nodelist) &&
+ (node_count != node_expected_votes)) {
+ if (!runtime) {
+ error = (char *)"configuration error: quorum.device.votes must be specified when not all nodes votes 1";
+ goto out;
+ } else {
+ log_printf(LOGSYS_LEVEL_CRIT, "configuration error: quorum.device.votes must be specified when not all nodes votes 1");
+ log_printf(LOGSYS_LEVEL_CRIT, "disabling quorum device operations");
+ update_qdevice_can_operate(0);
+ }
+ }
+
+ /*
+ * validate quorum device votes vs expected_votes
+ */
+
+ if ((qdevice_votes > 0) && (expected_votes)) {
+ int delta = expected_votes - qdevice_votes;
+ if (delta < 2) {
+ if (!runtime) {
+ error = (char *)"configuration error: quorum.device.votes is too high or expected_votes is too low";
+ goto out;
+ } else {
+ log_printf(LOGSYS_LEVEL_CRIT, "configuration error: quorum.device.votes is too high or expected_votes is too low");
+ log_printf(LOGSYS_LEVEL_CRIT, "disabling quorum device operations");
+ update_qdevice_can_operate(0);
+ }
+ }
+ }
+
+ /*
+ * automatically calculate device votes and adjust expected_votes from nodelist
+ */
+
+ if ((have_qdevice) &&
+ (qdevice_votes == -1) &&
+ (!expected_votes) &&
+ (have_nodelist) &&
+ (node_count == node_expected_votes)) {
+ qdevice_votes = node_expected_votes - 1;
+ node_expected_votes = node_expected_votes + qdevice_votes;
+ }
+
+ /*
+ * set this node votes and expected_votes
+ */
+ log_printf(LOGSYS_LEVEL_DEBUG, "ev_tracking=%d, ev_tracking_barrier = %d: expected_votes = %d\n", ev_tracking, ev_tracking_barrier, expected_votes);
+
+ if (ev_tracking) {
+ expected_votes = ev_tracking_barrier;
+ }
+
+ if (have_nodelist) {
+ us->votes = node_votes;
+ us->expected_votes = node_expected_votes;
+ } else {
+ us->votes = 1;
+ (void)icmap_get_uint32("quorum.votes", &us->votes);
+ }
+
+ if (expected_votes) {
+ us->expected_votes = expected_votes;
+ }
+
+ /*
+ * set qdevice votes
+ */
+
+ if (!have_qdevice) {
+ qdevice->votes = 0;
+ }
+
+ if (qdevice_votes != -1) {
+ qdevice->votes = qdevice_votes;
+ }
+
+ update_ev_barrier(us->expected_votes);
+ update_two_node();
+ if (wait_for_all) {
+ if (!runtime) {
+ update_wait_for_all_status(1);
+ }
+ } else if (wait_for_all_autoset && wait_for_all_status) {
+ /*
+ * Reset wait for all status for consistency when wfa is auto-unset by 2node.
+ * wait_for_all_status would be ignored by are_we_quorate anyway.
+ */
+ update_wait_for_all_status(0);
+ }
+
+out:
+ LEAVE();
+ return error;
+}
+
+static void votequorum_refresh_config(
+ int32_t event,
+ const char *key_name,
+ struct icmap_notify_value new_val,
+ struct icmap_notify_value old_val,
+ void *user_data)
+{
+ int old_votes, old_expected_votes;
+ uint8_t reloading;
+ uint8_t cancel_wfa;
+ int32_t reload_status;
+
+ ENTER();
+
+ /*
+ * If a full reload is in progress then don't do anything until it's done and
+ * can reconfigure it all atomically
+ */
+ if (icmap_get_uint8("config.totemconfig_reload_in_progress", &reloading) == CS_OK && reloading) {
+ return;
+ }
+
+ /* If a full reload failed, then don't reconfigure */
+ if ( (strcmp(key_name, "config.totemconfig_reload_in_progress") == 0) &&
+ (icmap_get_int32("config.reload_status", &reload_status) == CS_OK) &&
+ (reload_status != CS_OK) ) {
+ return;
+ }
+
+ (void)icmap_get_uint8("quorum.cancel_wait_for_all", &cancel_wfa);
+ if (strcmp(key_name, "quorum.cancel_wait_for_all") == 0 &&
+ cancel_wfa >= 1) {
+ icmap_set_uint8("quorum.cancel_wait_for_all", 0);
+ if (votequorum_exec_send_reconfigure(VOTEQUORUM_RECONFIG_PARAM_CANCEL_WFA,
+ us->node_id, 0)) {
+ log_printf(LOGSYS_LEVEL_ERROR, "Failed to send Cancel WFA message to other nodes");
+ }
+ return;
+ }
+
+ old_votes = us->votes;
+ old_expected_votes = us->expected_votes;
+
+ /*
+ * Reload the configuration
+ */
+ votequorum_readconfig(VOTEQUORUM_READCONFIG_RUNTIME);
+
+ /*
+ * activate new config
+ */
+ votequorum_exec_send_nodeinfo(us->node_id);
+ votequorum_exec_send_nodeinfo(VOTEQUORUM_QDEVICE_NODEID);
+ if (us->votes != old_votes) {
+ if (votequorum_exec_send_reconfigure(VOTEQUORUM_RECONFIG_PARAM_NODE_VOTES,
+ us->node_id, us->votes)) {
+ log_printf(LOGSYS_LEVEL_ERROR, "Failed to send new votes message to other nodes");
+ }
+ }
+ if (us->expected_votes != old_expected_votes) {
+ if (votequorum_exec_send_reconfigure(VOTEQUORUM_RECONFIG_PARAM_EXPECTED_VOTES,
+ us->node_id, us->expected_votes)) {
+ log_printf(LOGSYS_LEVEL_ERROR, "Failed to send expected votes message to other nodes");
+ }
+ }
+
+ LEAVE();
+}
+
+static void votequorum_exec_add_config_notification(void)
+{
+ icmap_track_t icmap_track_nodelist = NULL;
+ icmap_track_t icmap_track_quorum = NULL;
+ icmap_track_t icmap_track_reload = NULL;
+
+ ENTER();
+
+ icmap_track_add("nodelist.",
+ ICMAP_TRACK_ADD | ICMAP_TRACK_DELETE | ICMAP_TRACK_MODIFY | ICMAP_TRACK_PREFIX,
+ votequorum_refresh_config,
+ NULL,
+ &icmap_track_nodelist);
+
+ icmap_track_add("quorum.",
+ ICMAP_TRACK_ADD | ICMAP_TRACK_DELETE | ICMAP_TRACK_MODIFY | ICMAP_TRACK_PREFIX,
+ votequorum_refresh_config,
+ NULL,
+ &icmap_track_quorum);
+
+ icmap_track_add("config.totemconfig_reload_in_progress",
+ ICMAP_TRACK_ADD | ICMAP_TRACK_MODIFY,
+ votequorum_refresh_config,
+ NULL,
+ &icmap_track_reload);
+
+ LEAVE();
+}
+
+/*
+ * votequorum_exec core
+ */
+
+static int votequorum_exec_send_reconfigure(uint8_t param, unsigned int nodeid, uint32_t value)
+{
+ struct req_exec_quorum_reconfigure req_exec_quorum_reconfigure;
+ struct iovec iov[1];
+ int ret;
+
+ ENTER();
+
+ req_exec_quorum_reconfigure.nodeid = nodeid;
+ req_exec_quorum_reconfigure.value = value;
+ req_exec_quorum_reconfigure.param = param;
+ req_exec_quorum_reconfigure._pad0 = 0;
+ req_exec_quorum_reconfigure._pad1 = 0;
+ req_exec_quorum_reconfigure._pad2 = 0;
+
+ req_exec_quorum_reconfigure.header.id = SERVICE_ID_MAKE(VOTEQUORUM_SERVICE, MESSAGE_REQ_EXEC_VOTEQUORUM_RECONFIGURE);
+ req_exec_quorum_reconfigure.header.size = sizeof(req_exec_quorum_reconfigure);
+
+ iov[0].iov_base = (void *)&req_exec_quorum_reconfigure;
+ iov[0].iov_len = sizeof(req_exec_quorum_reconfigure);
+
+ ret = corosync_api->totem_mcast (iov, 1, TOTEM_AGREED);
+
+ LEAVE();
+ return ret;
+}
+
+static int votequorum_exec_send_nodeinfo(uint32_t nodeid)
+{
+ struct req_exec_quorum_nodeinfo req_exec_quorum_nodeinfo;
+ struct iovec iov[1];
+ struct cluster_node *node;
+ int ret;
+
+ ENTER();
+
+ node = find_node_by_nodeid(nodeid);
+ if (!node) {
+ return -1;
+ }
+
+ memset(&req_exec_quorum_nodeinfo, 0, sizeof(req_exec_quorum_nodeinfo));
+ req_exec_quorum_nodeinfo.nodeid = nodeid;
+ req_exec_quorum_nodeinfo.votes = node->votes;
+ req_exec_quorum_nodeinfo.expected_votes = node->expected_votes;
+ req_exec_quorum_nodeinfo.flags = node->flags;
+ if (nodeid != VOTEQUORUM_QDEVICE_NODEID) {
+ decode_flags(node->flags);
+ }
+
+ req_exec_quorum_nodeinfo.header.id = SERVICE_ID_MAKE(VOTEQUORUM_SERVICE, MESSAGE_REQ_EXEC_VOTEQUORUM_NODEINFO);
+ req_exec_quorum_nodeinfo.header.size = sizeof(req_exec_quorum_nodeinfo);
+
+ iov[0].iov_base = (void *)&req_exec_quorum_nodeinfo;
+ iov[0].iov_len = sizeof(req_exec_quorum_nodeinfo);
+
+ ret = corosync_api->totem_mcast (iov, 1, TOTEM_AGREED);
+
+ LEAVE();
+ return ret;
+}
+
+static int votequorum_exec_send_qdevice_reconfigure(const char *oldname, const char *newname)
+{
+ struct req_exec_quorum_qdevice_reconfigure req_exec_quorum_qdevice_reconfigure;
+ struct iovec iov[1];
+ int ret;
+
+ ENTER();
+
+ req_exec_quorum_qdevice_reconfigure.header.id = SERVICE_ID_MAKE(VOTEQUORUM_SERVICE, MESSAGE_REQ_EXEC_VOTEQUORUM_QDEVICE_RECONFIGURE);
+ req_exec_quorum_qdevice_reconfigure.header.size = sizeof(req_exec_quorum_qdevice_reconfigure);
+
+ assert(strlen(oldname) < sizeof(req_exec_quorum_qdevice_reconfigure.oldname));
+ strcpy(req_exec_quorum_qdevice_reconfigure.oldname, oldname);
+
+ assert(strlen(newname) < sizeof(req_exec_quorum_qdevice_reconfigure.newname));
+ strcpy(req_exec_quorum_qdevice_reconfigure.newname, newname);
+
+ iov[0].iov_base = (void *)&req_exec_quorum_qdevice_reconfigure;
+ iov[0].iov_len = sizeof(req_exec_quorum_qdevice_reconfigure);
+
+ ret = corosync_api->totem_mcast (iov, 1, TOTEM_AGREED);
+
+ LEAVE();
+ return ret;
+}
+
+static int votequorum_exec_send_qdevice_reg(uint32_t operation, const char *qdevice_name_req)
+{
+ struct req_exec_quorum_qdevice_reg req_exec_quorum_qdevice_reg;
+ struct iovec iov[1];
+ int ret;
+
+ ENTER();
+
+ req_exec_quorum_qdevice_reg.header.id = SERVICE_ID_MAKE(VOTEQUORUM_SERVICE, MESSAGE_REQ_EXEC_VOTEQUORUM_QDEVICE_REG);
+ req_exec_quorum_qdevice_reg.header.size = sizeof(req_exec_quorum_qdevice_reg);
+ req_exec_quorum_qdevice_reg.operation = operation;
+
+ assert(strlen(qdevice_name_req) < sizeof(req_exec_quorum_qdevice_reg.qdevice_name));
+ strcpy(req_exec_quorum_qdevice_reg.qdevice_name, qdevice_name_req);
+
+ iov[0].iov_base = (void *)&req_exec_quorum_qdevice_reg;
+ iov[0].iov_len = sizeof(req_exec_quorum_qdevice_reg);
+
+ ret = corosync_api->totem_mcast (iov, 1, TOTEM_AGREED);
+
+ LEAVE();
+ return ret;
+}
+
+static int votequorum_exec_send_quorum_notification(void *conn, uint64_t context)
+{
+ struct res_lib_votequorum_quorum_notification *res_lib_votequorum_notification;
+ struct qb_list_head *tmp;
+ struct cluster_node *node;
+ int i = 0;
+ int cluster_members = 0;
+ int size;
+ char buf[sizeof(struct res_lib_votequorum_quorum_notification) + sizeof(struct votequorum_node) * (PROCESSOR_COUNT_MAX + 2)];
+
+ ENTER();
+
+ log_printf(LOGSYS_LEVEL_DEBUG, "Sending quorum callback, quorate = %d", cluster_is_quorate);
+
+ qb_list_for_each(tmp, &cluster_members_list) {
+ node = qb_list_entry(tmp, struct cluster_node, list);
+ cluster_members++;
+ }
+ if (us->flags & NODE_FLAGS_QDEVICE_REGISTERED) {
+ cluster_members++;
+ }
+
+ size = sizeof(struct res_lib_votequorum_quorum_notification) + sizeof(struct votequorum_node) * cluster_members;
+
+ res_lib_votequorum_notification = (struct res_lib_votequorum_quorum_notification *)&buf;
+ res_lib_votequorum_notification->quorate = cluster_is_quorate;
+ res_lib_votequorum_notification->context = context;
+ res_lib_votequorum_notification->node_list_entries = cluster_members;
+ res_lib_votequorum_notification->header.id = MESSAGE_RES_VOTEQUORUM_QUORUM_NOTIFICATION;
+ res_lib_votequorum_notification->header.size = size;
+ res_lib_votequorum_notification->header.error = CS_OK;
+
+ /* Send all known nodes and their states */
+ qb_list_for_each(tmp, &cluster_members_list) {
+ node = qb_list_entry(tmp, struct cluster_node, list);
+ res_lib_votequorum_notification->node_list[i].nodeid = node->node_id;
+ res_lib_votequorum_notification->node_list[i++].state = node->state;
+ }
+ if (us->flags & NODE_FLAGS_QDEVICE_REGISTERED) {
+ res_lib_votequorum_notification->node_list[i].nodeid = VOTEQUORUM_QDEVICE_NODEID;
+ res_lib_votequorum_notification->node_list[i++].state = qdevice->state;
+ }
+
+ /* Send it to all interested parties */
+ if (conn) {
+ int ret = corosync_api->ipc_dispatch_send(conn, &buf, size);
+ LEAVE();
+ return ret;
+ } else {
+ struct quorum_pd *qpd;
+
+ qb_list_for_each(tmp, &trackers_list) {
+ qpd = qb_list_entry(tmp, struct quorum_pd, list);
+ res_lib_votequorum_notification->context = qpd->tracking_context;
+ corosync_api->ipc_dispatch_send(qpd->conn, &buf, size);
+ }
+ }
+
+ LEAVE();
+
+ return 0;
+}
+
+static int votequorum_exec_send_nodelist_notification(void *conn, uint64_t context)
+{
+ struct res_lib_votequorum_nodelist_notification *res_lib_votequorum_notification;
+ int i = 0;
+ int size;
+ struct qb_list_head *tmp;
+ char buf[sizeof(struct res_lib_votequorum_nodelist_notification) + sizeof(uint32_t) * quorum_members_entries];
+
+ ENTER();
+
+ log_printf(LOGSYS_LEVEL_DEBUG, "Sending nodelist callback. ring_id = " CS_PRI_RING_ID, quorum_ringid.nodeid, quorum_ringid.seq);
+
+ size = sizeof(struct res_lib_votequorum_nodelist_notification) + sizeof(uint32_t) * quorum_members_entries;
+
+ res_lib_votequorum_notification = (struct res_lib_votequorum_nodelist_notification *)&buf;
+ res_lib_votequorum_notification->node_list_entries = quorum_members_entries;
+ res_lib_votequorum_notification->ring_id.nodeid = quorum_ringid.nodeid;
+ res_lib_votequorum_notification->ring_id.seq = quorum_ringid.seq;
+ res_lib_votequorum_notification->context = context;
+
+ for (i=0; i<quorum_members_entries; i++) {
+ res_lib_votequorum_notification->node_list[i] = quorum_members[i];
+ }
+
+ res_lib_votequorum_notification->header.id = MESSAGE_RES_VOTEQUORUM_NODELIST_NOTIFICATION;
+ res_lib_votequorum_notification->header.size = size;
+ res_lib_votequorum_notification->header.error = CS_OK;
+
+ /* Send it to all interested parties */
+ if (conn) {
+ int ret = corosync_api->ipc_dispatch_send(conn, &buf, size);
+ LEAVE();
+ return ret;
+ } else {
+ struct quorum_pd *qpd;
+
+ qb_list_for_each(tmp, &trackers_list) {
+ qpd = qb_list_entry(tmp, struct quorum_pd, list);
+ res_lib_votequorum_notification->context = qpd->tracking_context;
+ corosync_api->ipc_dispatch_send(qpd->conn, &buf, size);
+ }
+ }
+
+ LEAVE();
+
+ return 0;
+}
+
+static void votequorum_exec_send_expectedvotes_notification(void)
+{
+ struct res_lib_votequorum_expectedvotes_notification res_lib_votequorum_expectedvotes_notification;
+ struct quorum_pd *qpd;
+ struct qb_list_head *tmp;
+
+ ENTER();
+
+ log_printf(LOGSYS_LEVEL_DEBUG, "Sending expected votes callback");
+
+ res_lib_votequorum_expectedvotes_notification.header.id = MESSAGE_RES_VOTEQUORUM_EXPECTEDVOTES_NOTIFICATION;
+ res_lib_votequorum_expectedvotes_notification.header.size = sizeof(res_lib_votequorum_expectedvotes_notification);
+ res_lib_votequorum_expectedvotes_notification.header.error = CS_OK;
+ res_lib_votequorum_expectedvotes_notification.expected_votes = us->expected_votes;
+
+ qb_list_for_each(tmp, &trackers_list) {
+ qpd = qb_list_entry(tmp, struct quorum_pd, list);
+ res_lib_votequorum_expectedvotes_notification.context = qpd->tracking_context;
+ corosync_api->ipc_dispatch_send(qpd->conn, &res_lib_votequorum_expectedvotes_notification,
+ sizeof(struct res_lib_votequorum_expectedvotes_notification));
+ }
+
+ LEAVE();
+}
+
+static void exec_votequorum_qdevice_reconfigure_endian_convert (void *message)
+{
+ ENTER();
+
+ LEAVE();
+}
+
+static void message_handler_req_exec_votequorum_qdevice_reconfigure (
+ const void *message,
+ unsigned int nodeid)
+{
+ const struct req_exec_quorum_qdevice_reconfigure *req_exec_quorum_qdevice_reconfigure = message;
+
+ ENTER();
+
+ log_printf(LOGSYS_LEVEL_DEBUG, "Received qdevice name change req from node " CS_PRI_NODE_ID " [from: %s to: %s]",
+ nodeid,
+ req_exec_quorum_qdevice_reconfigure->oldname,
+ req_exec_quorum_qdevice_reconfigure->newname);
+
+ if (!strcmp(req_exec_quorum_qdevice_reconfigure->oldname, qdevice_name)) {
+ log_printf(LOGSYS_LEVEL_DEBUG, "Allowing qdevice rename");
+ memset(qdevice_name, 0, VOTEQUORUM_QDEVICE_MAX_NAME_LEN);
+ strcpy(qdevice_name, req_exec_quorum_qdevice_reconfigure->newname);
+ /*
+ * TODO: notify qdevices about name change?
+ * this is not relevant for now and can wait later on since
+ * qdevices are local only and libvotequorum is not final
+ */
+ }
+
+ LEAVE();
+}
+
+static void exec_votequorum_qdevice_reg_endian_convert (void *message)
+{
+ struct req_exec_quorum_qdevice_reg *req_exec_quorum_qdevice_reg = message;
+
+ ENTER();
+
+ req_exec_quorum_qdevice_reg->operation = swab32(req_exec_quorum_qdevice_reg->operation);
+
+ LEAVE();
+}
+
+static void message_handler_req_exec_votequorum_qdevice_reg (
+ const void *message,
+ unsigned int nodeid)
+{
+ const struct req_exec_quorum_qdevice_reg *req_exec_quorum_qdevice_reg = message;
+ struct res_lib_votequorum_status res_lib_votequorum_status;
+ int wipe_qdevice_name = 1;
+ struct cluster_node *node = NULL;
+ struct qb_list_head *tmp;
+ cs_error_t error = CS_OK;
+
+ ENTER();
+
+ log_printf(LOGSYS_LEVEL_DEBUG, "Received qdevice op %u req from node " CS_PRI_NODE_ID " [%s]",
+ req_exec_quorum_qdevice_reg->operation,
+ nodeid, req_exec_quorum_qdevice_reg->qdevice_name);
+
+ switch(req_exec_quorum_qdevice_reg->operation)
+ {
+ case VOTEQUORUM_QDEVICE_OPERATION_REGISTER:
+ if (nodeid != us->node_id) {
+ if (!strlen(qdevice_name)) {
+ log_printf(LOGSYS_LEVEL_DEBUG, "Remote qdevice name recorded");
+ strcpy(qdevice_name, req_exec_quorum_qdevice_reg->qdevice_name);
+ }
+ LEAVE();
+ return;
+ }
+
+ /*
+ * protect against the case where we broadcast qdevice registration
+ * to new memebers, we receive the message back, but there is no registration
+ * connection in progress
+ */
+ if (us->flags & NODE_FLAGS_QDEVICE_REGISTERED) {
+ LEAVE();
+ return;
+ }
+
+ /*
+ * this should NEVER happen
+ */
+ if (!qdevice_reg_conn) {
+ log_printf(LOGSYS_LEVEL_WARNING, "Unable to determine origin of the qdevice register call!");
+ LEAVE();
+ return;
+ }
+
+ /*
+ * registering our own device in this case
+ */
+ if (!strlen(qdevice_name)) {
+ strcpy(qdevice_name, req_exec_quorum_qdevice_reg->qdevice_name);
+ }
+
+ /*
+ * check if it is our device or something else
+ */
+ if ((!strncmp(req_exec_quorum_qdevice_reg->qdevice_name,
+ qdevice_name, VOTEQUORUM_QDEVICE_MAX_NAME_LEN))) {
+ us->flags |= NODE_FLAGS_QDEVICE_REGISTERED;
+ votequorum_exec_send_nodeinfo(VOTEQUORUM_QDEVICE_NODEID);
+ votequorum_exec_send_nodeinfo(us->node_id);
+ } else {
+ log_printf(LOGSYS_LEVEL_WARNING,
+ "A new qdevice with different name (new: %s old: %s) is trying to register!",
+ req_exec_quorum_qdevice_reg->qdevice_name, qdevice_name);
+ error = CS_ERR_EXIST;
+ }
+
+ res_lib_votequorum_status.header.size = sizeof(res_lib_votequorum_status);
+ res_lib_votequorum_status.header.id = MESSAGE_RES_VOTEQUORUM_STATUS;
+ res_lib_votequorum_status.header.error = error;
+ corosync_api->ipc_response_send(qdevice_reg_conn, &res_lib_votequorum_status, sizeof(res_lib_votequorum_status));
+ qdevice_reg_conn = NULL;
+ break;
+ case VOTEQUORUM_QDEVICE_OPERATION_UNREGISTER:
+ qb_list_for_each(tmp, &cluster_members_list) {
+ node = qb_list_entry(tmp, struct cluster_node, list);
+ if ((node->state == NODESTATE_MEMBER) &&
+ (node->flags & NODE_FLAGS_QDEVICE_REGISTERED)) {
+ wipe_qdevice_name = 0;
+ }
+ }
+
+ if (wipe_qdevice_name) {
+ memset(qdevice_name, 0, VOTEQUORUM_QDEVICE_MAX_NAME_LEN);
+ }
+
+ break;
+ }
+ LEAVE();
+}
+
+static void exec_votequorum_nodeinfo_endian_convert (void *message)
+{
+ struct req_exec_quorum_nodeinfo *nodeinfo = message;
+
+ ENTER();
+
+ nodeinfo->nodeid = swab32(nodeinfo->nodeid);
+ nodeinfo->votes = swab32(nodeinfo->votes);
+ nodeinfo->expected_votes = swab32(nodeinfo->expected_votes);
+ nodeinfo->flags = swab32(nodeinfo->flags);
+
+ LEAVE();
+}
+
+static void message_handler_req_exec_votequorum_nodeinfo (
+ const void *message,
+ unsigned int sender_nodeid)
+{
+ const struct req_exec_quorum_nodeinfo *req_exec_quorum_nodeinfo = message;
+ struct cluster_node *node = NULL;
+ int old_votes;
+ int old_expected;
+ uint32_t old_flags;
+ nodestate_t old_state;
+ int new_node = 0;
+ int allow_downgrade = 0;
+ int by_node = 0;
+ unsigned int nodeid = req_exec_quorum_nodeinfo->nodeid;
+
+ ENTER();
+
+ log_printf(LOGSYS_LEVEL_DEBUG, "got nodeinfo message from cluster node " CS_PRI_NODE_ID, sender_nodeid);
+ log_printf(LOGSYS_LEVEL_DEBUG, "nodeinfo message[" CS_PRI_NODE_ID "]: votes: %d, expected: %d flags: %d",
+ nodeid,
+ req_exec_quorum_nodeinfo->votes,
+ req_exec_quorum_nodeinfo->expected_votes,
+ req_exec_quorum_nodeinfo->flags);
+
+ if (nodeid != VOTEQUORUM_QDEVICE_NODEID) {
+ decode_flags(req_exec_quorum_nodeinfo->flags);
+ }
+
+ node = find_node_by_nodeid(nodeid);
+ if (!node) {
+ node = allocate_node(nodeid);
+ new_node = 1;
+ }
+ if (!node) {
+ corosync_api->error_memory_failure();
+ LEAVE();
+ return;
+ }
+
+ if (new_node) {
+ old_votes = 0;
+ old_expected = 0;
+ old_state = NODESTATE_DEAD;
+ old_flags = 0;
+ } else {
+ old_votes = node->votes;
+ old_expected = node->expected_votes;
+ old_state = node->state;
+ old_flags = node->flags;
+ }
+
+ if (nodeid == VOTEQUORUM_QDEVICE_NODEID) {
+ struct cluster_node *sender_node = find_node_by_nodeid(sender_nodeid);
+
+ assert(sender_node != NULL);
+
+ if ((!cluster_is_quorate) &&
+ (sender_node->flags & NODE_FLAGS_QUORATE)) {
+ node->votes = req_exec_quorum_nodeinfo->votes;
+ } else {
+ node->votes = max(node->votes, req_exec_quorum_nodeinfo->votes);
+ }
+ goto recalculate;
+ }
+
+ /* Update node state */
+ node->flags = req_exec_quorum_nodeinfo->flags;
+ node->votes = req_exec_quorum_nodeinfo->votes;
+ node->state = NODESTATE_MEMBER;
+
+ if (node->flags & NODE_FLAGS_LEAVING) {
+ node->state = NODESTATE_LEAVING;
+ allow_downgrade = 1;
+ by_node = 1;
+ }
+
+ if ((!cluster_is_quorate) &&
+ (node->flags & NODE_FLAGS_QUORATE)) {
+ allow_downgrade = 1;
+ us->expected_votes = req_exec_quorum_nodeinfo->expected_votes;
+ }
+
+ if (node->flags & NODE_FLAGS_QUORATE || (ev_tracking)) {
+ node->expected_votes = req_exec_quorum_nodeinfo->expected_votes;
+ } else {
+ node->expected_votes = us->expected_votes;
+ }
+
+ if ((last_man_standing) && (node->votes > 1)) {
+ log_printf(LOGSYS_LEVEL_WARNING, "Last Man Standing feature is supported only when all"
+ "cluster nodes votes are set to 1. Disabling LMS.");
+ last_man_standing = 0;
+ if (last_man_standing_timer_set) {
+ corosync_api->timer_delete(last_man_standing_timer);
+ last_man_standing_timer_set = 0;
+ }
+ }
+
+recalculate:
+ if ((new_node) ||
+ (nodeid == us->node_id) ||
+ (node->flags & NODE_FLAGS_FIRST) ||
+ (old_votes != node->votes) ||
+ (old_expected != node->expected_votes) ||
+ (old_flags != node->flags) ||
+ (old_state != node->state)) {
+ recalculate_quorum(allow_downgrade, by_node);
+ }
+
+ if ((wait_for_all) &&
+ (!(node->flags & NODE_FLAGS_WFASTATUS)) &&
+ (node->flags & NODE_FLAGS_QUORATE)) {
+ update_wait_for_all_status(0);
+ }
+
+ LEAVE();
+}
+
+static void exec_votequorum_reconfigure_endian_convert (void *message)
+{
+ struct req_exec_quorum_reconfigure *reconfigure = message;
+
+ ENTER();
+
+ reconfigure->nodeid = swab32(reconfigure->nodeid);
+ reconfigure->value = swab32(reconfigure->value);
+
+ LEAVE();
+}
+
+static void message_handler_req_exec_votequorum_reconfigure (
+ const void *message,
+ unsigned int nodeid)
+{
+ const struct req_exec_quorum_reconfigure *req_exec_quorum_reconfigure = message;
+ struct cluster_node *node;
+
+ ENTER();
+
+ log_printf(LOGSYS_LEVEL_DEBUG, "got reconfigure message from cluster node " CS_PRI_NODE_ID " for " CS_PRI_NODE_ID,
+ nodeid, req_exec_quorum_reconfigure->nodeid);
+
+ switch(req_exec_quorum_reconfigure->param)
+ {
+ case VOTEQUORUM_RECONFIG_PARAM_EXPECTED_VOTES:
+ update_node_expected_votes(req_exec_quorum_reconfigure->value);
+ votequorum_exec_send_expectedvotes_notification();
+ update_ev_barrier(req_exec_quorum_reconfigure->value);
+ if (ev_tracking) {
+ us->expected_votes = max(us->expected_votes, ev_tracking_barrier);
+ }
+ recalculate_quorum(1, 0); /* Allow decrease */
+ break;
+
+ case VOTEQUORUM_RECONFIG_PARAM_NODE_VOTES:
+ node = find_node_by_nodeid(req_exec_quorum_reconfigure->nodeid);
+ if (!node) {
+ LEAVE();
+ return;
+ }
+ node->votes = req_exec_quorum_reconfigure->value;
+ recalculate_quorum(1, 0); /* Allow decrease */
+ break;
+
+ case VOTEQUORUM_RECONFIG_PARAM_CANCEL_WFA:
+ update_wait_for_all_status(0);
+ log_printf(LOGSYS_LEVEL_INFO, "wait_for_all_status reset by user on node " CS_PRI_NODE_ID ".",
+ req_exec_quorum_reconfigure->nodeid);
+ recalculate_quorum(0, 0);
+
+ break;
+
+ }
+
+ LEAVE();
+}
+
+static int votequorum_exec_exit_fn (void)
+{
+ int ret = 0;
+
+ ENTER();
+
+ /*
+ * tell the other nodes we are leaving
+ */
+
+ if (allow_downscale) {
+ us->flags |= NODE_FLAGS_LEAVING;
+ ret = votequorum_exec_send_nodeinfo(us->node_id);
+ }
+
+ if ((ev_tracking) && (ev_tracking_fd != -1)) {
+ close(ev_tracking_fd);
+ }
+
+
+ LEAVE();
+ return ret;
+}
+
+static void votequorum_set_icmap_ro_keys(void)
+{
+ icmap_set_ro_access("quorum.allow_downscale", CS_FALSE, CS_TRUE);
+ icmap_set_ro_access("quorum.wait_for_all", CS_FALSE, CS_TRUE);
+ icmap_set_ro_access("quorum.last_man_standing", CS_FALSE, CS_TRUE);
+ icmap_set_ro_access("quorum.last_man_standing_window", CS_FALSE, CS_TRUE);
+ icmap_set_ro_access("quorum.expected_votes_tracking", CS_FALSE, CS_TRUE);
+ icmap_set_ro_access("quorum.auto_tie_breaker", CS_FALSE, CS_TRUE);
+ icmap_set_ro_access("quorum.auto_tie_breaker_node", CS_FALSE, CS_TRUE);
+}
+
+static char *votequorum_exec_init_fn (struct corosync_api_v1 *api)
+{
+ char *error = NULL;
+
+ ENTER();
+
+ /*
+ * make sure we start clean
+ */
+ qb_list_init(&cluster_members_list);
+ qb_list_init(&trackers_list);
+ qdevice = NULL;
+ us = NULL;
+ memset(cluster_nodes, 0, sizeof(cluster_nodes));
+
+ /*
+ * Allocate a cluster_node for qdevice
+ */
+ qdevice = allocate_node(VOTEQUORUM_QDEVICE_NODEID);
+ if (!qdevice) {
+ LEAVE();
+ return ((char *)"Could not allocate node.");
+ }
+ qdevice->votes = 0;
+ memset(qdevice_name, 0, VOTEQUORUM_QDEVICE_MAX_NAME_LEN);
+
+ /*
+ * Allocate a cluster_node for us
+ */
+ us = allocate_node(corosync_api->totem_nodeid_get());
+ if (!us) {
+ LEAVE();
+ return ((char *)"Could not allocate node.");
+ }
+
+ icmap_set_uint32("runtime.votequorum.this_node_id", us->node_id);
+
+ us->state = NODESTATE_MEMBER;
+ us->votes = 1;
+ us->flags |= NODE_FLAGS_FIRST;
+
+ error = votequorum_readconfig(VOTEQUORUM_READCONFIG_STARTUP);
+ if (error) {
+ return error;
+ }
+ recalculate_quorum(0, 0);
+
+ /*
+ * Set RO keys in icmap
+ */
+ votequorum_set_icmap_ro_keys();
+
+ /*
+ * Listen for changes
+ */
+ votequorum_exec_add_config_notification();
+
+ /*
+ * Start us off with one node
+ */
+ votequorum_exec_send_nodeinfo(us->node_id);
+
+ LEAVE();
+
+ return (NULL);
+}
+
+/*
+ * votequorum service core
+ */
+
+static void votequorum_last_man_standing_timer_fn(void *arg)
+{
+ ENTER();
+
+ last_man_standing_timer_set = 0;
+ if (cluster_is_quorate) {
+ recalculate_quorum(1,1);
+ }
+
+ LEAVE();
+}
+
+static void votequorum_sync_init (
+ const unsigned int *trans_list, size_t trans_list_entries,
+ const unsigned int *member_list, size_t member_list_entries,
+ const struct memb_ring_id *ring_id)
+{
+ int i, j;
+ int found;
+ int left_nodes;
+ struct cluster_node *node;
+
+ ENTER();
+
+ sync_in_progress = 1;
+ sync_nodeinfo_sent = 0;
+ sync_wait_for_poll_or_timeout = 0;
+
+ if (member_list_entries > 1) {
+ us->flags &= ~NODE_FLAGS_FIRST;
+ }
+
+ /*
+ * we don't need to track which nodes have left directly,
+ * since that info is in the node db, but we need to know
+ * if somebody has left for last_man_standing
+ */
+ left_nodes = 0;
+ for (i = 0; i < quorum_members_entries; i++) {
+ found = 0;
+ for (j = 0; j < member_list_entries; j++) {
+ if (quorum_members[i] == member_list[j]) {
+ found = 1;
+ break;
+ }
+ }
+ if (found == 0) {
+ left_nodes = 1;
+ node = find_node_by_nodeid(quorum_members[i]);
+ if (node) {
+ node->state = NODESTATE_DEAD;
+ }
+ }
+ }
+
+ if (last_man_standing) {
+ if (((member_list_entries >= quorum) && (left_nodes)) ||
+ ((member_list_entries <= quorum) && (auto_tie_breaker != ATB_NONE) && (check_low_node_id_partition() == 1))) {
+ if (last_man_standing_timer_set) {
+ corosync_api->timer_delete(last_man_standing_timer);
+ last_man_standing_timer_set = 0;
+ }
+ corosync_api->timer_add_duration((unsigned long long)last_man_standing_window*1000000,
+ NULL, votequorum_last_man_standing_timer_fn,
+ &last_man_standing_timer);
+ last_man_standing_timer_set = 1;
+ }
+ }
+
+ memcpy(previous_quorum_members, quorum_members, sizeof(unsigned int) * quorum_members_entries);
+ previous_quorum_members_entries = quorum_members_entries;
+
+ memcpy(quorum_members, member_list, sizeof(unsigned int) * member_list_entries);
+ quorum_members_entries = member_list_entries;
+ memcpy(&quorum_ringid, ring_id, sizeof(*ring_id));
+
+ if (us->flags & NODE_FLAGS_QDEVICE_REGISTERED && us->flags & NODE_FLAGS_QDEVICE_ALIVE) {
+ /*
+ * Reset poll timer. Sync waiting is interrupted on valid qdevice poll or after timeout
+ */
+ if (qdevice_timer_set) {
+ corosync_api->timer_delete(qdevice_timer);
+ }
+ corosync_api->timer_add_duration((unsigned long long)qdevice_sync_timeout*1000000, qdevice,
+ qdevice_timer_fn, &qdevice_timer);
+ qdevice_timer_set = 1;
+ sync_wait_for_poll_or_timeout = 1;
+
+ log_printf(LOGSYS_LEVEL_INFO, "waiting for quorum device %s poll (but maximum for %u ms)",
+ qdevice_name, qdevice_sync_timeout);
+ }
+
+ LEAVE();
+}
+
+static int votequorum_sync_process (void)
+{
+ if (!sync_nodeinfo_sent) {
+ votequorum_exec_send_nodeinfo(us->node_id);
+ votequorum_exec_send_nodeinfo(VOTEQUORUM_QDEVICE_NODEID);
+ if (strlen(qdevice_name)) {
+ votequorum_exec_send_qdevice_reg(VOTEQUORUM_QDEVICE_OPERATION_REGISTER,
+ qdevice_name);
+ }
+ votequorum_exec_send_nodelist_notification(NULL, 0LL);
+ sync_nodeinfo_sent = 1;
+ }
+
+ if (us->flags & NODE_FLAGS_QDEVICE_REGISTERED && sync_wait_for_poll_or_timeout) {
+ /*
+ * Waiting for qdevice to poll with new ringid or timeout
+ */
+
+ return (-1);
+ }
+
+ return 0;
+}
+
+static void votequorum_sync_activate (void)
+{
+ recalculate_quorum(0, 0);
+ quorum_callback(quorum_members, quorum_members_entries,
+ cluster_is_quorate, &quorum_ringid);
+ votequorum_exec_send_quorum_notification(NULL, 0L);
+
+ sync_in_progress = 0;
+}
+
+static void votequorum_sync_abort (void)
+{
+
+}
+
+char *votequorum_init(struct corosync_api_v1 *api,
+ quorum_set_quorate_fn_t q_set_quorate_fn)
+{
+ char *error;
+
+ ENTER();
+
+ if (q_set_quorate_fn == NULL) {
+ return ((char *)"Quorate function not set");
+ }
+
+ corosync_api = api;
+ quorum_callback = q_set_quorate_fn;
+
+ error = corosync_service_link_and_init(corosync_api,
+ &votequorum_service[0]);
+ if (error) {
+ return (error);
+ }
+
+ LEAVE();
+
+ return (NULL);
+}
+
+/*
+ * Library Handler init/fini
+ */
+
+static int quorum_lib_init_fn (void *conn)
+{
+ struct quorum_pd *pd = (struct quorum_pd *)corosync_api->ipc_private_data_get (conn);
+
+ ENTER();
+
+ qb_list_init (&pd->list);
+ pd->conn = conn;
+
+ LEAVE();
+ return (0);
+}
+
+static int quorum_lib_exit_fn (void *conn)
+{
+ struct quorum_pd *quorum_pd = (struct quorum_pd *)corosync_api->ipc_private_data_get (conn);
+
+ ENTER();
+
+ if (quorum_pd->tracking_enabled) {
+ qb_list_del (&quorum_pd->list);
+ qb_list_init (&quorum_pd->list);
+ }
+
+ LEAVE();
+
+ return (0);
+}
+
+/*
+ * library internal functions
+ */
+
+static void qdevice_timer_fn(void *arg)
+{
+ ENTER();
+
+ if ((!(us->flags & NODE_FLAGS_QDEVICE_ALIVE)) ||
+ (!qdevice_timer_set)) {
+ LEAVE();
+ return;
+ }
+
+ us->flags &= ~NODE_FLAGS_QDEVICE_ALIVE;
+ us->flags &= ~NODE_FLAGS_QDEVICE_CAST_VOTE;
+ log_printf(LOGSYS_LEVEL_INFO, "lost contact with quorum device %s", qdevice_name);
+ votequorum_exec_send_nodeinfo(us->node_id);
+
+ qdevice_timer_set = 0;
+ sync_wait_for_poll_or_timeout = 0;
+
+ LEAVE();
+}
+
+/*
+ * Library Handler Functions
+ */
+
+static void message_handler_req_lib_votequorum_getinfo (void *conn, const void *message)
+{
+ const struct req_lib_votequorum_getinfo *req_lib_votequorum_getinfo = message;
+ struct res_lib_votequorum_getinfo res_lib_votequorum_getinfo;
+ struct cluster_node *node;
+ unsigned int highest_expected = 0;
+ unsigned int total_votes = 0;
+ cs_error_t error = CS_OK;
+ uint32_t nodeid = req_lib_votequorum_getinfo->nodeid;
+
+ ENTER();
+
+ log_printf(LOGSYS_LEVEL_DEBUG, "got getinfo request on %p for node " CS_PRI_NODE_ID, conn, req_lib_votequorum_getinfo->nodeid);
+
+ if (nodeid == VOTEQUORUM_QDEVICE_NODEID) {
+ nodeid = us->node_id;
+ }
+
+ node = find_node_by_nodeid(nodeid);
+ if (node) {
+ struct cluster_node *iternode;
+ struct qb_list_head *nodelist;
+
+ qb_list_for_each(nodelist, &cluster_members_list) {
+ iternode = qb_list_entry(nodelist, struct cluster_node, list);
+
+ if (iternode->state == NODESTATE_MEMBER) {
+ highest_expected =
+ max(highest_expected, iternode->expected_votes);
+ total_votes += iternode->votes;
+ }
+ }
+
+ if (node->flags & NODE_FLAGS_QDEVICE_CAST_VOTE) {
+ total_votes += qdevice->votes;
+ }
+
+ switch(node->state) {
+ case NODESTATE_MEMBER:
+ res_lib_votequorum_getinfo.state = VOTEQUORUM_NODESTATE_MEMBER;
+ break;
+ case NODESTATE_DEAD:
+ res_lib_votequorum_getinfo.state = VOTEQUORUM_NODESTATE_DEAD;
+ break;
+ case NODESTATE_LEAVING:
+ res_lib_votequorum_getinfo.state = VOTEQUORUM_NODESTATE_LEAVING;
+ break;
+ default:
+ res_lib_votequorum_getinfo.state = node->state;
+ break;
+ }
+ res_lib_votequorum_getinfo.state = node->state;
+ res_lib_votequorum_getinfo.votes = node->votes;
+ res_lib_votequorum_getinfo.expected_votes = node->expected_votes;
+ res_lib_votequorum_getinfo.highest_expected = highest_expected;
+
+ res_lib_votequorum_getinfo.quorum = quorum;
+ res_lib_votequorum_getinfo.total_votes = total_votes;
+ res_lib_votequorum_getinfo.flags = 0;
+ res_lib_votequorum_getinfo.nodeid = node->node_id;
+
+ if (two_node) {
+ res_lib_votequorum_getinfo.flags |= VOTEQUORUM_INFO_TWONODE;
+ }
+ if (cluster_is_quorate) {
+ res_lib_votequorum_getinfo.flags |= VOTEQUORUM_INFO_QUORATE;
+ }
+ if (wait_for_all) {
+ res_lib_votequorum_getinfo.flags |= VOTEQUORUM_INFO_WAIT_FOR_ALL;
+ }
+ if (last_man_standing) {
+ res_lib_votequorum_getinfo.flags |= VOTEQUORUM_INFO_LAST_MAN_STANDING;
+ }
+ if (auto_tie_breaker != ATB_NONE) {
+ res_lib_votequorum_getinfo.flags |= VOTEQUORUM_INFO_AUTO_TIE_BREAKER;
+ }
+ if (allow_downscale) {
+ res_lib_votequorum_getinfo.flags |= VOTEQUORUM_INFO_ALLOW_DOWNSCALE;
+ }
+
+ memset(res_lib_votequorum_getinfo.qdevice_name, 0, VOTEQUORUM_QDEVICE_MAX_NAME_LEN);
+ strcpy(res_lib_votequorum_getinfo.qdevice_name, qdevice_name);
+ res_lib_votequorum_getinfo.qdevice_votes = qdevice->votes;
+
+ if (node->flags & NODE_FLAGS_QDEVICE_REGISTERED) {
+ res_lib_votequorum_getinfo.flags |= VOTEQUORUM_INFO_QDEVICE_REGISTERED;
+ }
+ if (node->flags & NODE_FLAGS_QDEVICE_ALIVE) {
+ res_lib_votequorum_getinfo.flags |= VOTEQUORUM_INFO_QDEVICE_ALIVE;
+ }
+ if (node->flags & NODE_FLAGS_QDEVICE_CAST_VOTE) {
+ res_lib_votequorum_getinfo.flags |= VOTEQUORUM_INFO_QDEVICE_CAST_VOTE;
+ }
+ if (node->flags & NODE_FLAGS_QDEVICE_MASTER_WINS) {
+ res_lib_votequorum_getinfo.flags |= VOTEQUORUM_INFO_QDEVICE_MASTER_WINS;
+ }
+ } else {
+ error = CS_ERR_NOT_EXIST;
+ }
+
+ res_lib_votequorum_getinfo.header.size = sizeof(res_lib_votequorum_getinfo);
+ res_lib_votequorum_getinfo.header.id = MESSAGE_RES_VOTEQUORUM_GETINFO;
+ res_lib_votequorum_getinfo.header.error = error;
+ corosync_api->ipc_response_send(conn, &res_lib_votequorum_getinfo, sizeof(res_lib_votequorum_getinfo));
+ log_printf(LOGSYS_LEVEL_DEBUG, "getinfo response error: %d", error);
+
+ LEAVE();
+}
+
+static void message_handler_req_lib_votequorum_setexpected (void *conn, const void *message)
+{
+ const struct req_lib_votequorum_setexpected *req_lib_votequorum_setexpected = message;
+ struct res_lib_votequorum_status res_lib_votequorum_status;
+ cs_error_t error = CS_OK;
+ unsigned int newquorum;
+ unsigned int total_votes;
+ uint8_t allow_downscale_status = 0;
+
+ ENTER();
+
+ allow_downscale_status = allow_downscale;
+ allow_downscale = 0;
+
+ /*
+ * Validate new expected votes
+ */
+ newquorum = calculate_quorum(1, req_lib_votequorum_setexpected->expected_votes, &total_votes);
+ allow_downscale = allow_downscale_status;
+ /*
+ * Setting expected_votes < total_votes doesn't make sense.
+ * For quorate cluster prevent cluster to become unquorate.
+ */
+ if (req_lib_votequorum_setexpected->expected_votes < total_votes ||
+ (cluster_is_quorate && (newquorum > total_votes))) {
+ error = CS_ERR_INVALID_PARAM;
+ goto error_exit;
+ }
+ update_node_expected_votes(req_lib_votequorum_setexpected->expected_votes);
+
+ if (votequorum_exec_send_reconfigure(VOTEQUORUM_RECONFIG_PARAM_EXPECTED_VOTES, us->node_id,
+ req_lib_votequorum_setexpected->expected_votes)) {
+ error = CS_ERR_NO_RESOURCES;
+ }
+
+error_exit:
+ res_lib_votequorum_status.header.size = sizeof(res_lib_votequorum_status);
+ res_lib_votequorum_status.header.id = MESSAGE_RES_VOTEQUORUM_STATUS;
+ res_lib_votequorum_status.header.error = error;
+ corosync_api->ipc_response_send(conn, &res_lib_votequorum_status, sizeof(res_lib_votequorum_status));
+
+ LEAVE();
+}
+
+static void message_handler_req_lib_votequorum_setvotes (void *conn, const void *message)
+{
+ const struct req_lib_votequorum_setvotes *req_lib_votequorum_setvotes = message;
+ struct res_lib_votequorum_status res_lib_votequorum_status;
+ struct cluster_node *node;
+ unsigned int newquorum;
+ unsigned int total_votes;
+ unsigned int saved_votes;
+ cs_error_t error = CS_OK;
+ unsigned int nodeid;
+
+ ENTER();
+
+ nodeid = req_lib_votequorum_setvotes->nodeid;
+ node = find_node_by_nodeid(nodeid);
+ if (!node) {
+ error = CS_ERR_NAME_NOT_FOUND;
+ goto error_exit;
+ }
+
+ /*
+ * Check votes is valid
+ */
+ saved_votes = node->votes;
+ node->votes = req_lib_votequorum_setvotes->votes;
+
+ newquorum = calculate_quorum(1, 0, &total_votes);
+
+ if (newquorum < total_votes / 2 ||
+ newquorum > total_votes) {
+ node->votes = saved_votes;
+ error = CS_ERR_INVALID_PARAM;
+ goto error_exit;
+ }
+
+ if (votequorum_exec_send_reconfigure(VOTEQUORUM_RECONFIG_PARAM_NODE_VOTES, nodeid,
+ req_lib_votequorum_setvotes->votes)) {
+ error = CS_ERR_NO_RESOURCES;
+ }
+
+error_exit:
+ res_lib_votequorum_status.header.size = sizeof(res_lib_votequorum_status);
+ res_lib_votequorum_status.header.id = MESSAGE_RES_VOTEQUORUM_STATUS;
+ res_lib_votequorum_status.header.error = error;
+ corosync_api->ipc_response_send(conn, &res_lib_votequorum_status, sizeof(res_lib_votequorum_status));
+
+ LEAVE();
+}
+
+static void message_handler_req_lib_votequorum_trackstart (void *conn,
+ const void *message)
+{
+ const struct req_lib_votequorum_trackstart *req_lib_votequorum_trackstart = message;
+ struct res_lib_votequorum_status res_lib_votequorum_status;
+ struct quorum_pd *quorum_pd = (struct quorum_pd *)corosync_api->ipc_private_data_get (conn);
+ cs_error_t error = CS_OK;
+
+ ENTER();
+
+ /*
+ * If an immediate listing of the current cluster membership
+ * is requested, generate membership list
+ */
+ if (req_lib_votequorum_trackstart->track_flags & CS_TRACK_CURRENT ||
+ req_lib_votequorum_trackstart->track_flags & CS_TRACK_CHANGES) {
+ log_printf(LOGSYS_LEVEL_DEBUG, "sending initial status to %p", conn);
+ votequorum_exec_send_nodelist_notification(conn, req_lib_votequorum_trackstart->context);
+ votequorum_exec_send_quorum_notification(conn, req_lib_votequorum_trackstart->context);
+ }
+
+ if (quorum_pd->tracking_enabled) {
+ error = CS_ERR_EXIST;
+ goto response_send;
+ }
+
+ /*
+ * Record requests for tracking
+ */
+ if (req_lib_votequorum_trackstart->track_flags & CS_TRACK_CHANGES ||
+ req_lib_votequorum_trackstart->track_flags & CS_TRACK_CHANGES_ONLY) {
+
+ quorum_pd->track_flags = req_lib_votequorum_trackstart->track_flags;
+ quorum_pd->tracking_enabled = 1;
+ quorum_pd->tracking_context = req_lib_votequorum_trackstart->context;
+
+ qb_list_add (&quorum_pd->list, &trackers_list);
+ }
+
+response_send:
+ res_lib_votequorum_status.header.size = sizeof(res_lib_votequorum_status);
+ res_lib_votequorum_status.header.id = MESSAGE_RES_VOTEQUORUM_STATUS;
+ res_lib_votequorum_status.header.error = error;
+ corosync_api->ipc_response_send(conn, &res_lib_votequorum_status, sizeof(res_lib_votequorum_status));
+
+ LEAVE();
+}
+
+static void message_handler_req_lib_votequorum_trackstop (void *conn,
+ const void *message)
+{
+ struct res_lib_votequorum_status res_lib_votequorum_status;
+ struct quorum_pd *quorum_pd = (struct quorum_pd *)corosync_api->ipc_private_data_get (conn);
+ int error = CS_OK;
+
+ ENTER();
+
+ if (quorum_pd->tracking_enabled) {
+ error = CS_OK;
+ quorum_pd->tracking_enabled = 0;
+ qb_list_del (&quorum_pd->list);
+ qb_list_init (&quorum_pd->list);
+ } else {
+ error = CS_ERR_NOT_EXIST;
+ }
+
+ res_lib_votequorum_status.header.size = sizeof(res_lib_votequorum_status);
+ res_lib_votequorum_status.header.id = MESSAGE_RES_VOTEQUORUM_STATUS;
+ res_lib_votequorum_status.header.error = error;
+ corosync_api->ipc_response_send(conn, &res_lib_votequorum_status, sizeof(res_lib_votequorum_status));
+
+ LEAVE();
+}
+
+static void message_handler_req_lib_votequorum_qdevice_register (void *conn,
+ const void *message)
+{
+ const struct req_lib_votequorum_qdevice_register *req_lib_votequorum_qdevice_register = message;
+ struct res_lib_votequorum_status res_lib_votequorum_status;
+ cs_error_t error = CS_OK;
+
+ ENTER();
+
+ if (!qdevice_can_operate) {
+ log_printf(LOGSYS_LEVEL_INFO, "Registration of quorum device is disabled by incorrect corosync.conf. See logs for more information");
+ error = CS_ERR_ACCESS;
+ goto out;
+ }
+
+ if (us->flags & NODE_FLAGS_QDEVICE_REGISTERED) {
+ if ((!strncmp(req_lib_votequorum_qdevice_register->name,
+ qdevice_name, VOTEQUORUM_QDEVICE_MAX_NAME_LEN))) {
+ goto out;
+ } else {
+ log_printf(LOGSYS_LEVEL_WARNING,
+ "A new qdevice with different name (new: %s old: %s) is trying to re-register!",
+ req_lib_votequorum_qdevice_register->name, qdevice_name);
+ error = CS_ERR_EXIST;
+ goto out;
+ }
+ } else {
+ if (qdevice_reg_conn != NULL) {
+ log_printf(LOGSYS_LEVEL_WARNING,
+ "Registration request already in progress");
+ error = CS_ERR_TRY_AGAIN;
+ goto out;
+ }
+ qdevice_reg_conn = conn;
+ if (votequorum_exec_send_qdevice_reg(VOTEQUORUM_QDEVICE_OPERATION_REGISTER,
+ req_lib_votequorum_qdevice_register->name) != 0) {
+ log_printf(LOGSYS_LEVEL_WARNING,
+ "Unable to send qdevice registration request to cluster");
+ error = CS_ERR_TRY_AGAIN;
+ qdevice_reg_conn = NULL;
+ } else {
+ LEAVE();
+ return;
+ }
+ }
+
+out:
+
+ res_lib_votequorum_status.header.size = sizeof(res_lib_votequorum_status);
+ res_lib_votequorum_status.header.id = MESSAGE_RES_VOTEQUORUM_STATUS;
+ res_lib_votequorum_status.header.error = error;
+ corosync_api->ipc_response_send(conn, &res_lib_votequorum_status, sizeof(res_lib_votequorum_status));
+
+ LEAVE();
+}
+
+static void message_handler_req_lib_votequorum_qdevice_unregister (void *conn,
+ const void *message)
+{
+ const struct req_lib_votequorum_qdevice_unregister *req_lib_votequorum_qdevice_unregister = message;
+ struct res_lib_votequorum_status res_lib_votequorum_status;
+ cs_error_t error = CS_OK;
+
+ ENTER();
+
+ if (us->flags & NODE_FLAGS_QDEVICE_REGISTERED) {
+ if (strncmp(req_lib_votequorum_qdevice_unregister->name, qdevice_name, VOTEQUORUM_QDEVICE_MAX_NAME_LEN)) {
+ error = CS_ERR_INVALID_PARAM;
+ goto out;
+ }
+ if (qdevice_timer_set) {
+ corosync_api->timer_delete(qdevice_timer);
+ qdevice_timer_set = 0;
+ sync_wait_for_poll_or_timeout = 0;
+ }
+ us->flags &= ~NODE_FLAGS_QDEVICE_REGISTERED;
+ us->flags &= ~NODE_FLAGS_QDEVICE_ALIVE;
+ us->flags &= ~NODE_FLAGS_QDEVICE_CAST_VOTE;
+ us->flags &= ~NODE_FLAGS_QDEVICE_MASTER_WINS;
+ votequorum_exec_send_nodeinfo(us->node_id);
+ votequorum_exec_send_qdevice_reg(VOTEQUORUM_QDEVICE_OPERATION_UNREGISTER,
+ req_lib_votequorum_qdevice_unregister->name);
+ } else {
+ error = CS_ERR_NOT_EXIST;
+ }
+
+out:
+ res_lib_votequorum_status.header.size = sizeof(res_lib_votequorum_status);
+ res_lib_votequorum_status.header.id = MESSAGE_RES_VOTEQUORUM_STATUS;
+ res_lib_votequorum_status.header.error = error;
+ corosync_api->ipc_response_send(conn, &res_lib_votequorum_status, sizeof(res_lib_votequorum_status));
+
+ LEAVE();
+}
+
+static void message_handler_req_lib_votequorum_qdevice_update (void *conn,
+ const void *message)
+{
+ const struct req_lib_votequorum_qdevice_update *req_lib_votequorum_qdevice_update = message;
+ struct res_lib_votequorum_status res_lib_votequorum_status;
+ cs_error_t error = CS_OK;
+
+ ENTER();
+
+ if (us->flags & NODE_FLAGS_QDEVICE_REGISTERED) {
+ if (strncmp(req_lib_votequorum_qdevice_update->oldname, qdevice_name, VOTEQUORUM_QDEVICE_MAX_NAME_LEN)) {
+ error = CS_ERR_INVALID_PARAM;
+ goto out;
+ }
+ votequorum_exec_send_qdevice_reconfigure(req_lib_votequorum_qdevice_update->oldname,
+ req_lib_votequorum_qdevice_update->newname);
+ } else {
+ error = CS_ERR_NOT_EXIST;
+ }
+
+out:
+ res_lib_votequorum_status.header.size = sizeof(res_lib_votequorum_status);
+ res_lib_votequorum_status.header.id = MESSAGE_RES_VOTEQUORUM_STATUS;
+ res_lib_votequorum_status.header.error = error;
+ corosync_api->ipc_response_send(conn, &res_lib_votequorum_status, sizeof(res_lib_votequorum_status));
+
+ LEAVE();
+}
+
+static void message_handler_req_lib_votequorum_qdevice_poll (void *conn,
+ const void *message)
+{
+ const struct req_lib_votequorum_qdevice_poll *req_lib_votequorum_qdevice_poll = message;
+ struct res_lib_votequorum_status res_lib_votequorum_status;
+ cs_error_t error = CS_OK;
+ uint32_t oldflags;
+
+ ENTER();
+
+ if (!qdevice_can_operate) {
+ error = CS_ERR_ACCESS;
+ goto out;
+ }
+
+ if (us->flags & NODE_FLAGS_QDEVICE_REGISTERED) {
+ if (!(req_lib_votequorum_qdevice_poll->ring_id.nodeid == quorum_ringid.nodeid &&
+ req_lib_votequorum_qdevice_poll->ring_id.seq == quorum_ringid.seq)) {
+ log_printf(LOGSYS_LEVEL_DEBUG, "Received poll ring id (" CS_PRI_RING_ID ") != last sync "
+ "ring id (" CS_PRI_RING_ID "). Ignoring poll call.",
+ req_lib_votequorum_qdevice_poll->ring_id.nodeid, req_lib_votequorum_qdevice_poll->ring_id.seq,
+ quorum_ringid.nodeid, quorum_ringid.seq);
+ error = CS_ERR_MESSAGE_ERROR;
+ goto out;
+ }
+ if (strncmp(req_lib_votequorum_qdevice_poll->name, qdevice_name, VOTEQUORUM_QDEVICE_MAX_NAME_LEN)) {
+ error = CS_ERR_INVALID_PARAM;
+ goto out;
+ }
+
+ if (qdevice_timer_set) {
+ corosync_api->timer_delete(qdevice_timer);
+ qdevice_timer_set = 0;
+ }
+
+ oldflags = us->flags;
+
+ us->flags |= NODE_FLAGS_QDEVICE_ALIVE;
+
+ if (req_lib_votequorum_qdevice_poll->cast_vote) {
+ us->flags |= NODE_FLAGS_QDEVICE_CAST_VOTE;
+ } else {
+ us->flags &= ~NODE_FLAGS_QDEVICE_CAST_VOTE;
+ }
+
+ if (us->flags != oldflags) {
+ votequorum_exec_send_nodeinfo(us->node_id);
+ }
+
+ corosync_api->timer_add_duration((unsigned long long)qdevice_timeout*1000000, qdevice,
+ qdevice_timer_fn, &qdevice_timer);
+ qdevice_timer_set = 1;
+ sync_wait_for_poll_or_timeout = 0;
+ } else {
+ error = CS_ERR_NOT_EXIST;
+ }
+
+out:
+ res_lib_votequorum_status.header.size = sizeof(res_lib_votequorum_status);
+ res_lib_votequorum_status.header.id = MESSAGE_RES_VOTEQUORUM_STATUS;
+ res_lib_votequorum_status.header.error = error;
+ corosync_api->ipc_response_send(conn, &res_lib_votequorum_status, sizeof(res_lib_votequorum_status));
+
+ LEAVE();
+}
+
+static void message_handler_req_lib_votequorum_qdevice_master_wins (void *conn,
+ const void *message)
+{
+ const struct req_lib_votequorum_qdevice_master_wins *req_lib_votequorum_qdevice_master_wins = message;
+ struct res_lib_votequorum_status res_lib_votequorum_status;
+ cs_error_t error = CS_OK;
+ uint32_t oldflags = us->flags;
+
+ ENTER();
+
+ if (!qdevice_can_operate) {
+ error = CS_ERR_ACCESS;
+ goto out;
+ }
+
+ if (us->flags & NODE_FLAGS_QDEVICE_REGISTERED) {
+ if (strncmp(req_lib_votequorum_qdevice_master_wins->name, qdevice_name, VOTEQUORUM_QDEVICE_MAX_NAME_LEN)) {
+ error = CS_ERR_INVALID_PARAM;
+ goto out;
+ }
+
+ if (req_lib_votequorum_qdevice_master_wins->allow) {
+ us->flags |= NODE_FLAGS_QDEVICE_MASTER_WINS;
+ } else {
+ us->flags &= ~NODE_FLAGS_QDEVICE_MASTER_WINS;
+ }
+
+ if (us->flags != oldflags) {
+ votequorum_exec_send_nodeinfo(us->node_id);
+ }
+
+ update_qdevice_master_wins(req_lib_votequorum_qdevice_master_wins->allow);
+ } else {
+ error = CS_ERR_NOT_EXIST;
+ }
+
+out:
+ res_lib_votequorum_status.header.size = sizeof(res_lib_votequorum_status);
+ res_lib_votequorum_status.header.id = MESSAGE_RES_VOTEQUORUM_STATUS;
+ res_lib_votequorum_status.header.error = error;
+ corosync_api->ipc_response_send(conn, &res_lib_votequorum_status, sizeof(res_lib_votequorum_status));
+
+ LEAVE();
+}
diff --git a/exec/votequorum.h b/exec/votequorum.h
new file mode 100644
index 0000000..697b694
--- /dev/null
+++ b/exec/votequorum.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2012 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Author: Fabio M. Di Nitto (fdinitto@redhat.com)
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of the MontaVista Software, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef VOTEQUORUM_H_DEFINED
+#define VOTEQUORUM_H_DEFINED
+
+#include "quorum.h"
+#include <corosync/logsys.h>
+#include <corosync/coroapi.h>
+
+char *votequorum_init(struct corosync_api_v1 *api,
+ quorum_set_quorate_fn_t q_set_quorate_fn);
+
+#endif /* VOTEQUORUM_H_DEFINED */
diff --git a/exec/vsf.h b/exec/vsf.h
new file mode 100644
index 0000000..6163410
--- /dev/null
+++ b/exec/vsf.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2006-2011 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Author: Steven Dake (sdake@redhat.com)
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of the MontaVista Software, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef VSF_H_DEFINED
+#define VSF_H_DEFINED
+
+struct corosync_api_v1;
+struct corosync_vsf_iface_ver0 {
+
+ /**
+ * Executes a callback whenever component changes
+ */
+ int (*init) (
+ struct corosync_api_v1 *api,
+ void (*primary_callback_fn) (
+ unsigned int *view_list,
+ int view_list_entries,
+ int primary_designated,
+ struct memb_ring_id *ring_id));
+
+ /**
+ * @retval 1 if we are primary component
+ * @retval 0 if not primary component
+ */
+ int (*primary) (void);
+};
+
+#endif /* VSF_H_DEFINED */
diff --git a/exec/vsf_quorum.c b/exec/vsf_quorum.c
new file mode 100644
index 0000000..e07134b
--- /dev/null
+++ b/exec/vsf_quorum.c
@@ -0,0 +1,801 @@
+/*
+ * Copyright (c) 2008-2020 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Author: Christine Caulfield (ccaulfie@redhat.com)
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of Red Hat Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include <pwd.h>
+#include <grp.h>
+#include <sys/types.h>
+#include <sys/poll.h>
+#include <sys/uio.h>
+#include <sys/mman.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+#include <sched.h>
+#include <time.h>
+
+#include "quorum.h"
+#include <corosync/corotypes.h>
+#include <qb/qbipc_common.h>
+#include <corosync/corodefs.h>
+#include <corosync/swab.h>
+#include <qb/qblist.h>
+#include <corosync/mar_gen.h>
+#include <corosync/ipc_quorum.h>
+#include <corosync/coroapi.h>
+#include <corosync/logsys.h>
+#include <corosync/icmap.h>
+
+#include "service.h"
+#include "votequorum.h"
+#include "vsf_ykd.h"
+
+LOGSYS_DECLARE_SUBSYS ("QUORUM");
+
+struct quorum_pd {
+ unsigned char track_flags;
+ int tracking_enabled;
+ struct qb_list_head list;
+ void *conn;
+ enum lib_quorum_model model;
+};
+
+struct internal_callback_pd {
+ struct qb_list_head list;
+ quorum_callback_fn_t callback;
+ void *context;
+};
+
+static void quorum_sync_init (
+ const unsigned int *trans_list,
+ size_t trans_list_entries,
+ const unsigned int *member_list,
+ size_t member_list_entries,
+ const struct memb_ring_id *ring_id);
+
+static int quorum_sync_process (void);
+
+static void quorum_sync_activate (void);
+
+static void quorum_sync_abort (void);
+
+static void message_handler_req_lib_quorum_getquorate (void *conn,
+ const void *msg);
+static void message_handler_req_lib_quorum_trackstart (void *conn,
+ const void *msg);
+static void message_handler_req_lib_quorum_trackstop (void *conn,
+ const void *msg);
+static void message_handler_req_lib_quorum_gettype (void *conn,
+ const void *msg);
+static void message_handler_req_lib_quorum_model_gettype (void *conn,
+ const void *msg);
+static void send_library_notification(void *conn);
+static void send_internal_notification(void);
+static void send_nodelist_library_notification(void *conn, int send_joined_left_list);
+static char *quorum_exec_init_fn (struct corosync_api_v1 *api);
+static int quorum_lib_init_fn (void *conn);
+static int quorum_lib_exit_fn (void *conn);
+
+static int primary_designated = 0;
+static int quorum_type = 0;
+static struct corosync_api_v1 *corosync_api;
+static struct qb_list_head lib_trackers_list;
+static struct qb_list_head internal_trackers_list;
+static struct memb_ring_id quorum_ring_id;
+static struct memb_ring_id last_sync_ring_id;
+static size_t quorum_view_list_entries = 0;
+static int quorum_view_list[PROCESSOR_COUNT_MAX];
+struct quorum_services_api_ver1 *quorum_iface = NULL;
+
+static char view_buf[64];
+
+static unsigned int my_member_list[PROCESSOR_COUNT_MAX];
+static size_t my_member_list_entries;
+static unsigned int my_old_member_list[PROCESSOR_COUNT_MAX];
+static size_t my_old_member_list_entries = 0;
+static unsigned int my_left_list[PROCESSOR_COUNT_MAX];
+static size_t my_left_list_entries;
+static unsigned int my_joined_list[PROCESSOR_COUNT_MAX];
+static size_t my_joined_list_entries;
+
+static void log_view_list(const unsigned int *view_list, size_t view_list_entries,
+ const char *view_list_type_str)
+{
+ int total = (int)view_list_entries;
+ int len, pos, ret;
+ int i = 0;
+
+ while (1) {
+ len = sizeof(view_buf);
+ pos = 0;
+ memset(view_buf, 0, len);
+
+ for (; i < total; i++) {
+ ret = snprintf(view_buf + pos, len - pos, " " CS_PRI_NODE_ID, view_list[i]);
+ if (ret >= len - pos)
+ break;
+ pos += ret;
+ }
+ log_printf (LOGSYS_LEVEL_NOTICE, "%s[%d]:%s%s",
+ view_list_type_str, total, view_buf, i < total ? "\\" : "");
+
+ if (i == total)
+ break;
+ }
+}
+
+/* Internal quorum API function */
+static void quorum_api_set_quorum(const unsigned int *view_list,
+ size_t view_list_entries,
+ int quorum, struct memb_ring_id *ring_id)
+{
+ int old_quorum = primary_designated;
+ primary_designated = quorum;
+
+ if (primary_designated && !old_quorum) {
+ log_printf (LOGSYS_LEVEL_NOTICE, "This node is within the primary component and will provide service.");
+ } else if (!primary_designated && old_quorum) {
+ log_printf (LOGSYS_LEVEL_NOTICE, "This node is within the non-primary component and will NOT provide any services.");
+ }
+
+ quorum_view_list_entries = view_list_entries;
+ memcpy(&quorum_ring_id, ring_id, sizeof (quorum_ring_id));
+ memcpy(quorum_view_list, view_list, sizeof(unsigned int)*view_list_entries);
+
+ log_view_list(view_list, view_list_entries, "Members");
+
+ /* Tell internal listeners */
+ send_internal_notification();
+
+ /* Tell IPC listeners */
+ send_library_notification(NULL);
+}
+
+static struct corosync_lib_handler quorum_lib_service[] =
+{
+ { /* 0 */
+ .lib_handler_fn = message_handler_req_lib_quorum_getquorate,
+ .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED
+ },
+ { /* 1 */
+ .lib_handler_fn = message_handler_req_lib_quorum_trackstart,
+ .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED
+ },
+ { /* 2 */
+ .lib_handler_fn = message_handler_req_lib_quorum_trackstop,
+ .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED
+ },
+ { /* 3 */
+ .lib_handler_fn = message_handler_req_lib_quorum_gettype,
+ .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED
+ },
+ { /* 4 */
+ .lib_handler_fn = message_handler_req_lib_quorum_model_gettype,
+ .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED
+ }
+};
+
+static struct corosync_service_engine quorum_service_handler = {
+ .name = "corosync cluster quorum service v0.1",
+ .id = QUORUM_SERVICE,
+ .priority = 1,
+ .private_data_size = sizeof (struct quorum_pd),
+ .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED,
+ .allow_inquorate = CS_LIB_ALLOW_INQUORATE,
+ .lib_init_fn = quorum_lib_init_fn,
+ .lib_exit_fn = quorum_lib_exit_fn,
+ .lib_engine = quorum_lib_service,
+ .exec_init_fn = quorum_exec_init_fn,
+ .sync_init = quorum_sync_init,
+ .sync_process = quorum_sync_process,
+ .sync_activate = quorum_sync_activate,
+ .sync_abort = quorum_sync_abort,
+ .lib_engine_count = sizeof (quorum_lib_service) / sizeof (struct corosync_lib_handler)
+};
+
+struct corosync_service_engine *vsf_quorum_get_service_engine_ver0 (void)
+{
+ return (&quorum_service_handler);
+}
+
+/* -------------------------------------------------- */
+
+
+/*
+ * Internal API functions for corosync
+ */
+
+static int quorum_quorate(void)
+{
+ return primary_designated;
+}
+
+
+static int quorum_register_callback(quorum_callback_fn_t function, void *context)
+{
+ struct internal_callback_pd *pd = malloc(sizeof(struct internal_callback_pd));
+ if (!pd)
+ return -1;
+
+ pd->context = context;
+ pd->callback = function;
+ qb_list_add (&pd->list, &internal_trackers_list);
+
+ return 0;
+}
+
+static int quorum_unregister_callback(quorum_callback_fn_t function, void *context)
+{
+ struct internal_callback_pd *pd;
+ struct qb_list_head *tmp, *tmp_iter;
+
+ qb_list_for_each_safe(tmp, tmp_iter, &internal_trackers_list) {
+ pd = qb_list_entry(tmp, struct internal_callback_pd, list);
+ if (pd->callback == function && pd->context == context) {
+ qb_list_del(&pd->list);
+ free(pd);
+ return 0;
+ }
+ }
+ return -1;
+}
+
+static struct quorum_callin_functions callins = {
+ .quorate = quorum_quorate,
+ .register_callback = quorum_register_callback,
+ .unregister_callback = quorum_unregister_callback
+};
+
+/* --------------------------------------------------------------------- */
+
+static void quorum_sync_init (
+ const unsigned int *trans_list,
+ size_t trans_list_entries,
+ const unsigned int *member_list,
+ size_t member_list_entries,
+ const struct memb_ring_id *ring_id)
+{
+ int found;
+ int i, j;
+ int entries;
+ int node_joined;
+
+ memcpy (my_member_list, member_list, member_list_entries *
+ sizeof (unsigned int));
+ my_member_list_entries = member_list_entries;
+
+ last_sync_ring_id = *ring_id;
+
+ /*
+ * Determine left list of nodeids
+ */
+ entries = 0;
+ for (i = 0; i < my_old_member_list_entries; i++) {
+ found = 0;
+ for (j = 0; j < trans_list_entries; j++) {
+ if (my_old_member_list[i] == trans_list[j]) {
+ found = 1;
+ break;
+ }
+ }
+
+ if (found == 0) {
+ my_left_list[entries++] = my_old_member_list[i];
+ } else {
+ /*
+ * Check it is really in new membership
+ */
+ found = 0;
+
+ for (j = 0; j < my_member_list_entries; j++) {
+ if (my_old_member_list[i] == my_member_list[j]) {
+ found = 1;
+ break;
+ }
+ }
+
+ /*
+ * Node is in both old_member_list and trans list but not in my_member_list.
+ * (This shouldn't really happen).
+ */
+ if (!found) {
+ my_left_list[entries++] = my_old_member_list[i];
+ }
+ }
+ }
+ my_left_list_entries = entries;
+
+ /*
+ * Determine joined list of nodeids
+ */
+ entries = 0;
+ for (i = 0; i < my_member_list_entries; i++) {
+ node_joined = 1;
+ for (j = 0; j < my_old_member_list_entries; j++) {
+ if (my_member_list[i] == my_old_member_list[j]) {
+ /*
+ * Node is in member list and also in my_old_member list -> check
+ * if it is in left_list.
+ */
+ node_joined = 0;
+ break;
+ }
+ }
+
+ if (!node_joined) {
+ /*
+ * Check if node is in left list.
+ */
+ for (j = 0; j < my_left_list_entries; j++) {
+ if (my_member_list[i] == my_left_list[j]) {
+ /*
+ * Node is both in left and also in member list -> joined
+ */
+ node_joined = 1;
+ break;
+ }
+ }
+ }
+
+ if (node_joined) {
+ my_joined_list[entries++] = my_member_list[i];
+ }
+ }
+ my_joined_list_entries = entries;
+
+ log_view_list(my_member_list, my_member_list_entries, "Sync members");
+
+ if (my_joined_list_entries > 0) {
+ log_view_list(my_joined_list, my_joined_list_entries, "Sync joined");
+ }
+
+ if (my_left_list_entries > 0) {
+ log_view_list(my_left_list, my_left_list_entries, "Sync left");
+ }
+}
+
+static int quorum_sync_process (void)
+{
+
+ return (0);
+}
+
+static void quorum_sync_activate (void)
+{
+
+ memcpy (my_old_member_list, my_member_list,
+ my_member_list_entries * sizeof (unsigned int));
+ my_old_member_list_entries = my_member_list_entries;
+
+ /* Tell IPC listeners */
+ send_nodelist_library_notification(NULL, 1);
+}
+
+static void quorum_sync_abort (void)
+{
+
+}
+
+static char *quorum_exec_init_fn (struct corosync_api_v1 *api)
+{
+ char *quorum_module = NULL;
+ char *error;
+
+ corosync_api = api;
+ qb_list_init (&lib_trackers_list);
+ qb_list_init (&internal_trackers_list);
+
+ /*
+ * Tell corosync we have a quorum engine.
+ */
+ api->quorum_initialize(&callins);
+
+ /*
+ * Look for a quorum provider
+ */
+ if (icmap_get_string("quorum.provider", &quorum_module) == CS_OK) {
+ log_printf (LOGSYS_LEVEL_NOTICE,
+ "Using quorum provider %s", quorum_module);
+
+ error = (char *)"Invalid quorum provider";
+
+ if (strcmp (quorum_module, "corosync_votequorum") == 0) {
+ error = votequorum_init (api, quorum_api_set_quorum);
+ quorum_type = 1;
+ }
+ if (strcmp (quorum_module, "corosync_ykd") == 0) {
+ error = ykd_init (api, quorum_api_set_quorum);
+ quorum_type = 1;
+ }
+ if (error) {
+ log_printf (LOGSYS_LEVEL_CRIT,
+ "Quorum provider: %s failed to initialize.",
+ quorum_module);
+ free(quorum_module);
+ return (error);
+ }
+ }
+
+ if (quorum_module) {
+ free(quorum_module);
+ quorum_module = NULL;
+ }
+
+ /*
+ * setting quorum_type and primary_designated in the right order is important
+ * always try to lookup/init a quorum module, then revert back to be quorate
+ */
+
+ if (quorum_type == 0) {
+ primary_designated = 1;
+ }
+
+ return (NULL);
+}
+
+static int quorum_lib_init_fn (void *conn)
+{
+ struct quorum_pd *pd = (struct quorum_pd *)corosync_api->ipc_private_data_get (conn);
+
+ log_printf(LOGSYS_LEVEL_DEBUG, "lib_init_fn: conn=%p", conn);
+
+ qb_list_init (&pd->list);
+ pd->conn = conn;
+ pd->model = LIB_QUORUM_MODEL_V0;
+
+ return (0);
+}
+
+static int quorum_lib_exit_fn (void *conn)
+{
+ struct quorum_pd *quorum_pd = (struct quorum_pd *)corosync_api->ipc_private_data_get (conn);
+
+ log_printf(LOGSYS_LEVEL_DEBUG, "lib_exit_fn: conn=%p", conn);
+
+ if (quorum_pd->tracking_enabled) {
+ qb_list_del (&quorum_pd->list);
+ qb_list_init (&quorum_pd->list);
+ }
+ return (0);
+}
+
+
+static void send_internal_notification(void)
+{
+ struct qb_list_head *tmp;
+ struct internal_callback_pd *pd;
+
+ qb_list_for_each(tmp, &internal_trackers_list) {
+ pd = qb_list_entry(tmp, struct internal_callback_pd, list);
+
+ pd->callback(primary_designated, pd->context);
+ }
+}
+
+static void prepare_library_notification_v0(char *buf, size_t size)
+{
+ struct res_lib_quorum_notification *res_lib_quorum_notification = (struct res_lib_quorum_notification *)buf;
+ int i;
+
+ res_lib_quorum_notification->quorate = primary_designated;
+ res_lib_quorum_notification->ring_seq = quorum_ring_id.seq;
+ res_lib_quorum_notification->view_list_entries = quorum_view_list_entries;
+ for (i=0; i<quorum_view_list_entries; i++) {
+ res_lib_quorum_notification->view_list[i] = quorum_view_list[i];
+ }
+
+ res_lib_quorum_notification->header.id = MESSAGE_RES_QUORUM_NOTIFICATION;
+ res_lib_quorum_notification->header.size = size;
+ res_lib_quorum_notification->header.error = CS_OK;
+}
+
+static void prepare_library_notification_v1(char *buf, size_t size)
+{
+ struct res_lib_quorum_v1_quorum_notification *res_lib_quorum_v1_quorum_notification =
+ (struct res_lib_quorum_v1_quorum_notification *)buf;
+ int i;
+
+ res_lib_quorum_v1_quorum_notification->quorate = primary_designated;
+ res_lib_quorum_v1_quorum_notification->ring_id.nodeid = quorum_ring_id.nodeid;
+ res_lib_quorum_v1_quorum_notification->ring_id.seq = quorum_ring_id.seq;
+ res_lib_quorum_v1_quorum_notification->view_list_entries = quorum_view_list_entries;
+ for (i=0; i<quorum_view_list_entries; i++) {
+ res_lib_quorum_v1_quorum_notification->view_list[i] = quorum_view_list[i];
+ }
+
+ res_lib_quorum_v1_quorum_notification->header.id = MESSAGE_RES_QUORUM_V1_QUORUM_NOTIFICATION;
+ res_lib_quorum_v1_quorum_notification->header.size = size;
+ res_lib_quorum_v1_quorum_notification->header.error = CS_OK;
+}
+
+static void send_library_notification(void *conn)
+{
+ int size_v0 = sizeof(struct res_lib_quorum_notification) +
+ sizeof(mar_uint32_t) * quorum_view_list_entries;
+ int size_v1 = sizeof(struct res_lib_quorum_v1_quorum_notification) +
+ sizeof(mar_uint32_t)*quorum_view_list_entries;
+
+ char buf_v0[size_v0];
+ char buf_v1[size_v1];
+
+ struct res_lib_quorum_notification *res_lib_quorum_notification =
+ (struct res_lib_quorum_notification *)buf_v0;
+ struct res_lib_quorum_v1_quorum_notification *res_lib_quorum_v1_quorum_notification =
+ (struct res_lib_quorum_v1_quorum_notification *)buf_v1;
+
+ struct quorum_pd *qpd;
+ struct qb_list_head *tmp;
+
+ log_printf(LOGSYS_LEVEL_DEBUG, "sending quorum notification to %p, length = %u/%u", conn, size_v0, size_v1);
+
+ prepare_library_notification_v0(buf_v0, size_v0);
+ prepare_library_notification_v1(buf_v1, size_v1);
+
+ /* Send it to all interested parties */
+ if (conn) {
+ qpd = (struct quorum_pd *)corosync_api->ipc_private_data_get (conn);
+
+ if (qpd->model == LIB_QUORUM_MODEL_V0) {
+ corosync_api->ipc_dispatch_send(conn, res_lib_quorum_notification, size_v0);
+ } else if (qpd->model == LIB_QUORUM_MODEL_V1) {
+ corosync_api->ipc_dispatch_send(conn, res_lib_quorum_v1_quorum_notification, size_v1);
+ }
+ }
+ else {
+ qb_list_for_each(tmp, &lib_trackers_list) {
+ qpd = qb_list_entry(tmp, struct quorum_pd, list);
+
+ if (qpd->model == LIB_QUORUM_MODEL_V0) {
+ corosync_api->ipc_dispatch_send(qpd->conn,
+ res_lib_quorum_notification, size_v0);
+ } else if (qpd->model == LIB_QUORUM_MODEL_V1) {
+ corosync_api->ipc_dispatch_send(qpd->conn,
+ res_lib_quorum_v1_quorum_notification, size_v1);
+ }
+ }
+ }
+ return;
+}
+
+static void send_nodelist_library_notification(void *conn, int send_joined_left_list)
+{
+ int size = sizeof(struct res_lib_quorum_v1_nodelist_notification) +
+ sizeof(mar_uint32_t) * my_member_list_entries;
+ char *buf;
+ struct res_lib_quorum_v1_nodelist_notification *res_lib_quorum_v1_nodelist_notification;
+ struct quorum_pd *qpd;
+ struct qb_list_head *tmp;
+ mar_uint32_t *ptr;
+ int i;
+
+ if (send_joined_left_list) {
+ size += sizeof(mar_uint32_t) * my_joined_list_entries;
+ size += sizeof(mar_uint32_t) * my_left_list_entries;
+ }
+
+ buf = alloca(size);
+ memset(buf, 0, size);
+
+ res_lib_quorum_v1_nodelist_notification = (struct res_lib_quorum_v1_nodelist_notification *)buf;
+
+ res_lib_quorum_v1_nodelist_notification->ring_id.nodeid = last_sync_ring_id.nodeid;
+ res_lib_quorum_v1_nodelist_notification->ring_id.seq = last_sync_ring_id.seq;
+ res_lib_quorum_v1_nodelist_notification->member_list_entries = my_member_list_entries;
+
+ if (send_joined_left_list) {
+ res_lib_quorum_v1_nodelist_notification->joined_list_entries = my_joined_list_entries;
+ res_lib_quorum_v1_nodelist_notification->left_list_entries = my_left_list_entries;
+ }
+
+ ptr = res_lib_quorum_v1_nodelist_notification->member_list;
+
+ for (i=0; i<my_member_list_entries; i++, ptr++) {
+ *ptr = my_member_list[i];
+ }
+
+ if (send_joined_left_list) {
+ for (i=0; i<my_joined_list_entries; i++, ptr++) {
+ *ptr = my_joined_list[i];
+ }
+
+ for (i=0; i<my_left_list_entries; i++, ptr++) {
+ *ptr = my_left_list[i];
+ }
+ }
+
+ res_lib_quorum_v1_nodelist_notification->header.id = MESSAGE_RES_QUORUM_V1_NODELIST_NOTIFICATION;
+ res_lib_quorum_v1_nodelist_notification->header.size = size;
+ res_lib_quorum_v1_nodelist_notification->header.error = CS_OK;
+
+ log_printf(LOGSYS_LEVEL_DEBUG, "sending nodelist notification to %p, length = %u", conn, size);
+
+ /* Send it to all interested parties */
+ if (conn) {
+ qpd = (struct quorum_pd *)corosync_api->ipc_private_data_get (conn);
+
+ if (qpd->model == LIB_QUORUM_MODEL_V1) {
+ corosync_api->ipc_dispatch_send(conn, res_lib_quorum_v1_nodelist_notification, size);
+ }
+ }
+ else {
+ qb_list_for_each(tmp, &lib_trackers_list) {
+ qpd = qb_list_entry(tmp, struct quorum_pd, list);
+
+ if (qpd->model == LIB_QUORUM_MODEL_V1) {
+ corosync_api->ipc_dispatch_send(qpd->conn,
+ res_lib_quorum_v1_nodelist_notification, size);
+ }
+ }
+ }
+
+ return;
+}
+
+static void message_handler_req_lib_quorum_getquorate (void *conn,
+ const void *msg)
+{
+ struct res_lib_quorum_getquorate res_lib_quorum_getquorate;
+
+ log_printf(LOGSYS_LEVEL_DEBUG, "got quorate request on %p", conn);
+
+ /* send status */
+ res_lib_quorum_getquorate.quorate = primary_designated;
+ res_lib_quorum_getquorate.header.size = sizeof(res_lib_quorum_getquorate);
+ res_lib_quorum_getquorate.header.id = MESSAGE_RES_QUORUM_GETQUORATE;
+ res_lib_quorum_getquorate.header.error = CS_OK;
+ corosync_api->ipc_response_send(conn, &res_lib_quorum_getquorate, sizeof(res_lib_quorum_getquorate));
+}
+
+static void message_handler_req_lib_quorum_trackstart (void *conn,
+ const void *msg)
+{
+ const struct req_lib_quorum_trackstart *req_lib_quorum_trackstart = msg;
+ struct qb_ipc_response_header res;
+ struct quorum_pd *quorum_pd = (struct quorum_pd *)corosync_api->ipc_private_data_get (conn);
+ cs_error_t error = CS_OK;
+
+ log_printf(LOGSYS_LEVEL_DEBUG, "got trackstart request on %p", conn);
+
+ /*
+ * If an immediate listing of the current cluster membership
+ * is requested, generate membership list
+ */
+ if (req_lib_quorum_trackstart->track_flags & CS_TRACK_CURRENT ||
+ req_lib_quorum_trackstart->track_flags & CS_TRACK_CHANGES) {
+ log_printf(LOGSYS_LEVEL_DEBUG, "sending initial status to %p", conn);
+ send_nodelist_library_notification(conn, 0);
+ send_library_notification(conn);
+ }
+
+ if (quorum_pd->tracking_enabled) {
+ error = CS_ERR_EXIST;
+ goto response_send;
+ }
+
+ /*
+ * Record requests for tracking
+ */
+ if (req_lib_quorum_trackstart->track_flags & CS_TRACK_CHANGES ||
+ req_lib_quorum_trackstart->track_flags & CS_TRACK_CHANGES_ONLY) {
+
+ quorum_pd->track_flags = req_lib_quorum_trackstart->track_flags;
+ quorum_pd->tracking_enabled = 1;
+
+ qb_list_add (&quorum_pd->list, &lib_trackers_list);
+ }
+
+response_send:
+ /* send status */
+ res.size = sizeof(res);
+ res.id = MESSAGE_RES_QUORUM_TRACKSTART;
+ res.error = error;
+ corosync_api->ipc_response_send(conn, &res, sizeof(struct qb_ipc_response_header));
+}
+
+static void message_handler_req_lib_quorum_trackstop (void *conn, const void *msg)
+{
+ struct qb_ipc_response_header res;
+ struct quorum_pd *quorum_pd = (struct quorum_pd *)corosync_api->ipc_private_data_get (conn);
+
+ log_printf(LOGSYS_LEVEL_DEBUG, "got trackstop request on %p", conn);
+
+ if (quorum_pd->tracking_enabled) {
+ res.error = CS_OK;
+ quorum_pd->tracking_enabled = 0;
+ qb_list_del (&quorum_pd->list);
+ qb_list_init (&quorum_pd->list);
+ } else {
+ res.error = CS_ERR_NOT_EXIST;
+ }
+
+ /* send status */
+ res.size = sizeof(res);
+ res.id = MESSAGE_RES_QUORUM_TRACKSTOP;
+ res.error = CS_OK;
+ corosync_api->ipc_response_send(conn, &res, sizeof(struct qb_ipc_response_header));
+}
+
+static void message_handler_req_lib_quorum_gettype (void *conn,
+ const void *msg)
+{
+ struct res_lib_quorum_gettype res_lib_quorum_gettype;
+
+ log_printf(LOGSYS_LEVEL_DEBUG, "got quorum_type request on %p", conn);
+
+ /* send status */
+ res_lib_quorum_gettype.quorum_type = quorum_type;
+ res_lib_quorum_gettype.header.size = sizeof(res_lib_quorum_gettype);
+ res_lib_quorum_gettype.header.id = MESSAGE_RES_QUORUM_GETTYPE;
+ res_lib_quorum_gettype.header.error = CS_OK;
+ corosync_api->ipc_response_send(conn, &res_lib_quorum_gettype, sizeof(res_lib_quorum_gettype));
+}
+
+static void message_handler_req_lib_quorum_model_gettype (void *conn,
+ const void *msg)
+{
+ const struct req_lib_quorum_model_gettype *req_lib_quorum_model_gettype = msg;
+ struct res_lib_quorum_model_gettype res_lib_quorum_model_gettype;
+ struct quorum_pd *quorum_pd = (struct quorum_pd *)corosync_api->ipc_private_data_get (conn);
+ cs_error_t ret_err;
+
+ log_printf(LOGSYS_LEVEL_DEBUG, "got quorum_model_type request on %p", conn);
+
+ ret_err = CS_OK;
+
+ if (req_lib_quorum_model_gettype->model != LIB_QUORUM_MODEL_V0 &&
+ req_lib_quorum_model_gettype->model != LIB_QUORUM_MODEL_V1) {
+ log_printf(LOGSYS_LEVEL_ERROR, "quorum_model_type request for unsupported model %u",
+ req_lib_quorum_model_gettype->model);
+
+ ret_err = CS_ERR_INVALID_PARAM;
+ } else {
+ quorum_pd->model = req_lib_quorum_model_gettype->model;
+ }
+
+ /* send status */
+ res_lib_quorum_model_gettype.quorum_type = quorum_type;
+ res_lib_quorum_model_gettype.header.size = sizeof(res_lib_quorum_model_gettype);
+ res_lib_quorum_model_gettype.header.id = MESSAGE_RES_QUORUM_MODEL_GETTYPE;
+ res_lib_quorum_model_gettype.header.error = ret_err;
+ corosync_api->ipc_response_send(conn, &res_lib_quorum_model_gettype, sizeof(res_lib_quorum_model_gettype));
+}
diff --git a/exec/vsf_ykd.c b/exec/vsf_ykd.c
new file mode 100644
index 0000000..8724168
--- /dev/null
+++ b/exec/vsf_ykd.c
@@ -0,0 +1,537 @@
+/*
+ * Copyright (c) 2005 MontaVista Software, Inc.
+ * Copyright (c) 2006-2012 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Author: Steven Dake (sdake@redhat.com)
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of the MontaVista Software, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include <assert.h>
+#include <pwd.h>
+#include <grp.h>
+#include <sys/types.h>
+#include <sys/poll.h>
+#include <sys/uio.h>
+#include <sys/mman.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+#include <sched.h>
+#include <time.h>
+
+#include "quorum.h"
+#include <corosync/logsys.h>
+#include <corosync/corotypes.h>
+#include <qb/qbipc_common.h>
+#include <corosync/mar_gen.h>
+#include <corosync/coroapi.h>
+#include <corosync/swab.h>
+
+#include "vsf_ykd.h"
+
+LOGSYS_DECLARE_SUBSYS ("YKD");
+
+#define YKD_PROCESSOR_COUNT_MAX 32
+
+enum ykd_header_values {
+ YKD_HEADER_SENDSTATE = 0,
+ YKD_HEADER_ATTEMPT = 1
+};
+
+enum ykd_mode {
+ YKD_MODE_SENDSTATE = 0,
+ YKD_MODE_ATTEMPT = 1
+};
+
+struct ykd_header {
+ int id;
+};
+
+struct ykd_session {
+ unsigned int member_list[YKD_PROCESSOR_COUNT_MAX];
+ int member_list_entries;
+ int session_id;
+};
+
+struct ykd_state {
+ struct ykd_session last_primary;
+
+ struct ykd_session last_formed[YKD_PROCESSOR_COUNT_MAX];
+
+ int last_formed_entries;
+
+ struct ykd_session ambiguous_sessions[YKD_PROCESSOR_COUNT_MAX];
+
+ int ambiguous_sessions_entries;
+
+ int session_id;
+};
+
+struct state_received {
+ unsigned int nodeid;
+ int received;
+ struct ykd_state ykd_state;
+};
+
+struct ykd_state ykd_state;
+
+static void *ykd_group_handle;
+
+static struct state_received state_received_confchg[YKD_PROCESSOR_COUNT_MAX];
+
+static int state_received_confchg_entries;
+
+static struct state_received state_received_process[YKD_PROCESSOR_COUNT_MAX];
+
+static int state_received_process_entries;
+
+static enum ykd_mode ykd_mode;
+
+static unsigned int ykd_view_list[YKD_PROCESSOR_COUNT_MAX];
+
+static int ykd_view_list_entries;
+
+static int session_id_max;
+
+static struct ykd_session *last_primary_max;
+
+static struct ykd_session ambiguous_sessions_max[YKD_PROCESSOR_COUNT_MAX];
+
+static int ambiguous_sessions_max_entries;
+
+static int ykd_primary_designated = 0;
+
+static struct memb_ring_id ykd_ring_id;
+
+hdb_handle_t schedwrk_attempt_send_callback_handle;
+
+hdb_handle_t schedwrk_state_send_callback_handle;
+
+static struct corosync_api_v1 *api;
+
+static void (*ykd_primary_callback_fn) (
+ const unsigned int *view_list,
+ size_t view_list_entries,
+ int primary_designated,
+ struct memb_ring_id *ring_id) = NULL;
+
+static void ykd_state_init (void)
+{
+ ykd_state.session_id = 0;
+ ykd_state.last_formed_entries = 0;
+ ykd_state.ambiguous_sessions_entries = 0;
+ ykd_state.last_primary.session_id = 0;
+ ykd_state.last_primary.member_list_entries = 0;
+}
+
+static int ykd_state_send_msg (const void *context)
+{
+ struct iovec iovec[2];
+ struct ykd_header header;
+ int res;
+
+ header.id = YKD_HEADER_SENDSTATE;
+
+ iovec[0].iov_base = (char *)&header;
+ iovec[0].iov_len = sizeof (struct ykd_header);
+ iovec[1].iov_base = (char *)&ykd_state;
+ iovec[1].iov_len = sizeof (struct ykd_state);
+
+ res = api->tpg_joined_mcast (ykd_group_handle, iovec, 2,
+ TOTEM_AGREED);
+
+ return (res);
+}
+
+static void ykd_state_send (void)
+{
+ api->schedwrk_create (
+ &schedwrk_state_send_callback_handle,
+ ykd_state_send_msg,
+ NULL);
+}
+
+static int ykd_attempt_send_msg (const void *context)
+{
+ struct iovec iovec;
+ struct ykd_header header;
+ int res;
+
+ header.id = YKD_HEADER_ATTEMPT;
+
+ iovec.iov_base = (char *)&header;
+ iovec.iov_len = sizeof (struct ykd_header);
+
+ res = api->tpg_joined_mcast (ykd_group_handle, &iovec, 1,
+ TOTEM_AGREED);
+
+ return (res);
+}
+
+static void ykd_attempt_send (void)
+{
+ api->schedwrk_create (
+ &schedwrk_attempt_send_callback_handle,
+ ykd_attempt_send_msg,
+ NULL);
+}
+
+static void compute (void)
+{
+ int i;
+ int j;
+
+ session_id_max = 0;
+ last_primary_max = &state_received_process[0].ykd_state.last_primary;
+ ambiguous_sessions_max_entries = 0;
+
+ for (i = 0; i < state_received_process_entries; i++) {
+ /*
+ * Calculate maximum session id
+ */
+ if (state_received_process[i].ykd_state.session_id > session_id_max) {
+ session_id_max = state_received_process[i].ykd_state.session_id;
+ }
+
+ /*
+ * Calculate maximum primary id
+ */
+ if (state_received_process[i].ykd_state.last_primary.session_id > last_primary_max->session_id) {
+ last_primary_max = &state_received_process[i].ykd_state.last_primary;
+ }
+
+ /*
+ * generate the maximum ambiguous sessions list
+ */
+ for (j = 0; j < state_received_process[i].ykd_state.ambiguous_sessions_entries; j++) {
+ if (state_received_process[i].ykd_state.ambiguous_sessions[j].session_id > last_primary_max->session_id) {
+ memcpy (&ambiguous_sessions_max[ambiguous_sessions_max_entries],
+ &state_received_process[i].ykd_state.ambiguous_sessions[j],
+ sizeof (struct ykd_session));
+ ambiguous_sessions_max_entries += 1;
+ }
+ }
+ }
+}
+
+static int subquorum (
+ unsigned int *member_list,
+ int member_list_entries,
+ struct ykd_session *session)
+{
+ int intersections = 0;
+ int i;
+ int j;
+
+ for (i = 0; i < member_list_entries; i++) {
+ for (j = 0; j < session->member_list_entries; j++) {
+ if (member_list[i] == session->member_list[j]) {
+ intersections += 1;
+ }
+ }
+ }
+
+ /*
+ * even split
+ */
+ if (intersections == (session->member_list_entries - intersections)) {
+ return (1);
+ } else
+
+ /*
+ * majority split
+ */
+ if (intersections > (session->member_list_entries - intersections)) {
+ return (1);
+ }
+ return (0);
+}
+
+static int decide (void)
+{
+ int i;
+
+ /*
+ * Determine if there is a subquorum
+ */
+ if (subquorum (ykd_view_list, ykd_view_list_entries, last_primary_max) == 0) {
+ return (0);
+ }
+
+ for (i = 0; i < ambiguous_sessions_max_entries; i++) {
+ if (subquorum (ykd_view_list, ykd_view_list_entries, &ambiguous_sessions_max[i]) == 0) {
+ return (0);
+ }
+
+ }
+ return (1);
+}
+
+static void ykd_session_endian_convert (struct ykd_session *ykd_session)
+{
+ int i;
+
+ ykd_session->member_list_entries =
+ swab32 (ykd_session->member_list_entries);
+ ykd_session->session_id = swab32 (ykd_session->session_id);
+ for (i = 0; i < ykd_session->member_list_entries; i++) {
+ ykd_session->member_list[i] =
+ swab32 (ykd_session->member_list[i]);
+ }
+}
+
+static void ykd_state_endian_convert (struct ykd_state *state)
+{
+ int i;
+
+ ykd_session_endian_convert (&state->last_primary);
+ state->last_formed_entries = swab32 (state->last_formed_entries);
+ state->ambiguous_sessions_entries = swab32 (state->ambiguous_sessions_entries);
+ state->session_id = swab32 (state->session_id);
+
+ for (i = 0; i < state->last_formed_entries; i++) {
+ ykd_session_endian_convert (&state->last_formed[i]);
+ }
+
+ for (i = 0; i < state->ambiguous_sessions_entries; i++) {
+ ykd_session_endian_convert (&state->ambiguous_sessions[i]);
+ }
+}
+
+static void ykd_deliver_fn (
+ unsigned int nodeid,
+ const void *msg,
+ unsigned int msg_len,
+ int endian_conversion_required)
+{
+ int all_received = 1;
+ int state_position = 0;
+ int i;
+ struct ykd_header *header = (struct ykd_header *)msg;
+ char *msg_state = (char *)msg + sizeof (struct ykd_header);
+
+ /*
+ * If this is a localhost address, this node is always primary
+ */
+#ifdef TODO
+ if (totemip_localhost_check (source_addr)) {
+ log_printf (LOGSYS_LEVEL_NOTICE,
+ "This processor is within the primary component.");
+ primary_designated = 1;
+
+ ykd_primary_callback_fn (
+ ykd_view_list,
+ ykd_view_list_entries,
+ primary_designated,
+ &ykd_ring_id);
+ return;
+ }
+#endif
+ if (endian_conversion_required &&
+ (msg_len > sizeof (struct ykd_header))) {
+ ykd_state_endian_convert ((struct ykd_state *)msg_state);
+ }
+
+ /*
+ * Set completion for source_addr's address
+ */
+ for (state_position = 0; state_position < state_received_confchg_entries; state_position++) {
+ if (nodeid == state_received_process[state_position].nodeid) {
+ /*
+ * State position contains the address of the state to modify
+ * This may be used later by the other algorithms
+ */
+ state_received_process[state_position].received = 1;
+ break;
+ }
+ }
+
+ /*
+ * Test if all nodes have submitted their state data
+ */
+ for (i = 0; i < state_received_confchg_entries; i++) {
+ if (state_received_process[i].received == 0) {
+ all_received = 0;
+ }
+ }
+
+ /*
+ * Ignore messages from a different state
+ */
+ if ((ykd_mode == YKD_MODE_SENDSTATE && header->id == YKD_HEADER_ATTEMPT) ||
+ (ykd_mode == YKD_MODE_ATTEMPT && header->id == YKD_HEADER_SENDSTATE))
+ return;
+
+ switch (ykd_mode) {
+ case YKD_MODE_SENDSTATE:
+ assert (msg_len > sizeof (struct ykd_header));
+ /*
+ * Copy state information for the sending processor
+ */
+ memcpy (&state_received_process[state_position].ykd_state,
+ msg_state, sizeof (struct ykd_state));
+
+ /*
+ * Try to form a component
+ */
+ if (all_received) {
+ for (i = 0; i < state_received_confchg_entries; i++) {
+ state_received_process[i].received = 0;
+ }
+ ykd_mode = YKD_MODE_ATTEMPT;
+
+// TODO resolve optimizes for failure conditions during ykd calculation
+// resolve();
+ compute();
+
+ if (decide ()) {
+ ykd_state.session_id = session_id_max + 1;
+ memcpy (ykd_state.ambiguous_sessions[ykd_state.ambiguous_sessions_entries].member_list,
+ ykd_view_list, sizeof (unsigned int) * ykd_view_list_entries);
+ ykd_state.ambiguous_sessions[ykd_state.ambiguous_sessions_entries].member_list_entries = ykd_view_list_entries;
+ ykd_state.ambiguous_sessions_entries += 1;
+ ykd_attempt_send();
+ }
+ }
+ break;
+
+ case YKD_MODE_ATTEMPT:
+ if (all_received) {
+ log_printf (LOGSYS_LEVEL_NOTICE,
+ "This processor is within the primary component.");
+ ykd_primary_designated = 1;
+
+ ykd_primary_callback_fn (
+ ykd_view_list,
+ ykd_view_list_entries,
+ ykd_primary_designated,
+ &ykd_ring_id);
+
+ memcpy (ykd_state.last_primary.member_list, ykd_view_list, sizeof (ykd_view_list));
+ ykd_state.last_primary.member_list_entries = ykd_view_list_entries;
+ ykd_state.last_primary.session_id = ykd_state.session_id;
+ ykd_state.ambiguous_sessions_entries = 0;
+ }
+ break;
+ }
+}
+
+int first_run = 1;
+static void ykd_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;
+
+ if (configuration_type != TOTEM_CONFIGURATION_REGULAR) {
+ return;
+ }
+
+ memcpy (&ykd_ring_id, ring_id, sizeof (struct memb_ring_id));
+
+ if (first_run) {
+ ykd_state.last_primary.member_list[0] = api->totem_nodeid_get();
+ ykd_state.last_primary.member_list_entries = 1;
+ ykd_state.last_primary.session_id = 0;
+ first_run = 0;
+ }
+ memcpy (ykd_view_list, member_list,
+ member_list_entries * sizeof (unsigned int));
+ ykd_view_list_entries = member_list_entries;
+
+ ykd_mode = YKD_MODE_SENDSTATE;
+
+ ykd_primary_designated = 0;
+
+ ykd_primary_callback_fn (
+ ykd_view_list,
+ ykd_view_list_entries,
+ ykd_primary_designated,
+ &ykd_ring_id);
+
+ memset (&state_received_confchg, 0, sizeof (state_received_confchg));
+ for (i = 0; i < member_list_entries; i++) {
+ state_received_confchg[i].nodeid = member_list[i];
+ state_received_confchg[i].received = 0;
+ }
+ memcpy (state_received_process, state_received_confchg,
+ sizeof (state_received_confchg));
+
+ state_received_confchg_entries = member_list_entries;
+ state_received_process_entries = member_list_entries;
+
+ ykd_state_send ();
+}
+
+struct corosync_tpg_group ykd_group = {
+ .group = "ykd",
+ .group_len = 3
+};
+
+char *ykd_init (
+ struct corosync_api_v1 *corosync_api,
+ quorum_set_quorate_fn_t set_primary)
+{
+ const char *error = NULL;
+
+ ykd_primary_callback_fn = set_primary;
+ api = corosync_api;
+
+ if (set_primary == 0) {
+ error = (char *)"set primary not set";
+ }
+
+ api->tpg_init (
+ &ykd_group_handle,
+ ykd_deliver_fn,
+ ykd_confchg_fn);
+
+ api->tpg_join (
+ ykd_group_handle,
+ &ykd_group,
+ 1);
+
+ ykd_state_init ();
+
+ return ((char *)error);
+}
diff --git a/exec/vsf_ykd.h b/exec/vsf_ykd.h
new file mode 100644
index 0000000..d009e1c
--- /dev/null
+++ b/exec/vsf_ykd.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2012 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Author: Fabio M. Di Nitto (fdinitto@redhat.com)
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of the MontaVista Software, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef VFS_YKD_H_DEFINED
+#define VFS_YKD_H_DEFINED
+
+#include "quorum.h"
+#include <corosync/logsys.h>
+#include <corosync/coroapi.h>
+
+char *ykd_init(struct corosync_api_v1 *api,
+ quorum_set_quorate_fn_t set_primary);
+
+#endif /* VFS_YKD_H_DEFINED */
diff --git a/exec/wd.c b/exec/wd.c
new file mode 100644
index 0000000..4ca5673
--- /dev/null
+++ b/exec/wd.c
@@ -0,0 +1,767 @@
+/*
+ * Copyright (c) 2010-2012 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Author: Angus Salkeld <asalkeld@redhat.com>
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of the MontaVista Software, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <linux/types.h>
+#include <linux/watchdog.h>
+#include <sys/reboot.h>
+
+#include <corosync/corotypes.h>
+#include <corosync/corodefs.h>
+#include <corosync/coroapi.h>
+#include <qb/qblist.h>
+#include <corosync/logsys.h>
+#include <corosync/icmap.h>
+#include "fsm.h"
+
+#include "service.h"
+
+typedef enum {
+ WD_RESOURCE_GOOD,
+ WD_RESOURCE_FAILED,
+ WD_RESOURCE_STATE_UNKNOWN,
+ WD_RESOURCE_NOT_MONITORED
+} wd_resource_state_t;
+
+struct resource {
+ char res_path[ICMAP_KEYNAME_MAXLEN];
+ char *recovery;
+ char name[CS_MAX_NAME_LENGTH];
+ time_t last_updated;
+ struct cs_fsm fsm;
+
+ corosync_timer_handle_t check_timer;
+ uint64_t check_timeout;
+ icmap_track_t icmap_track;
+};
+
+LOGSYS_DECLARE_SUBSYS("WD");
+
+/*
+ * Service Interfaces required by service_message_handler struct
+ */
+static char *wd_exec_init_fn (struct corosync_api_v1 *corosync_api);
+static int wd_exec_exit_fn (void);
+static void wd_resource_check_fn (void* resource_ref);
+
+static struct corosync_api_v1 *api;
+#define WD_DEFAULT_TIMEOUT_SEC 6
+#define WD_DEFAULT_TIMEOUT_MS (WD_DEFAULT_TIMEOUT_SEC * CS_TIME_MS_IN_SEC)
+#define WD_MIN_TIMEOUT_MS 500
+#define WD_MAX_TIMEOUT_MS (120 * CS_TIME_MS_IN_SEC)
+static uint32_t watchdog_timeout = WD_DEFAULT_TIMEOUT_SEC;
+static uint64_t tickle_timeout = (WD_DEFAULT_TIMEOUT_MS / 2);
+static int dog = -1;
+static corosync_timer_handle_t wd_timer;
+static int watchdog_ok = 1;
+static char *watchdog_device = NULL;
+
+struct corosync_service_engine wd_service_engine = {
+ .name = "corosync watchdog service",
+ .id = WD_SERVICE,
+ .priority = 1,
+ .private_data_size = 0,
+ .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED,
+ .lib_init_fn = NULL,
+ .lib_exit_fn = NULL,
+ .lib_engine = NULL,
+ .lib_engine_count = 0,
+ .exec_engine = NULL,
+ .exec_engine_count = 0,
+ .confchg_fn = NULL,
+ .exec_init_fn = wd_exec_init_fn,
+ .exec_exit_fn = wd_exec_exit_fn,
+ .exec_dump_fn = NULL
+};
+
+static QB_LIST_DECLARE (confchg_notify);
+
+/*
+ * F S M
+ */
+static void wd_config_changed (struct cs_fsm* fsm, int32_t event, void * data);
+static void wd_resource_failed (struct cs_fsm* fsm, int32_t event, void * data);
+
+enum wd_resource_state {
+ WD_S_RUNNING,
+ WD_S_FAILED,
+ WD_S_STOPPED
+};
+
+enum wd_resource_event {
+ WD_E_FAILURE,
+ WD_E_CONFIG_CHANGED
+};
+
+const char * wd_running_str = "running";
+const char * wd_failed_str = "failed";
+const char * wd_failure_str = "failure";
+const char * wd_stopped_str = "stopped";
+const char * wd_config_changed_str = "config_changed";
+
+struct cs_fsm_entry wd_fsm_table[] = {
+ { WD_S_STOPPED, WD_E_CONFIG_CHANGED, wd_config_changed, {WD_S_STOPPED, WD_S_RUNNING, -1} },
+ { WD_S_STOPPED, WD_E_FAILURE, NULL, {-1} },
+ { WD_S_RUNNING, WD_E_CONFIG_CHANGED, wd_config_changed, {WD_S_RUNNING, WD_S_STOPPED, -1} },
+ { WD_S_RUNNING, WD_E_FAILURE, wd_resource_failed, {WD_S_FAILED, -1} },
+ { WD_S_FAILED, WD_E_CONFIG_CHANGED, wd_config_changed, {WD_S_RUNNING, WD_S_STOPPED, -1} },
+ { WD_S_FAILED, WD_E_FAILURE, NULL, {-1} },
+};
+
+struct corosync_service_engine *wd_get_service_engine_ver0 (void)
+{
+ return (&wd_service_engine);
+}
+
+static const char * wd_res_state_to_str(struct cs_fsm* fsm,
+ int32_t state)
+{
+ switch (state) {
+ case WD_S_STOPPED:
+ return wd_stopped_str;
+ break;
+ case WD_S_RUNNING:
+ return wd_running_str;
+ break;
+ case WD_S_FAILED:
+ return wd_failed_str;
+ break;
+ }
+ return NULL;
+}
+
+static const char * wd_res_event_to_str(struct cs_fsm* fsm,
+ int32_t event)
+{
+ switch (event) {
+ case WD_E_CONFIG_CHANGED:
+ return wd_config_changed_str;
+ break;
+ case WD_E_FAILURE:
+ return wd_failure_str;
+ break;
+ }
+ return NULL;
+}
+
+static void wd_fsm_cb (struct cs_fsm *fsm, int cb_event, int32_t curr_state,
+ int32_t next_state, int32_t fsm_event, void *data)
+{
+ switch (cb_event) {
+ case CS_FSM_CB_EVENT_PROCESS_NF:
+ log_printf (LOGSYS_LEVEL_ERROR, "Fsm:%s could not find event \"%s\" in state \"%s\"",
+ fsm->name, fsm->event_to_str(fsm, fsm_event), fsm->state_to_str(fsm, curr_state));
+ corosync_exit_error(COROSYNC_DONE_FATAL_ERR);
+ break;
+ case CS_FSM_CB_EVENT_STATE_SET:
+ log_printf (LOGSYS_LEVEL_INFO, "Fsm:%s event \"%s\", state \"%s\" --> \"%s\"",
+ fsm->name,
+ fsm->event_to_str(fsm, fsm_event),
+ fsm->state_to_str(fsm, fsm->table[fsm->curr_entry].curr_state),
+ fsm->state_to_str(fsm, next_state));
+ break;
+ case CS_FSM_CB_EVENT_STATE_SET_NF:
+ log_printf (LOGSYS_LEVEL_CRIT, "Fsm:%s Can't change state from \"%s\" to \"%s\" (event was \"%s\")",
+ fsm->name,
+ fsm->state_to_str(fsm, fsm->table[fsm->curr_entry].curr_state),
+ fsm->state_to_str(fsm, next_state),
+ fsm->event_to_str(fsm, fsm_event));
+ corosync_exit_error(COROSYNC_DONE_FATAL_ERR);
+ break;
+ default:
+ log_printf (LOGSYS_LEVEL_CRIT, "Fsm: Unknown callback event!");
+ corosync_exit_error(COROSYNC_DONE_FATAL_ERR);
+ break;
+ }
+}
+
+/*
+ * returns (CS_TRUE == OK, CS_FALSE == failed)
+ */
+static int32_t wd_resource_state_is_ok (struct resource *ref)
+{
+ char* state = NULL;
+ uint64_t last_updated;
+ uint64_t my_time;
+ uint64_t allowed_period;
+ char key_name[ICMAP_KEYNAME_MAXLEN];
+
+ if ((snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "%s%s", ref->res_path, "last_updated") >= ICMAP_KEYNAME_MAXLEN) ||
+ (icmap_get_uint64(key_name, &last_updated) != CS_OK)) {
+ /* key does not exist.
+ */
+ return CS_FALSE;
+ }
+
+ if ((snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "%s%s", ref->res_path, "state") >= ICMAP_KEYNAME_MAXLEN) ||
+ (icmap_get_string(key_name, &state) != CS_OK || strcmp(state, "disabled") == 0)) {
+ /* key does not exist.
+ */
+ if (state != NULL)
+ free(state);
+
+ return CS_FALSE;
+ }
+
+ if (last_updated == 0) {
+ /* initial value */
+ free(state);
+ return CS_TRUE;
+ }
+
+ my_time = cs_timestamp_get();
+
+ /*
+ * Here we check that the monitor has written a timestamp within the poll_period
+ * plus a grace factor of (0.5 * poll_period).
+ */
+ allowed_period = (ref->check_timeout * MILLI_2_NANO_SECONDS * 3) / 2;
+ if ((last_updated + allowed_period) < my_time) {
+ log_printf (LOGSYS_LEVEL_ERROR,
+ "last_updated %"PRIu64" ms too late, period:%"PRIu64".",
+ (uint64_t)(my_time/MILLI_2_NANO_SECONDS - ((last_updated + allowed_period) / MILLI_2_NANO_SECONDS)),
+ ref->check_timeout);
+ free(state);
+ return CS_FALSE;
+ }
+
+ if (strcmp (state, wd_failed_str) == 0) {
+ free(state);
+ return CS_FALSE;
+ }
+
+ free(state);
+ return CS_TRUE;
+}
+
+static void wd_config_changed (struct cs_fsm* fsm, int32_t event, void * data)
+{
+ char *state;
+ uint64_t tmp_value;
+ uint64_t next_timeout;
+ struct resource *ref = (struct resource*)data;
+ char key_name[ICMAP_KEYNAME_MAXLEN];
+
+ next_timeout = ref->check_timeout;
+
+ if ((snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "%s%s", ref->res_path, "poll_period") >= ICMAP_KEYNAME_MAXLEN) ||
+ (icmap_get_uint64(ref->res_path, &tmp_value) == CS_OK)) {
+ if (tmp_value >= WD_MIN_TIMEOUT_MS && tmp_value <= WD_MAX_TIMEOUT_MS) {
+ log_printf (LOGSYS_LEVEL_DEBUG,
+ "poll_period changing from:%"PRIu64" to %"PRIu64".",
+ ref->check_timeout, tmp_value);
+ /*
+ * To easy in the transition between poll_period's we are going
+ * to make the first timeout the bigger of the new and old value.
+ * This is to give the monitoring system time to adjust.
+ */
+ next_timeout = CS_MAX(tmp_value, ref->check_timeout);
+ ref->check_timeout = tmp_value;
+ } else {
+ log_printf (LOGSYS_LEVEL_WARNING,
+ "Could NOT use poll_period:%"PRIu64" ms for resource %s",
+ tmp_value, ref->name);
+ }
+ }
+
+ if ((snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "%s%s", ref->res_path, "recovery") >= ICMAP_KEYNAME_MAXLEN) ||
+ (icmap_get_string(key_name, &ref->recovery) != CS_OK)) {
+ /* key does not exist.
+ */
+ log_printf (LOGSYS_LEVEL_WARNING,
+ "resource %s missing a recovery key.", ref->name);
+ cs_fsm_state_set(&ref->fsm, WD_S_STOPPED, ref, wd_fsm_cb);
+ return;
+ }
+ if ((snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "%s%s", ref->res_path, "state") >= ICMAP_KEYNAME_MAXLEN) ||
+ (icmap_get_string(key_name, &state) != CS_OK)) {
+ /* key does not exist.
+ */
+ log_printf (LOGSYS_LEVEL_WARNING,
+ "resource %s missing a state key.", ref->name);
+ cs_fsm_state_set(&ref->fsm, WD_S_STOPPED, ref, wd_fsm_cb);
+ return;
+ }
+ if (ref->check_timer) {
+ api->timer_delete(ref->check_timer);
+ ref->check_timer = 0;
+ }
+
+ if (strcmp(wd_stopped_str, state) == 0) {
+ cs_fsm_state_set(&ref->fsm, WD_S_STOPPED, ref, wd_fsm_cb);
+ } else {
+ api->timer_add_duration(next_timeout * MILLI_2_NANO_SECONDS,
+ ref, wd_resource_check_fn, &ref->check_timer);
+ cs_fsm_state_set(&ref->fsm, WD_S_RUNNING, ref, wd_fsm_cb);
+ }
+ free(state);
+}
+
+static void wd_resource_failed (struct cs_fsm* fsm, int32_t event, void * data)
+{
+ struct resource* ref = (struct resource*)data;
+
+ if (ref->check_timer) {
+ api->timer_delete(ref->check_timer);
+ ref->check_timer = 0;
+ }
+
+ log_printf (LOGSYS_LEVEL_CRIT, "%s resource \"%s\" failed!",
+ ref->recovery, (char*)ref->name);
+ if (strcmp (ref->recovery, "watchdog") == 0 ||
+ strcmp (ref->recovery, "quit") == 0) {
+ watchdog_ok = 0;
+ }
+ else if (strcmp (ref->recovery, "reboot") == 0) {
+ reboot(RB_AUTOBOOT);
+ }
+ else if (strcmp (ref->recovery, "shutdown") == 0) {
+ reboot(RB_POWER_OFF);
+ }
+ cs_fsm_state_set(fsm, WD_S_FAILED, data, wd_fsm_cb);
+}
+
+static void wd_key_changed(
+ int32_t event,
+ const char *key_name,
+ struct icmap_notify_value new_val,
+ struct icmap_notify_value old_val,
+ void *user_data)
+{
+ struct resource* ref = (struct resource*)user_data;
+ char *last_key_part;
+
+ if (ref == NULL) {
+ return ;
+ }
+
+ last_key_part = strrchr(key_name, '.');
+ if (last_key_part == NULL) {
+ return ;
+ }
+ last_key_part++;
+
+ if (event == ICMAP_TRACK_ADD || event == ICMAP_TRACK_MODIFY) {
+ if (strcmp(last_key_part, "last_updated") == 0 ||
+ strcmp(last_key_part, "current") == 0) {
+ return;
+ }
+
+ cs_fsm_process(&ref->fsm, WD_E_CONFIG_CHANGED, ref, wd_fsm_cb);
+ }
+
+ if (event == ICMAP_TRACK_DELETE && ref != NULL) {
+ if (strcmp(last_key_part, "state") != 0) {
+ return ;
+ }
+
+ log_printf (LOGSYS_LEVEL_WARNING,
+ "resource \"%s\" deleted from cmap!",
+ ref->name);
+
+ api->timer_delete(ref->check_timer);
+ ref->check_timer = 0;
+ icmap_track_delete(ref->icmap_track);
+
+ free(ref);
+ }
+}
+
+static void wd_resource_check_fn (void* resource_ref)
+{
+ struct resource* ref = (struct resource*)resource_ref;
+
+ if (wd_resource_state_is_ok (ref) == CS_FALSE) {
+ cs_fsm_process(&ref->fsm, WD_E_FAILURE, ref, wd_fsm_cb);
+ return;
+ }
+ api->timer_add_duration(ref->check_timeout*MILLI_2_NANO_SECONDS,
+ ref, wd_resource_check_fn, &ref->check_timer);
+}
+
+/*
+ * return 0 - fully configured
+ * return -1 - partially configured
+ */
+static int32_t wd_resource_create (char *res_path, char *res_name)
+{
+ char *state;
+ uint64_t tmp_value;
+ struct resource *ref = calloc (1, sizeof (struct resource));
+ char key_name[ICMAP_KEYNAME_MAXLEN];
+
+ strcpy(ref->res_path, res_path);
+ ref->check_timeout = WD_DEFAULT_TIMEOUT_MS;
+ ref->check_timer = 0;
+
+ strcpy(ref->name, res_name);
+ ref->fsm.name = ref->name;
+ ref->fsm.table = wd_fsm_table;
+ ref->fsm.entries = sizeof(wd_fsm_table) / sizeof(struct cs_fsm_entry);
+ ref->fsm.curr_entry = 0;
+ ref->fsm.curr_state = WD_S_STOPPED;
+ ref->fsm.state_to_str = wd_res_state_to_str;
+ ref->fsm.event_to_str = wd_res_event_to_str;
+
+ snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "%s%s", res_path, "poll_period");
+ if (icmap_get_uint64(key_name, &tmp_value) != CS_OK) {
+ icmap_set_uint64(key_name, ref->check_timeout);
+ } else {
+ if (tmp_value >= WD_MIN_TIMEOUT_MS && tmp_value <= WD_MAX_TIMEOUT_MS) {
+ ref->check_timeout = tmp_value;
+ } else {
+ log_printf (LOGSYS_LEVEL_WARNING,
+ "Could NOT use poll_period:%"PRIu64" ms for resource %s",
+ tmp_value, ref->name);
+ }
+ }
+
+ icmap_track_add(res_path,
+ ICMAP_TRACK_ADD | ICMAP_TRACK_MODIFY | ICMAP_TRACK_DELETE | ICMAP_TRACK_PREFIX,
+ wd_key_changed,
+ ref, &ref->icmap_track);
+
+ snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "%s%s", res_path, "recovery");
+ if (icmap_get_string(key_name, &ref->recovery) != CS_OK) {
+ /* key does not exist.
+ */
+ log_printf (LOGSYS_LEVEL_WARNING,
+ "resource %s missing a recovery key.", ref->name);
+ return -1;
+ }
+ snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "%s%s", res_path, "state");
+ if (icmap_get_string(key_name, &state) != CS_OK) {
+ /* key does not exist.
+ */
+ log_printf (LOGSYS_LEVEL_WARNING,
+ "resource %s missing a state key.", ref->name);
+ return -1;
+ }
+
+ snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "%s%s", res_path, "last_updated");
+ if (icmap_get_uint64(key_name, &tmp_value) != CS_OK) {
+ /* key does not exist.
+ */
+ ref->last_updated = 0;
+ } else {
+ ref->last_updated = tmp_value;
+ }
+
+ /*
+ * delay the first check to give the monitor time to start working.
+ */
+ tmp_value = CS_MAX(ref->check_timeout * 2, WD_DEFAULT_TIMEOUT_MS);
+ api->timer_add_duration(tmp_value * MILLI_2_NANO_SECONDS,
+ ref,
+ wd_resource_check_fn, &ref->check_timer);
+
+ cs_fsm_state_set(&ref->fsm, WD_S_RUNNING, ref, wd_fsm_cb);
+ return 0;
+}
+
+
+static void wd_tickle_fn (void* arg)
+{
+ ENTER();
+
+ if (watchdog_ok) {
+ if (dog > 0) {
+ ioctl(dog, WDIOC_KEEPALIVE, &watchdog_ok);
+ }
+ api->timer_add_duration(tickle_timeout*MILLI_2_NANO_SECONDS, NULL,
+ wd_tickle_fn, &wd_timer);
+ }
+ else {
+ log_printf (LOGSYS_LEVEL_ALERT, "NOT tickling the watchdog!");
+ }
+
+}
+
+static void wd_resource_created_cb(
+ int32_t event,
+ const char *key_name,
+ struct icmap_notify_value new_val,
+ struct icmap_notify_value old_val,
+ void *user_data)
+{
+ char res_name[ICMAP_KEYNAME_MAXLEN];
+ char res_type[ICMAP_KEYNAME_MAXLEN];
+ char tmp_key[ICMAP_KEYNAME_MAXLEN];
+ int res;
+
+ if (event != ICMAP_TRACK_ADD) {
+ return ;
+ }
+
+ res = sscanf(key_name, "resources.%[^.].%[^.].%[^.]", res_type, res_name, tmp_key);
+ if (res != 3) {
+ return ;
+ }
+
+ if (strcmp(tmp_key, "state") != 0) {
+ return ;
+ }
+
+ snprintf(tmp_key, ICMAP_KEYNAME_MAXLEN, "resources.%s.%s.", res_type, res_name);
+ wd_resource_create (tmp_key, res_name);
+}
+
+static void wd_scan_resources (void)
+{
+ int res_count = 0;
+ icmap_track_t icmap_track = NULL;
+ icmap_iter_t iter;
+ const char *key_name;
+ int res;
+ char res_name[ICMAP_KEYNAME_MAXLEN];
+ char res_type[ICMAP_KEYNAME_MAXLEN];
+ char tmp_key[ICMAP_KEYNAME_MAXLEN];
+
+ ENTER();
+
+ iter = icmap_iter_init("resources.");
+ while ((key_name = icmap_iter_next(iter, NULL, NULL)) != NULL) {
+ res = sscanf(key_name, "resources.%[^.].%[^.].%[^.]", res_type, res_name, tmp_key);
+ if (res != 3) {
+ continue ;
+ }
+
+ if (strcmp(tmp_key, "state") != 0) {
+ continue ;
+ }
+
+ snprintf(tmp_key, ICMAP_KEYNAME_MAXLEN, "resources.%s.%s.", res_type, res_name);
+ if (wd_resource_create (tmp_key, res_name) == 0) {
+ res_count++;
+ }
+ }
+ icmap_iter_finalize(iter);
+
+ icmap_track_add("resources.process.", ICMAP_TRACK_ADD | ICMAP_TRACK_PREFIX,
+ wd_resource_created_cb, NULL, &icmap_track);
+ icmap_track_add("resources.system.", ICMAP_TRACK_ADD | ICMAP_TRACK_PREFIX,
+ wd_resource_created_cb, NULL, &icmap_track);
+
+ if (res_count == 0) {
+ log_printf (LOGSYS_LEVEL_INFO, "no resources configured.");
+ }
+}
+
+
+static void watchdog_timeout_apply (uint32_t new)
+{
+ struct watchdog_info ident;
+ uint32_t original_timeout = 0;
+
+ if (dog > 0) {
+ ioctl(dog, WDIOC_GETTIMEOUT, &original_timeout);
+ }
+
+ if (new == original_timeout) {
+ return;
+ }
+
+ watchdog_timeout = new;
+
+ if (dog > 0) {
+ ioctl(dog, WDIOC_GETSUPPORT, &ident);
+ if (ident.options & WDIOF_SETTIMEOUT) {
+ /* yay! the dog is trained.
+ */
+ ioctl(dog, WDIOC_SETTIMEOUT, &watchdog_timeout);
+ }
+ ioctl(dog, WDIOC_GETTIMEOUT, &watchdog_timeout);
+ }
+
+ if (watchdog_timeout == new) {
+ tickle_timeout = (watchdog_timeout * CS_TIME_MS_IN_SEC)/ 2;
+
+ /* reset the tickle timer in case it was reduced.
+ */
+ api->timer_delete (wd_timer);
+ api->timer_add_duration(tickle_timeout*MILLI_2_NANO_SECONDS, NULL,
+ wd_tickle_fn, &wd_timer);
+
+ log_printf (LOGSYS_LEVEL_DEBUG, "The Watchdog timeout is %d seconds", watchdog_timeout);
+ log_printf (LOGSYS_LEVEL_DEBUG, "The tickle timeout is %"PRIu64" ms", tickle_timeout);
+ } else {
+ log_printf (LOGSYS_LEVEL_WARNING,
+ "Could not change the Watchdog timeout from %d to %d seconds",
+ original_timeout, new);
+ }
+
+}
+
+static int setup_watchdog(void)
+{
+ struct watchdog_info ident;
+ char *str;
+
+ ENTER();
+
+ if (icmap_get_string("resources.watchdog_device", &str) == CS_OK) {
+ if (str[0] == 0 || strcmp (str, "off") == 0) {
+ log_printf (LOGSYS_LEVEL_WARNING, "Watchdog disabled by configuration");
+ free(str);
+ dog = -1;
+ return -1;
+ } else {
+ watchdog_device = str;
+ }
+ } else {
+ log_printf (LOGSYS_LEVEL_WARNING, "Watchdog not enabled by configuration");
+ dog = -1;
+ return -1;
+ }
+
+ if (access (watchdog_device, W_OK) != 0) {
+ log_printf (LOGSYS_LEVEL_WARNING, "No watchdog %s, try modprobe <a watchdog>", watchdog_device);
+ dog = -1;
+ return -1;
+ }
+
+ /* here goes, lets hope they have "Magic Close"
+ */
+ dog = open(watchdog_device, O_WRONLY);
+
+ if (dog == -1) {
+ log_printf (LOGSYS_LEVEL_WARNING, "Watchdog %s exists but couldn't be opened.", watchdog_device);
+ dog = -1;
+ return -1;
+ }
+
+ /* Right we have the dog.
+ * Lets see what breed it is.
+ */
+
+ ioctl(dog, WDIOC_GETSUPPORT, &ident);
+ log_printf (LOGSYS_LEVEL_INFO, "Watchdog %s is now being tickled by corosync.", watchdog_device);
+ log_printf (LOGSYS_LEVEL_DEBUG, "%s", ident.identity);
+
+ watchdog_timeout_apply (watchdog_timeout);
+
+ ioctl(dog, WDIOC_SETOPTIONS, WDIOS_ENABLECARD);
+
+ return 0;
+}
+
+static void wd_top_level_key_changed(
+ int32_t event,
+ const char *key_name,
+ struct icmap_notify_value new_val,
+ struct icmap_notify_value old_val,
+ void *user_data)
+{
+ uint32_t tmp_value_32;
+
+ ENTER();
+
+ if (icmap_get_uint32("resources.watchdog_timeout", &tmp_value_32) == CS_OK) {
+ if (tmp_value_32 >= 2 && tmp_value_32 <= 120) {
+ watchdog_timeout_apply (tmp_value_32);
+ return;
+ }
+ }
+
+ log_printf (LOGSYS_LEVEL_WARNING,
+ "Set watchdog_timeout is out of range (2..120).");
+ icmap_set_uint32("resources.watchdog_timeout", watchdog_timeout);
+}
+
+static void watchdog_timeout_get_initial (void)
+{
+ uint32_t tmp_value_32;
+ icmap_track_t icmap_track = NULL;
+
+ ENTER();
+
+ if (icmap_get_uint32("resources.watchdog_timeout", &tmp_value_32) != CS_OK) {
+ watchdog_timeout_apply (WD_DEFAULT_TIMEOUT_SEC);
+
+ icmap_set_uint32("resources.watchdog_timeout", watchdog_timeout);
+ }
+ else {
+ if (tmp_value_32 >= 2 && tmp_value_32 <= 120) {
+ watchdog_timeout_apply (tmp_value_32);
+ }
+ else {
+ log_printf (LOGSYS_LEVEL_WARNING,
+ "Set watchdog_timeout is out of range (2..120).");
+ log_printf (LOGSYS_LEVEL_INFO,
+ "use default value %d seconds.", WD_DEFAULT_TIMEOUT_SEC);
+ watchdog_timeout_apply (WD_DEFAULT_TIMEOUT_SEC);
+ icmap_set_uint32("resources.watchdog_timeout", watchdog_timeout);
+ }
+ }
+
+ icmap_track_add("resources.watchdog_timeout", ICMAP_TRACK_MODIFY,
+ wd_top_level_key_changed, NULL, &icmap_track);
+
+}
+
+static char *wd_exec_init_fn (struct corosync_api_v1 *corosync_api)
+{
+
+ ENTER();
+
+ api = corosync_api;
+
+ watchdog_timeout_get_initial();
+
+ setup_watchdog();
+
+ wd_scan_resources();
+
+ return NULL;
+}
+
+static int wd_exec_exit_fn (void)
+{
+ char magic = 'V';
+ ENTER();
+
+ if (dog > 0) {
+ log_printf (LOGSYS_LEVEL_INFO, "magically closing the watchdog.");
+ if (write (dog, &magic, 1) == -1) {
+ log_printf (LOGSYS_LEVEL_ERROR, "failed to write %c to dog(%d).", magic, dog);
+ }
+ }
+ return 0;
+}
+
+
diff --git a/include/Makefile.am b/include/Makefile.am
new file mode 100644
index 0000000..4b6697e
--- /dev/null
+++ b/include/Makefile.am
@@ -0,0 +1,47 @@
+# Copyright (c) 2009 Red Hat, Inc.
+#
+# Authors: Andrew Beekhof
+# Steven Dake (sdake@redhat.com)
+#
+# This software licensed under BSD license, the text of which follows:
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# - Redistributions of source code must retain the above copyright notice,
+# this list of conditions and the following disclaimer.
+# - Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+# - Neither the name of the MontaVista Software, Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from this
+# software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+# THE POSSIBILITY OF SUCH DAMAGE.
+
+MAINTAINERCLEANFILES = Makefile.in corosync/config.h.in
+
+CS_H = hdb.h cpg.h cfg.h corodefs.h \
+ corotypes.h quorum.h votequorum.h sam.h cmap.h
+
+CS_INTERNAL_H = ipc_cfg.h ipc_cpg.h ipc_quorum.h \
+ quorum.h sq.h ipc_votequorum.h ipc_cmap.h \
+ logsys.h coroapi.h icmap.h mar_gen.h swab.h
+
+TOTEM_H = totem.h totemip.h totempg.h totemstats.h
+
+EXTRA_DIST = $(noinst_HEADERS)
+
+noinst_HEADERS = $(CS_INTERNAL_H:%=corosync/%) $(TOTEM_H:%=corosync/totem/%)
+
+nobase_include_HEADERS = $(CS_H:%=corosync/%)
diff --git a/include/Makefile.in b/include/Makefile.in
new file mode 100644
index 0000000..75b2d1c
--- /dev/null
+++ b/include/Makefile.in
@@ -0,0 +1,646 @@
+# Makefile.in generated by automake 1.13.4 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+# Copyright (c) 2009 Red Hat, Inc.
+#
+# Authors: Andrew Beekhof
+# Steven Dake (sdake@redhat.com)
+#
+# This software licensed under BSD license, the text of which follows:
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# - Redistributions of source code must retain the above copyright notice,
+# this list of conditions and the following disclaimer.
+# - Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+# - Neither the name of the MontaVista Software, Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from this
+# software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+# THE POSSIBILITY OF SUCH DAMAGE.
+
+VPATH = @srcdir@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = include
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+ $(nobase_include_HEADERS) $(noinst_HEADERS)
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/lib/libcfg.verso $(top_srcdir)/lib/libcpg.verso \
+ $(top_srcdir)/lib/libquorum.verso \
+ $(top_srcdir)/lib/libsam.verso \
+ $(top_srcdir)/lib/libvotequorum.verso \
+ $(top_srcdir)/lib/libcmap.verso $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/include/corosync/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+SOURCES =
+DIST_SOURCES =
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+am__installdirs = "$(DESTDIR)$(includedir)"
+HEADERS = $(nobase_include_HEADERS) $(noinst_HEADERS)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALLOCA = @ALLOCA@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUGTOOL = @AUGTOOL@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BASHPATH = @BASHPATH@
+BINDGEN = @BINDGEN@
+CARGO = @CARGO@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFG_SONAME = @CFG_SONAME@
+CFLAGS = @CFLAGS@
+CLIPPY = @CLIPPY@
+CMAP_SONAME = @CMAP_SONAME@
+COROSYSCONFDIR = @COROSYSCONFDIR@
+CPG_SONAME = @CPG_SONAME@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DBUS_CFLAGS = @DBUS_CFLAGS@
+DBUS_LIBS = @DBUS_LIBS@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DOT = @DOT@
+DOXYGEN = @DOXYGEN@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GREP = @GREP@
+GROFF = @GROFF@
+INITCONFIGDIR = @INITCONFIGDIR@
+INITDDIR = @INITDDIR@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBQB_CFLAGS = @LIBQB_CFLAGS@
+LIBQB_LIBS = @LIBQB_LIBS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LINT_FLAGS = @LINT_FLAGS@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LOGDIR = @LOGDIR@
+LOGROTATEDIR = @LOGROTATEDIR@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+QUORUM_SONAME = @QUORUM_SONAME@
+RANLIB = @RANLIB@
+RUSTC = @RUSTC@
+RUSTDOC = @RUSTDOC@
+RUSTFMT = @RUSTFMT@
+RUST_FLAGS = @RUST_FLAGS@
+RUST_TARGET_DIR = @RUST_TARGET_DIR@
+SAM_SONAME = @SAM_SONAME@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SNMPCONFIG = @SNMPCONFIG@
+SNMP_LIBS = @SNMP_LIBS@
+SOMAJOR = @SOMAJOR@
+SOMICRO = @SOMICRO@
+SOMINOR = @SOMINOR@
+SONAME = @SONAME@
+STRIP = @STRIP@
+SYSTEMDDIR = @SYSTEMDDIR@
+VERSCRIPT_LDFLAGS = @VERSCRIPT_LDFLAGS@
+VERSION = @VERSION@
+VOTEQUORUM_SONAME = @VOTEQUORUM_SONAME@
+WITH_LIST = @WITH_LIST@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+corosyncrustver = @corosyncrustver@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+knet_CFLAGS = @knet_CFLAGS@
+knet_LIBS = @knet_LIBS@
+libdir = @libdir@
+libexecdir = @libexecdir@
+libsystemd_CFLAGS = @libsystemd_CFLAGS@
+libsystemd_LIBS = @libsystemd_LIBS@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+nozzle_CFLAGS = @nozzle_CFLAGS@
+nozzle_LIBS = @nozzle_LIBS@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+statgrab_CFLAGS = @statgrab_CFLAGS@
+statgrab_LIBS = @statgrab_LIBS@
+statgrabge090_CFLAGS = @statgrabge090_CFLAGS@
+statgrabge090_LIBS = @statgrabge090_LIBS@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+MAINTAINERCLEANFILES = Makefile.in corosync/config.h.in
+CS_H = hdb.h cpg.h cfg.h corodefs.h \
+ corotypes.h quorum.h votequorum.h sam.h cmap.h
+
+CS_INTERNAL_H = ipc_cfg.h ipc_cpg.h ipc_quorum.h \
+ quorum.h sq.h ipc_votequorum.h ipc_cmap.h \
+ logsys.h coroapi.h icmap.h mar_gen.h swab.h
+
+TOTEM_H = totem.h totemip.h totempg.h totemstats.h
+EXTRA_DIST = $(noinst_HEADERS)
+noinst_HEADERS = $(CS_INTERNAL_H:%=corosync/%) $(TOTEM_H:%=corosync/totem/%)
+nobase_include_HEADERS = $(CS_H:%=corosync/%)
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign include/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign include/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+install-nobase_includeHEADERS: $(nobase_include_HEADERS)
+ @$(NORMAL_INSTALL)
+ @list='$(nobase_include_HEADERS)'; test -n "$(includedir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(includedir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(includedir)" || exit 1; \
+ fi; \
+ $(am__nobase_list) | while read dir files; do \
+ xfiles=; for file in $$files; do \
+ if test -f "$$file"; then xfiles="$$xfiles $$file"; \
+ else xfiles="$$xfiles $(srcdir)/$$file"; fi; done; \
+ test -z "$$xfiles" || { \
+ test "x$$dir" = x. || { \
+ echo " $(MKDIR_P) '$(DESTDIR)$(includedir)/$$dir'"; \
+ $(MKDIR_P) "$(DESTDIR)$(includedir)/$$dir"; }; \
+ echo " $(INSTALL_HEADER) $$xfiles '$(DESTDIR)$(includedir)/$$dir'"; \
+ $(INSTALL_HEADER) $$xfiles "$(DESTDIR)$(includedir)/$$dir" || exit $$?; }; \
+ done
+
+uninstall-nobase_includeHEADERS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(nobase_include_HEADERS)'; test -n "$(includedir)" || list=; \
+ $(am__nobase_strip_setup); files=`$(am__nobase_strip)`; \
+ dir='$(DESTDIR)$(includedir)'; $(am__uninstall_files_from_dir)
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(HEADERS)
+installdirs:
+ for dir in "$(DESTDIR)$(includedir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+ -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+clean: clean-am
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-am
+ -rm -f Makefile
+distclean-am: clean-am distclean-generic distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-nobase_includeHEADERS
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-nobase_includeHEADERS
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
+ clean-libtool cscopelist-am ctags ctags-am distclean \
+ distclean-generic distclean-libtool distclean-tags distdir dvi \
+ dvi-am html html-am info info-am install install-am \
+ install-data install-data-am install-dvi install-dvi-am \
+ install-exec install-exec-am install-html install-html-am \
+ install-info install-info-am install-man \
+ install-nobase_includeHEADERS install-pdf install-pdf-am \
+ install-ps install-ps-am install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-generic \
+ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \
+ uninstall-am uninstall-nobase_includeHEADERS
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/include/corosync/cfg.h b/include/corosync/cfg.h
new file mode 100644
index 0000000..f3bce09
--- /dev/null
+++ b/include/corosync/cfg.h
@@ -0,0 +1,315 @@
+/*
+ * Copyright (c) 2005 MontaVista Software, Inc.
+ * Copyright (c) 2006-2013 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Author: Steven Dake (sdake@redhat.com)
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of the MontaVista Software, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef COROSYNC_CFG_H_DEFINED
+#define COROSYNC_CFG_H_DEFINED
+
+#include <netinet/in.h>
+#include <corosync/corotypes.h>
+
+typedef uint64_t corosync_cfg_handle_t;
+
+/**
+ * Shutdown types.
+ */
+typedef enum {
+ /**
+ * REQUEST is the normal shutdown.
+ * Other daemons will be consulted.
+ */
+ COROSYNC_CFG_SHUTDOWN_FLAG_REQUEST = 0,
+ /**
+ * REGARDLESS will tell other daemons but ignore their opinions.
+ */
+ COROSYNC_CFG_SHUTDOWN_FLAG_REGARDLESS = 1,
+ /**
+ * IMMEDIATE will shut down straight away
+ * (but still tell other nodes).
+ */
+ COROSYNC_CFG_SHUTDOWN_FLAG_IMMEDIATE = 2,
+} corosync_cfg_shutdown_flags_t;
+
+/**
+ * @brief enum corosync_cfg_shutdown_reply_flags_t
+ */
+typedef enum {
+ COROSYNC_CFG_SHUTDOWN_FLAG_NO = 0,
+ COROSYNC_CFG_SHUTDOWN_FLAG_YES = 1,
+} corosync_cfg_shutdown_reply_flags_t;
+
+/**
+ * @brief corosync_cfg_shutdown_callback_t callback
+ */
+typedef void (*corosync_cfg_shutdown_callback_t) (
+ corosync_cfg_handle_t cfg_handle,
+ corosync_cfg_shutdown_flags_t flags);
+
+/**
+ * @brief struct corosync_cfg_shutdown_callback_t
+ */
+typedef struct {
+ corosync_cfg_shutdown_callback_t corosync_cfg_shutdown_callback;
+} corosync_cfg_callbacks_t;
+
+/**
+ * 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
+{
+ int address_length; /**< @todo FIXME: set but never used */
+ char address[sizeof(struct sockaddr_in6)];
+} corosync_cfg_node_address_t;
+
+/*
+ * Interfaces
+ */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief corosync_cfg_initialize
+ * @param cfg_handle
+ * @param cfg_callbacks
+ * @return
+ */
+cs_error_t
+corosync_cfg_initialize (
+ corosync_cfg_handle_t *cfg_handle,
+ const corosync_cfg_callbacks_t *cfg_callbacks);
+
+/**
+ * @brief corosync_cfg_fd_get
+ * @param cfg_handle
+ * @param selection_fd
+ * @return
+ */
+cs_error_t
+corosync_cfg_fd_get (
+ corosync_cfg_handle_t cfg_handle,
+ int32_t *selection_fd);
+
+/**
+ * @brief corosync_cfg_dispatch
+ * @param cfg_handle
+ * @param dispatch_flags
+ * @return
+ */
+cs_error_t
+corosync_cfg_dispatch (
+ corosync_cfg_handle_t cfg_handle,
+ cs_dispatch_flags_t dispatch_flags);
+
+/**
+ * @brief corosync_cfg_finalize
+ * @param cfg_handle
+ * @return
+ */
+cs_error_t
+corosync_cfg_finalize (
+ corosync_cfg_handle_t cfg_handle);
+
+/**
+ * @brief corosync_cfg_ring_status_get
+ * @param cfg_handle
+ * @param interface_names
+ * @param status
+ * @param interface_count
+ * @return
+ */
+cs_error_t
+corosync_cfg_ring_status_get (
+ corosync_cfg_handle_t cfg_handle,
+ char ***interface_names,
+ char ***status,
+ unsigned int *interface_count);
+
+typedef enum {
+ CFG_NODE_STATUS_V1 = 1,
+} corosync_cfg_node_status_version_t;
+
+#define CFG_MAX_HOST_LEN 256
+#define CFG_MAX_LINKS 8
+
+struct corosync_knet_link_status_v1 {
+ uint8_t enabled; /* link is configured and admin enabled for traffic */
+ uint8_t connected; /* link is connected for data (local view) */
+ uint8_t dynconnected; /* link has been activated by remote dynip */
+ unsigned int mtu; /* current detected MTU on this link */
+ char src_ipaddr[CFG_MAX_HOST_LEN];
+ char dst_ipaddr[CFG_MAX_HOST_LEN];
+};
+
+struct corosync_cfg_node_status_v1 {
+ corosync_cfg_node_status_version_t version;
+ unsigned int nodeid;
+ uint8_t reachable;
+ uint8_t remote;
+ uint8_t external;
+ uint8_t onwire_min;
+ uint8_t onwire_max;
+ uint8_t onwire_ver;
+ struct corosync_knet_link_status_v1 link_status[CFG_MAX_LINKS];
+};
+
+/**
+ * @brief corosync_cfg_node_status_get
+ * @param cfg_handle
+ * @param nodeid
+ * @param node_status
+ * @return
+ */
+cs_error_t
+corosync_cfg_node_status_get (
+ corosync_cfg_handle_t cfg_handle,
+ unsigned int nodeid,
+ corosync_cfg_node_status_version_t version,
+ void *node_status);
+
+/**
+ * @brief corosync_cfg_kill_node
+ * @param cfg_handle
+ * @param nodeid
+ * @param reason
+ * @return
+ */
+cs_error_t
+corosync_cfg_kill_node (
+ corosync_cfg_handle_t cfg_handle,
+ unsigned int nodeid,
+ const char *reason);
+
+/**
+ * @brief corosync_cfg_trackstart
+ * Track CFG for shutdown requests
+ * @param cfg_handle
+ * @param track_flags (none currently supported)
+ * @param reason
+ * @return
+ */
+cs_error_t
+corosync_cfg_trackstart (
+ corosync_cfg_handle_t cfg_handle,
+ uint8_t track_flags);
+
+/**
+ * @brief corosync_cfg_trackstop
+ * Stop tracking CFG for shutdown requests
+ * @param cfg_handle
+ * @param reason
+ * @return
+ */
+cs_error_t
+corosync_cfg_trackstop (
+ corosync_cfg_handle_t cfg_handle);
+
+/**
+ * @brief corosync_cfg_try_shutdown
+ * @param cfg_handle
+ * @param flags
+ * @return
+ */
+cs_error_t
+corosync_cfg_try_shutdown (
+ corosync_cfg_handle_t cfg_handle,
+ corosync_cfg_shutdown_flags_t flags);
+
+/**
+ * @brief corosync_cfg_replyto_shutdown
+ * @param cfg_handle
+ * @param flags
+ * @return
+ */
+cs_error_t
+corosync_cfg_replyto_shutdown (
+ corosync_cfg_handle_t cfg_handle,
+ corosync_cfg_shutdown_reply_flags_t flags);
+
+/**
+ * @brief corosync_cfg_get_node_addrs
+ * @param cfg_handle
+ * @param nodeid
+ * @param max_addrs
+ * @param num_addrs
+ * @param addrs
+ * @return
+ */
+cs_error_t
+corosync_cfg_get_node_addrs (
+ corosync_cfg_handle_t cfg_handle,
+ unsigned int nodeid,
+ size_t max_addrs,
+ int *num_addrs,
+ corosync_cfg_node_address_t *addrs);
+
+/**
+ * @brief corosync_cfg_local_get
+ * @param handle
+ * @param local_nodeid
+ * @return
+ */
+cs_error_t
+corosync_cfg_local_get (
+ corosync_cfg_handle_t handle,
+ unsigned int *local_nodeid);
+
+/**
+ * @brief corosync_cfg_reload_config
+ * @param handle
+ * @return
+ */
+cs_error_t corosync_cfg_reload_config (
+ corosync_cfg_handle_t handle);
+
+/**
+ * @brief Reopen logging files
+ * @param handle CFG service handle
+ * @return CS_OK on success, CS_ERR_NOT_SUPPORTED if reopening of logging files is not available,
+ * otherwise one of common errors.
+ */
+cs_error_t corosync_cfg_reopen_log_files (
+ corosync_cfg_handle_t handle);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* COROSYNC_CFG_H_DEFINED */
diff --git a/include/corosync/cmap.h b/include/corosync/cmap.h
new file mode 100644
index 0000000..29b2e9e
--- /dev/null
+++ b/include/corosync/cmap.h
@@ -0,0 +1,378 @@
+/*
+ * Copyright (c) 2011-2017 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Author: Jan Friesse (jfriesse@redhat.com)
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of the Red Hat, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef COROSYNC_CMAP_H_DEFINED
+#define COROSYNC_CMAP_H_DEFINED
+
+#include <corosync/corotypes.h>
+#include <corosync/hdb.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup cmap_corosync
+ *
+ * @{
+ */
+
+/*
+ * Handle for cmap service connection
+ */
+typedef uint64_t cmap_handle_t;
+
+/*
+ * Handle for cmap iterator
+ */
+typedef uint64_t cmap_iter_handle_t;
+
+/*
+ * Handle for cmap tracking function
+ */
+typedef uint64_t cmap_track_handle_t;
+
+/*
+ * Maximum length of key in cmap
+ */
+#define CMAP_KEYNAME_MAXLEN 255
+/*
+ * Minumum length of key in cmap
+ */
+#define CMAP_KEYNAME_MINLEN 3
+
+/*
+ * Tracking values.
+ */
+#define CMAP_TRACK_ADD 4
+#define CMAP_TRACK_DELETE 1
+#define CMAP_TRACK_MODIFY 2
+
+/**
+ * Whole prefix is tracked, instead of key only (so "totem." tracking means that
+ * "totem.nodeid", "totem.version", ... applies). This value is also never returned
+ * inside of callback and is used only in adding track
+ */
+#define CMAP_TRACK_PREFIX 8
+
+/**
+ * Possible types of value. Binary is raw data without trailing zero with given length
+ */
+typedef enum {
+ CMAP_VALUETYPE_INT8 = 1,
+ CMAP_VALUETYPE_UINT8 = 2,
+ CMAP_VALUETYPE_INT16 = 3,
+ CMAP_VALUETYPE_UINT16 = 4,
+ CMAP_VALUETYPE_INT32 = 5,
+ CMAP_VALUETYPE_UINT32 = 6,
+ CMAP_VALUETYPE_INT64 = 7,
+ CMAP_VALUETYPE_UINT64 = 8,
+ CMAP_VALUETYPE_FLOAT = 9,
+ CMAP_VALUETYPE_DOUBLE = 10,
+ CMAP_VALUETYPE_STRING = 11,
+ CMAP_VALUETYPE_BINARY = 12,
+} cmap_value_types_t;
+
+typedef enum {
+ CMAP_MAP_DEFAULT = 0,
+ CMAP_MAP_ICMAP = 0,
+ CMAP_MAP_STATS = 1,
+} cmap_map_t;
+
+/**
+ * Structure passed as new_value and old_value in change callback. It contains type of
+ * key, length of key and pointer to value of key
+ */
+struct cmap_notify_value {
+ cmap_value_types_t type;
+ size_t len;
+ const void *data;
+};
+
+/**
+ * Prototype for notify callback function. Even is one of CMAP_TRACK_* event, key_name is
+ * changed key, new and old_value contains values or are zeroed (in other words, type is non
+ * existing 0 type) if there were no old (creating of key) or new (deleting of key) value.
+ * user_data are passed when adding tracking.
+ */
+typedef void (*cmap_notify_fn_t) (
+ cmap_handle_t cmap_handle,
+ cmap_track_handle_t cmap_track_handle,
+ int32_t event,
+ const char *key_name,
+ struct cmap_notify_value new_value,
+ struct cmap_notify_value old_value,
+ void *user_data);
+
+/**
+ * Create a new cmap connection
+ *
+ * @param handle will be filled with handle to be used for all following
+ * operations with cht.
+ */
+extern cs_error_t cmap_initialize (
+ cmap_handle_t *handle);
+
+/**
+ * Create a new cmap connection on a specified map
+ *
+ * @param handle will be filled with handle to be used for all following
+ * operations with cht.
+ * @param map is the 'map' to use for this connection
+ */
+extern cs_error_t cmap_initialize_map (
+ cmap_handle_t *handle,
+ cmap_map_t map);
+
+/**
+ * Close the cmap handle
+ * @param handle cmap handle
+ */
+extern cs_error_t cmap_finalize (
+ cmap_handle_t handle);
+
+/**
+ * Get a file descriptor on which to poll. cmap_handle_t is NOT a
+ * file descriptor and may not be used directly.
+ * @param handle cmap handle initialized by cmap_initialize
+ * @param fd file descriptor for poll
+ */
+extern cs_error_t cmap_fd_get (
+ cmap_handle_t handle,
+ int *fd);
+
+/**
+ * Dispatch data from service.
+ * @param handle cmap handle initialized by cmap_initialize
+ * @param dispatch_types one of standard corosync dispatch values
+ */
+extern cs_error_t cmap_dispatch (
+ cmap_handle_t handle,
+ cs_dispatch_flags_t dispatch_types);
+/**
+ * @brief cmap_context_get
+ * @param handle
+ * @param context
+ * @return
+ */
+extern cs_error_t cmap_context_get (
+ cmap_handle_t handle,
+ const void **context);
+
+/**
+ * @brief cmap_context_set
+ * @param handle
+ * @param context
+ * @return
+ */
+extern cs_error_t cmap_context_set (
+ cmap_handle_t handle,
+ const void *context);
+
+/**
+ * Store value in cmap
+ * @param handle cmap handle
+ * @param key_name name of key where to store value
+ * @param value value to store
+ * @param value_len length of value to store
+ * @param type type to store
+ */
+extern cs_error_t cmap_set(
+ cmap_handle_t handle,
+ const char *key_name,
+ const void *value,
+ size_t value_len,
+ cmap_value_types_t type);
+
+/*
+ * Shortcuts for cmap_set with given type
+ */
+extern cs_error_t cmap_set_int8(cmap_handle_t handle, const char *key_name, int8_t value);
+extern cs_error_t cmap_set_uint8(cmap_handle_t handle, const char *key_name, uint8_t value);
+extern cs_error_t cmap_set_int16(cmap_handle_t handle, const char *key_name, int16_t value);
+extern cs_error_t cmap_set_uint16(cmap_handle_t handle, const char *key_name, uint16_t value);
+extern cs_error_t cmap_set_int32(cmap_handle_t handle, const char *key_name, int32_t value);
+extern cs_error_t cmap_set_uint32(cmap_handle_t handle, const char *key_name, uint32_t value);
+extern cs_error_t cmap_set_int64(cmap_handle_t handle, const char *key_name, int64_t value);
+extern cs_error_t cmap_set_uint64(cmap_handle_t handle, const char *key_name, uint64_t value);
+extern cs_error_t cmap_set_float(cmap_handle_t handle, const char *key_name, float value);
+extern cs_error_t cmap_set_double(cmap_handle_t handle, const char *key_name, double value);
+extern cs_error_t cmap_set_string(cmap_handle_t handle, const char *key_name, const char *value);
+
+/**
+ * Deletes key from cmap database
+ * @param handle cmap handle
+ * @param key_name name of key to delete
+ */
+extern cs_error_t cmap_delete(cmap_handle_t handle, const char *key_name);
+
+/**
+ * @brief Retrieve value of key key_name and store it in user preallocated value pointer.
+ *
+ * value can be NULL, and then only value_len and/or type is returned (both of them
+ * can also be NULL). If value is not NULL, actual length of value in map is checked
+ * against value_len. If *value_len is shorter then length of value in map, error
+ * CS_ERR_INVALID_PARAM is returned. After successful copy of value, value_len is
+ * set to actual length of value in map.
+ *
+ * @param handle cmap handle
+ * @param key_name name of key where to get value
+ * @param value pointer to store data (or NULL)
+ * @param value_len pointer with length of value (value != NULL), or pointer where value length
+ * will be returned (value == NULL) or NULL.
+ * @param type type of value in cmap
+ */
+extern cs_error_t cmap_get(
+ cmap_handle_t handle,
+ const char *key_name,
+ void *value,
+ size_t *value_len,
+ cmap_value_types_t *type);
+
+/*
+ * Shortcuts for cmap_get.
+ */
+extern cs_error_t cmap_get_int8(cmap_handle_t handle, const char *key_name, int8_t *i8);
+extern cs_error_t cmap_get_uint8(cmap_handle_t handle, const char *key_name, uint8_t *u8);
+extern cs_error_t cmap_get_int16(cmap_handle_t handle, const char *key_name, int16_t *i16);
+extern cs_error_t cmap_get_uint16(cmap_handle_t handle, const char *key_name, uint16_t *u16);
+extern cs_error_t cmap_get_int32(cmap_handle_t handle, const char *key_name, int32_t *i32);
+extern cs_error_t cmap_get_uint32(cmap_handle_t handle, const char *key_name, uint32_t *u32);
+extern cs_error_t cmap_get_int64(cmap_handle_t handle, const char *key_name, int64_t *i64);
+extern cs_error_t cmap_get_uint64(cmap_handle_t handle, const char *key_name, uint64_t *u64);
+extern cs_error_t cmap_get_float(cmap_handle_t handle, const char *key_name, float *flt);
+extern cs_error_t cmap_get_double(cmap_handle_t handle, const char *key_name, double *dbl);
+
+/**
+ * @brief Shortcut for cmap_get for string type.
+ *
+ * Returned string is newly allocated and caller is responsible for freeing memory
+ *
+ * @param handle cmap handle
+ * @param key_name name of key to get value from
+ * @param str pointer where char pointer will be stored
+ */
+extern cs_error_t cmap_get_string(cmap_handle_t handle, const char *key_name, char **str);
+
+/**
+ * @brief Increment value of key_name if it is [u]int* type
+ *
+ * @param handle cmap handle
+ * @param key_name key name
+ */
+extern cs_error_t cmap_inc(cmap_handle_t handle, const char *key_name);
+
+/**
+ * @brief Decrement value of key_name if it is [u]int* type
+ *
+ * @param handle cmap handle
+ * @param key_name key name
+ */
+extern cs_error_t cmap_dec(cmap_handle_t handle, const char *key_name);
+
+/**
+ * @brief Initialize iterator with given prefix
+ *
+ * @param handle cmap handle
+ * @param prefix prefix to iterate on
+ * @param cmap_iter_handle value used for getting next value of iterator and/or deleting iteration
+ */
+extern cs_error_t cmap_iter_init(cmap_handle_t handle, const char *prefix, cmap_iter_handle_t *cmap_iter_handle);
+
+/**
+ * @brief Return next item in iterator iter.
+ *
+ * value_len and type are optional (= can be NULL), but if set,
+ * length of returned value and/or type is returned.
+ *
+ * @param handle cmap handle
+ * @param iter_handle handle of iteration returned by cmap_iter_init
+ * @param key_name place to store name of key. Maximum length is CMAP_KEYNAME_MAXLEN and
+ * trailing zero is always added so size of the buffer has to be at least
+ * CMAP_KEYNAME_MAXLEN + 1.
+ * @param value_len length of value
+ * @param type type of value
+ * @return CS_NO_SECTION if there are no more sections to iterate
+ */
+extern cs_error_t cmap_iter_next(
+ cmap_handle_t handle,
+ cmap_iter_handle_t iter_handle,
+ char key_name[],
+ size_t *value_len,
+ cmap_value_types_t *type);
+
+/**
+ * @brief Finalize iterator
+ * @param handle
+ * @param iter_handle
+ * @return
+ */
+extern cs_error_t cmap_iter_finalize(cmap_handle_t handle, cmap_iter_handle_t iter_handle);
+
+/**
+ * @brief Add tracking function for given key_name.
+ *
+ * Tracked changes (add|modify|delete) depend on track_type,
+ * which is bitwise or of CMAP_TRACK_* values. notify_fn is called on change, where user_data pointer
+ * is passed (unchanged). Value which can be used to delete tracking is passed as cmap_track.
+ *
+ * @param handle cmap handle
+ * @param key_name name of key to track changes on
+ * @param track_type bitwise-or of CMAP_TRACK_* values
+ * @param notify_fn function to be called on change of key
+ * @param user_data given pointer is unchanged passed to notify_fn
+ * @param cmap_track_handle handle used for removing of newly created track
+ */
+extern cs_error_t cmap_track_add(
+ cmap_handle_t handle,
+ const char *key_name,
+ int32_t track_type,
+ cmap_notify_fn_t notify_fn,
+ void *user_data,
+ cmap_track_handle_t *cmap_track_handle);
+
+/**
+ * Delete track created previously by cmap_track_add
+ * @param handle cmap handle
+ * @param track_handle Track handle
+ */
+extern cs_error_t cmap_track_delete(cmap_handle_t handle, cmap_track_handle_t track_handle);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* COROSYNC_CMAP_H_DEFINED */
diff --git a/include/corosync/config.h.in b/include/corosync/config.h.in
new file mode 100644
index 0000000..f827615
--- /dev/null
+++ b/include/corosync/config.h.in
@@ -0,0 +1,542 @@
+/* include/corosync/config.h.in. Generated from configure.ac by autoheader. */
+
+/* Define to 1 if the `closedir' function returns void instead of `int'. */
+#undef CLOSEDIR_VOID
+
+/* corosync config directory */
+#undef COROSYSCONFDIR
+
+/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP
+ systems. This function is required for `alloca.c' support on those systems.
+ */
+#undef CRAY_STACKSEG_END
+
+/* Define to 1 if using `alloca.c'. */
+#undef C_ALLOCA
+
+/* Compiling Debugging code */
+#undef DEBUG
+
+/* Build in support for sending SNMP traps */
+#undef ENABLE_SNMP
+
+/* Define to 1 if you have the `alarm' function. */
+#undef HAVE_ALARM
+
+/* Define to 1 if you have `alloca', as a function or macro. */
+#undef HAVE_ALLOCA
+
+/* Define to 1 if you have <alloca.h> and it should be used (not on Ultrix).
+ */
+#undef HAVE_ALLOCA_H
+
+/* Define to 1 if you have the `alphasort' function. */
+#undef HAVE_ALPHASORT
+
+/* Define to 1 if you have the <arpa/inet.h> header file. */
+#undef HAVE_ARPA_INET_H
+
+/* Define to 1 if you have the `atexit' function. */
+#undef HAVE_ATEXIT
+
+/* Define to 1 if you have the `bzero' function. */
+#undef HAVE_BZERO
+
+/* Define to 1 if you have the `clock_gettime' function. */
+#undef HAVE_CLOCK_GETTIME
+
+/* have dbus */
+#undef HAVE_DBUS
+
+/* Define to 1 if you have the <dirent.h> header file, and it defines `DIR'.
+ */
+#undef HAVE_DIRENT_H
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#undef HAVE_DLFCN_H
+
+/* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */
+#undef HAVE_DOPRNT
+
+/* Define to 1 if you have the `dup2' function. */
+#undef HAVE_DUP2
+
+/* Define to 1 if you have the `endgrent' function. */
+#undef HAVE_ENDGRENT
+
+/* Define to 1 if you have the `endpwent' function. */
+#undef HAVE_ENDPWENT
+
+/* Define to 1 if you have the `fcntl' function. */
+#undef HAVE_FCNTL
+
+/* Define to 1 if you have the <fcntl.h> header file. */
+#undef HAVE_FCNTL_H
+
+/* Define to 1 if you have the `fdatasync' function. */
+#undef HAVE_FDATASYNC
+
+/* Define to 1 if you have the `fork' function. */
+#undef HAVE_FORK
+
+/* Define to 1 if you have the `ftruncate' function. */
+#undef HAVE_FTRUNCATE
+
+/* Define to 1 if you have the `getcwd' function. */
+#undef HAVE_GETCWD
+
+/* Define to 1 if you have the `gethostname' function. */
+#undef HAVE_GETHOSTNAME
+
+/* Define to 1 if you have the `getifaddrs' function. */
+#undef HAVE_GETIFADDRS
+
+/* Define to 1 if you have the <getopt.h> header file. */
+#undef HAVE_GETOPT_H
+
+/* Define to 1 if you have the `getpagesize' function. */
+#undef HAVE_GETPAGESIZE
+
+/* Define to 1 if you have the `getpeereid' function. */
+#undef HAVE_GETPEEREID
+
+/* Define to 1 if you have the `getpeerucred' function. */
+#undef HAVE_GETPEERUCRED
+
+/* Define to 1 if you have the `gettimeofday' function. */
+#undef HAVE_GETTIMEOFDAY
+
+/* Define to 1 if you have the <ifaddrs.h> header file. */
+#undef HAVE_IFADDRS_H
+
+/* Define to 1 if you have the `inet_ntoa' function. */
+#undef HAVE_INET_NTOA
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* have knet access list */
+#undef HAVE_KNET_ACCESS_LIST
+
+/* have knet crypto reconfig support */
+#undef HAVE_KNET_CRYPTO_RECONF
+
+/* have knet onwire versioning */
+#undef HAVE_KNET_ONWIRE_VER
+
+/* Define to 1 if you have the `asan' library (-lasan). */
+#undef HAVE_LIBASAN
+
+/* have nozzle */
+#undef HAVE_LIBNOZZLE
+
+/* Define to 1 if you have the `nsl' library (-lnsl). */
+#undef HAVE_LIBNSL
+
+/* Define to 1 if you have the `pthread' library (-lpthread). */
+#undef HAVE_LIBPTHREAD
+
+/* Define to 1 if you have the `rt' library (-lrt). */
+#undef HAVE_LIBRT
+
+/* Define to 1 if you have the `socket' library (-lsocket). */
+#undef HAVE_LIBSOCKET
+
+/* have libstatgrab >= 0.90 */
+#undef HAVE_LIBSTATGRAB_GE_090
+
+/* have systemd interface library */
+#undef HAVE_LIBSYSTEMD
+
+/* Define to 1 if you have the `tsan' library (-ltsan). */
+#undef HAVE_LIBTSAN
+
+/* Define to 1 if you have the `ubsan' library (-lubsan). */
+#undef HAVE_LIBUBSAN
+
+/* Define to 1 if you have the <limits.h> header file. */
+#undef HAVE_LIMITS_H
+
+/* Define to 1 if you have the `localtime_r' function. */
+#undef HAVE_LOCALTIME_R
+
+/* Define to 1 if your system has a GNU libc compatible `malloc' function, and
+ to 0 otherwise. */
+#undef HAVE_MALLOC
+
+/* Define to 1 if you have the <malloc.h> header file. */
+#undef HAVE_MALLOC_H
+
+/* Define to 1 if you have the `memmove' function. */
+#undef HAVE_MEMMOVE
+
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define to 1 if you have the `memset' function. */
+#undef HAVE_MEMSET
+
+/* Define to 1 if you have the `mkdir' function. */
+#undef HAVE_MKDIR
+
+/* Define to 1 if you have a working `mmap' system call. */
+#undef HAVE_MMAP
+
+/* have resource monitoring */
+#undef HAVE_MONITORING
+
+/* msghdr has msg_accrights */
+#undef HAVE_MSGHDR_ACCRIGHTS
+
+/* msghdr has msg_accrightslen */
+#undef HAVE_MSGHDR_ACCRIGHTSLEN
+
+/* msghdr has msg_control */
+#undef HAVE_MSGHDR_CONTROL
+
+/* msghdr has msg_controllen */
+#undef HAVE_MSGHDR_CONTROLLEN
+
+/* msghdr has msg_flags */
+#undef HAVE_MSGHDR_FLAGS
+
+/* Define to 1 if you have the `munmap' function. */
+#undef HAVE_MUNMAP
+
+/* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */
+#undef HAVE_NDIR_H
+
+/* Define to 1 if you have the <netdb.h> header file. */
+#undef HAVE_NETDB_H
+
+/* Define to 1 if you have the <netinet/in.h> header file. */
+#undef HAVE_NETINET_IN_H
+
+/* Define to 1 if you have the `netsnmp_tdomain_transport' function. */
+#undef HAVE_NETSNMP_TDOMAIN_TRANSPORT
+
+/* Define to 1 if you have the `netsnmp_transport_open_client' function. */
+#undef HAVE_NETSNMP_TRANSPORT_OPEN_CLIENT
+
+/* Define to 1 if you have the <net-snmp/net-snmp-config.h> header file. */
+#undef HAVE_NET_SNMP_NET_SNMP_CONFIG_H
+
+/* Define to 1 if you have the `pthread_setschedparam' function. */
+#undef HAVE_PTHREAD_SETSCHEDPARAM
+
+/* have qb_log_file_reopen */
+#undef HAVE_QB_LOG_FILE_REOPEN
+
+/* have qb_log_thread_priority_set */
+#undef HAVE_QB_LOG_THREAD_PRIORITY_SET
+
+/* Define to 1 if you have the <readline/history.h> header file. */
+#undef HAVE_READLINE_HISTORY_H
+
+/* Define to 1 if you have the <readline/readline.h> header file. */
+#undef HAVE_READLINE_READLINE_H
+
+/* Define to 1 if your system has a GNU libc compatible `realloc' function,
+ and to 0 otherwise. */
+#undef HAVE_REALLOC
+
+/* Define to 1 if you have the `scandir' function. */
+#undef HAVE_SCANDIR
+
+/* Define to 1 if you have the `sched_get_priority_max' function. */
+#undef HAVE_SCHED_GET_PRIORITY_MAX
+
+/* Define to 1 if you have the `sched_setscheduler' function. */
+#undef HAVE_SCHED_SETSCHEDULER
+
+/* Define to 1 if you have the `select' function. */
+#undef HAVE_SELECT
+
+/* have small_memory_footprint */
+#undef HAVE_SMALL_MEMORY_FOOTPRINT
+
+/* Define to 1 if you have the `socket' function. */
+#undef HAVE_SOCKET
+
+/* sockaddr_in6 needs sin6_len */
+#undef HAVE_SOCK_SIN6_LEN
+
+/* sockaddr_in needs sin_len */
+#undef HAVE_SOCK_SIN_LEN
+
+/* Define to 1 if you have the <stddef.h> header file. */
+#undef HAVE_STDDEF_H
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Define to 1 if you have the `strcasecmp' function. */
+#undef HAVE_STRCASECMP
+
+/* Define to 1 if you have the `strchr' function. */
+#undef HAVE_STRCHR
+
+/* Define to 1 if you have the `strdup' function. */
+#undef HAVE_STRDUP
+
+/* Define to 1 if you have the `strerror' function. */
+#undef HAVE_STRERROR
+
+/* Define to 1 if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define to 1 if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define to 1 if you have the `strrchr' function. */
+#undef HAVE_STRRCHR
+
+/* Define to 1 if you have the `strspn' function. */
+#undef HAVE_STRSPN
+
+/* Define to 1 if you have the `strstr' function. */
+#undef HAVE_STRSTR
+
+/* Define to 1 if you have the `strtol' function. */
+#undef HAVE_STRTOL
+
+/* Define to 1 if you have the <syslog.h> header file. */
+#undef HAVE_SYSLOG_H
+
+/* Define to 1 if you have the <sys/dir.h> header file, and it defines `DIR'.
+ */
+#undef HAVE_SYS_DIR_H
+
+/* Define to 1 if you have the <sys/file.h> header file. */
+#undef HAVE_SYS_FILE_H
+
+/* Define to 1 if you have the <sys/ioctl.h> header file. */
+#undef HAVE_SYS_IOCTL_H
+
+/* Define to 1 if you have the <sys/ndir.h> header file, and it defines `DIR'.
+ */
+#undef HAVE_SYS_NDIR_H
+
+/* Define to 1 if you have the <sys/param.h> header file. */
+#undef HAVE_SYS_PARAM_H
+
+/* Define to 1 if you have the <sys/select.h> header file. */
+#undef HAVE_SYS_SELECT_H
+
+/* Define to 1 if you have the <sys/socket.h> header file. */
+#undef HAVE_SYS_SOCKET_H
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define to 1 if you have the <sys/time.h> header file. */
+#undef HAVE_SYS_TIME_H
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* Define to 1 if you have the <sys/uio.h> header file. */
+#undef HAVE_SYS_UIO_H
+
+/* Define to 1 if you have <sys/wait.h> that is POSIX.1 compatible. */
+#undef HAVE_SYS_WAIT_H
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* Define to 1 if you have the <utmpx.h> header file. */
+#undef HAVE_UTMPX_H
+
+/* Define to 1 if you have the `vfork' function. */
+#undef HAVE_VFORK
+
+/* Define to 1 if you have the <vfork.h> header file. */
+#undef HAVE_VFORK_H
+
+/* Define to 1 if you have the `vprintf' function. */
+#undef HAVE_VPRINTF
+
+/* have watchdog */
+#undef HAVE_WATCHDOG
+
+/* Define to 1 if `fork' works. */
+#undef HAVE_WORKING_FORK
+
+/* Define to 1 if `vfork' works. */
+#undef HAVE_WORKING_VFORK
+
+/* localstate directory */
+#undef LOCALSTATEDIR
+
+/* Define to the sub-directory in which libtool stores uninstalled libraries.
+ */
+#undef LT_OBJDIR
+
+/* have net-snmp5.4 over */
+#undef NETSNMPV54
+
+/* Name of package */
+#undef PACKAGE
+
+/* Define to the address where bug reports for this package should be sent. */
+#undef PACKAGE_BUGREPORT
+
+/* corosync built-in features */
+#undef PACKAGE_FEATURES
+
+/* Define to the full name of this package. */
+#undef PACKAGE_NAME
+
+/* Define to the full name and version of this package. */
+#undef PACKAGE_STRING
+
+/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME
+
+/* Define to the home page for this package. */
+#undef PACKAGE_URL
+
+/* Define to the version of this package. */
+#undef PACKAGE_VERSION
+
+/* Define to the type of arg 1 for `select'. */
+#undef SELECT_TYPE_ARG1
+
+/* Define to the type of args 2, 3 and 4 for `select'. */
+#undef SELECT_TYPE_ARG234
+
+/* Define to the type of arg 5 for `select'. */
+#undef SELECT_TYPE_ARG5
+
+/* If using the C implementation of alloca, define if you know the
+ direction of stack growth for your system; otherwise it will be
+ automatically deduced at runtime.
+ STACK_DIRECTION > 0 => grows toward higher addresses
+ STACK_DIRECTION < 0 => grows toward lower addresses
+ STACK_DIRECTION = 0 => direction of growth unknown */
+#undef STACK_DIRECTION
+
+/* Define to 1 if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Enable extensions on AIX 3, Interix. */
+#ifndef _ALL_SOURCE
+# undef _ALL_SOURCE
+#endif
+/* Enable GNU extensions on systems that have them. */
+#ifndef _GNU_SOURCE
+# undef _GNU_SOURCE
+#endif
+/* Enable threading extensions on Solaris. */
+#ifndef _POSIX_PTHREAD_SEMANTICS
+# undef _POSIX_PTHREAD_SEMANTICS
+#endif
+/* Enable extensions on HP NonStop. */
+#ifndef _TANDEM_SOURCE
+# undef _TANDEM_SOURCE
+#endif
+/* Enable general extensions on Solaris. */
+#ifndef __EXTENSIONS__
+# undef __EXTENSIONS__
+#endif
+
+
+/* Version number of package */
+#undef VERSION
+
+/* Define to 1 if on MINIX. */
+#undef _MINIX
+
+/* Define to 2 if the system does not provide POSIX.1 features except with
+ this defined. */
+#undef _POSIX_1_SOURCE
+
+/* Define to 1 if you need to in order for `stat' and other things to work. */
+#undef _POSIX_SOURCE
+
+/* Define for Solaris 2.5.1 so the uint32_t typedef from <sys/synch.h>,
+ <pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the
+ #define below would cause a syntax error. */
+#undef _UINT32_T
+
+/* Define for Solaris 2.5.1 so the uint64_t typedef from <sys/synch.h>,
+ <pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the
+ #define below would cause a syntax error. */
+#undef _UINT64_T
+
+/* Define for Solaris 2.5.1 so the uint8_t typedef from <sys/synch.h>,
+ <pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the
+ #define below would cause a syntax error. */
+#undef _UINT8_T
+
+/* Define to empty if `const' does not conform to ANSI C. */
+#undef const
+
+/* Define to `int' if <sys/types.h> doesn't define. */
+#undef gid_t
+
+/* Define to `__inline__' or `__inline' if that's what the C compiler
+ calls it, or to nothing if 'inline' is not supported under any name. */
+#ifndef __cplusplus
+#undef inline
+#endif
+
+/* Define to the type of a signed integer type of width exactly 16 bits if
+ such a type exists and the standard includes do not define it. */
+#undef int16_t
+
+/* Define to the type of a signed integer type of width exactly 32 bits if
+ such a type exists and the standard includes do not define it. */
+#undef int32_t
+
+/* Define to the type of a signed integer type of width exactly 64 bits if
+ such a type exists and the standard includes do not define it. */
+#undef int64_t
+
+/* Define to the type of a signed integer type of width exactly 8 bits if such
+ a type exists and the standard includes do not define it. */
+#undef int8_t
+
+/* Define to rpl_malloc if the replacement function should be used. */
+#undef malloc
+
+/* Define to `int' if <sys/types.h> does not define. */
+#undef pid_t
+
+/* Define to rpl_realloc if the replacement function should be used. */
+#undef realloc
+
+/* Define to `unsigned int' if <sys/types.h> does not define. */
+#undef size_t
+
+/* Define to `int' if <sys/types.h> does not define. */
+#undef ssize_t
+
+/* Define to `int' if <sys/types.h> doesn't define. */
+#undef uid_t
+
+/* Define to the type of an unsigned integer type of width exactly 16 bits if
+ such a type exists and the standard includes do not define it. */
+#undef uint16_t
+
+/* Define to the type of an unsigned integer type of width exactly 32 bits if
+ such a type exists and the standard includes do not define it. */
+#undef uint32_t
+
+/* Define to the type of an unsigned integer type of width exactly 64 bits if
+ such a type exists and the standard includes do not define it. */
+#undef uint64_t
+
+/* Define to the type of an unsigned integer type of width exactly 8 bits if
+ such a type exists and the standard includes do not define it. */
+#undef uint8_t
+
+/* Define as `fork' if `vfork' does not work. */
+#undef vfork
+
+/* Define to empty if the keyword `volatile' does not work. Warning: valid
+ code using `volatile' can become incorrect without. Disable with care. */
+#undef volatile
diff --git a/include/corosync/coroapi.h b/include/corosync/coroapi.h
new file mode 100644
index 0000000..9d14b7b
--- /dev/null
+++ b/include/corosync/coroapi.h
@@ -0,0 +1,526 @@
+/*
+ * Copyright (c) 2008-2012 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Author: Steven Dake (sdake@redhat.com)
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of the MontaVista Software, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef COROAPI_H_DEFINED
+#define COROAPI_H_DEFINED
+
+#include <config.h>
+
+#include <stdio.h>
+#ifdef HAVE_SYS_UIO_H
+#include <sys/uio.h>
+#endif
+#include <corosync/hdb.h>
+#include <qb/qbloop.h>
+#include <corosync/swab.h>
+
+/**
+ * @brief The mar_message_source_t struct
+ */
+typedef struct {
+ uint32_t nodeid __attribute__((aligned(8)));
+ void *conn __attribute__((aligned(8)));
+} mar_message_source_t __attribute__((aligned(8)));
+
+/**
+ * @brief swab_mar_message_source_t
+ * @param to_swab
+ */
+static inline void swab_mar_message_source_t (mar_message_source_t *to_swab)
+{
+ swab32 (to_swab->nodeid);
+ /*
+ * if it is from a byteswapped machine, then we can safely
+ * ignore its conn info data structure since this is only
+ * local to the machine
+ */
+ to_swab->conn = NULL;
+}
+
+#ifndef TIMER_HANDLE_T
+/**
+ * @brief corosync_timer_handle_t
+ */
+typedef qb_loop_timer_handle corosync_timer_handle_t;
+#define TIMER_HANDLE_T 1
+#endif
+
+/**
+ * @brief The corosync_tpg_group struct
+ */
+struct corosync_tpg_group {
+ const void *group;
+ size_t group_len;
+};
+
+#define TOTEMIP_ADDRLEN (sizeof(struct in6_addr))
+
+#define INTERFACE_MAX 8
+
+#ifndef MESSAGE_QUEUE_MAX
+#ifdef HAVE_SMALL_MEMORY_FOOTPRINT
+#define PROCESSOR_COUNT_MAX 16
+#define MESSAGE_SIZE_MAX 1024*64
+#define MESSAGE_QUEUE_MAX 512
+#else
+#define PROCESSOR_COUNT_MAX 384
+#define MESSAGE_SIZE_MAX 1024*1024
+#define MESSAGE_QUEUE_MAX ((4 * MESSAGE_SIZE_MAX) / totem_config->net_mtu)
+#endif /* HAVE_SMALL_MEMORY_FOOTPRINT */
+#endif /* MESSAGE_QUEUE_MAX */
+
+#define TOTEM_AGREED 0
+#define TOTEM_SAFE 1
+
+#define MILLI_2_NANO_SECONDS 1000000ULL
+
+#if !defined(TOTEM_IP_ADDRESS)
+/**
+ * @brief The totem_ip_address struct
+ */
+struct totem_ip_address {
+ unsigned int nodeid;
+ unsigned short family;
+ unsigned char addr[TOTEMIP_ADDRLEN];
+} __attribute__((packed));
+#endif
+
+#if !defined(MEMB_RING_ID)
+/**
+ * @brief The memb_ring_id struct
+ */
+struct memb_ring_id {
+ unsigned int nodeid;
+ unsigned long long seq;
+} __attribute__((packed));
+#endif
+
+#if !defined(TOTEM_CONFIGURATION_TYPE)
+/**
+ * @brief The totem_configuration_type enum
+ */
+enum totem_configuration_type {
+ TOTEM_CONFIGURATION_REGULAR,
+ TOTEM_CONFIGURATION_TRANSITIONAL
+};
+#endif
+
+#if !defined(TOTEM_CALLBACK_TOKEN_TYPE)
+/**
+ * @brief The totem_callback_token_type enum
+ */
+enum totem_callback_token_type {
+ TOTEM_CALLBACK_TOKEN_RECEIVED = 1,
+ TOTEM_CALLBACK_TOKEN_SENT = 2
+};
+#endif
+
+/**
+ * @brief The cs_lib_flow_control enum
+ */
+enum cs_lib_flow_control {
+ CS_LIB_FLOW_CONTROL_REQUIRED = 1,
+ CS_LIB_FLOW_CONTROL_NOT_REQUIRED = 2
+};
+#define corosync_lib_flow_control cs_lib_flow_control
+#define COROSYNC_LIB_FLOW_CONTROL_REQUIRED CS_LIB_FLOW_CONTROL_REQUIRED
+#define COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED CS_LIB_FLOW_CONTROL_NOT_REQUIRED
+
+/**
+ * @brief The cs_lib_allow_inquorate enum
+ */
+enum cs_lib_allow_inquorate {
+ CS_LIB_DISALLOW_INQUORATE = 0, /* default */
+ CS_LIB_ALLOW_INQUORATE = 1
+};
+
+#if !defined (COROSYNC_FLOW_CONTROL_STATE)
+/**
+ * @brief The cs_flow_control_state enum
+ */
+enum cs_flow_control_state {
+ CS_FLOW_CONTROL_STATE_DISABLED,
+ CS_FLOW_CONTROL_STATE_ENABLED
+};
+#define corosync_flow_control_state cs_flow_control_state
+#define CS_FLOW_CONTROL_STATE_DISABLED CS_FLOW_CONTROL_STATE_DISABLED
+#define CS_FLOW_CONTROL_STATE_ENABLED CS_FLOW_CONTROL_STATE_ENABLED
+
+#endif /* COROSYNC_FLOW_CONTROL_STATE */
+/**
+ * @brief The cs_fatal_error_t enum.
+ */
+typedef enum {
+ COROSYNC_FATAL_ERROR_EXIT = -1,
+ COROSYNC_LIBAIS_SOCKET = -6,
+ COROSYNC_LIBAIS_BIND = -7,
+ COROSYNC_READKEY = -8,
+ COROSYNC_INVALID_CONFIG = -9,
+ COROSYNC_DYNAMICLOAD = -12,
+ COROSYNC_OUT_OF_MEMORY = -15,
+ COROSYNC_FATAL_ERR = -16
+} cs_fatal_error_t;
+#define corosync_fatal_error_t cs_fatal_error_t;
+
+#ifndef QUORUM_H_DEFINED
+/**
+ *@brief The quorum_callback_fn_t callback
+ */
+typedef void (*quorum_callback_fn_t) (int quorate, void *context);
+
+/**
+ * @brief The quorum_callin_functions struct
+ */
+struct quorum_callin_functions {
+ int (*quorate) (void);
+ int (*register_callback) (quorum_callback_fn_t callback_fn, void *contexxt);
+ int (*unregister_callback) (quorum_callback_fn_t callback_fn, void *context);
+};
+
+/**
+ * @brief The sync_callback_fn_t callback
+ */
+typedef void (*sync_callback_fn_t) (
+ const unsigned int *view_list,
+ size_t view_list_entries,
+ int primary_designated,
+ struct memb_ring_id *ring_id);
+
+#endif /* QUORUM_H_DEFINED */
+
+
+/**
+ * @brief The corosync_api_v1 struct
+ */
+struct corosync_api_v1 {
+ /*
+ * Time and timer APIs
+ */
+ int (*timer_add_duration) (
+ unsigned long long nanoseconds_in_future,
+ void *data,
+ void (*timer_nf) (void *data),
+ corosync_timer_handle_t *handle);
+
+ int (*timer_add_absolute) (
+ unsigned long long nanoseconds_from_epoch,
+ void *data,
+ void (*timer_fn) (void *data),
+ corosync_timer_handle_t *handle);
+
+ void (*timer_delete) (
+ corosync_timer_handle_t timer_handle);
+
+ unsigned long long (*timer_time_get) (void);
+
+ unsigned long long (*timer_expire_time_get) (
+ corosync_timer_handle_t timer_handle);
+
+ /*
+ * IPC APIs
+ */
+ void (*ipc_source_set) (mar_message_source_t *source, void *conn);
+
+ int (*ipc_source_is_local) (const mar_message_source_t *source);
+
+ void *(*ipc_private_data_get) (void *conn);
+
+ int (*ipc_response_send) (void *conn, const void *msg, size_t mlen);
+
+ int (*ipc_response_iov_send) (void *conn,
+ const struct iovec *iov, unsigned int iov_len);
+
+ int (*ipc_dispatch_send) (void *conn, const void *msg, size_t mlen);
+
+ int (*ipc_dispatch_iov_send) (void *conn,
+ const struct iovec *iov, unsigned int iov_len);
+
+ void (*ipc_refcnt_inc) (void *conn);
+
+ void (*ipc_refcnt_dec) (void *conn);
+
+ /*
+ * Totem APIs
+ */
+ unsigned int (*totem_nodeid_get) (void);
+
+ int (*totem_family_get) (void);
+
+ int (*totem_mcast) (const struct iovec *iovec,
+ unsigned int iov_len, unsigned int guarantee);
+
+ int (*totem_ifaces_get) (
+ unsigned int nodeid,
+ unsigned int *interface_ids,
+ struct totem_ip_address *interfaces,
+ unsigned int interfaces_size,
+ char ***status,
+ unsigned int *iface_count);
+
+ const char *(*totem_ifaces_print) (unsigned int nodeid);
+
+ const char *(*totem_ip_print) (const struct totem_ip_address *addr);
+
+ int (*totem_crypto_set) (const char *cipher_type, const char *hash_type);
+
+ int (*totem_callback_token_create) (
+ void **handle_out,
+ enum totem_callback_token_type type,
+ int delete,
+ int (*callback_fn) (enum totem_callback_token_type type,
+ const void *),
+ const void *data);
+
+ /*
+ * Totem open process groups API for those service engines
+ * wanting their own groups
+ */
+ int (*tpg_init) (
+ void **instance,
+
+ void (*deliver_fn) (
+ unsigned int nodeid,
+ const void *msg,
+ unsigned int msg_len,
+ int endian_conversion_required),
+
+ void (*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 (*tpg_exit) (
+ void *instance);
+
+ int (*tpg_join) (
+ void *instance,
+ const struct corosync_tpg_group *groups,
+ size_t group_cnt);
+
+ int (*tpg_leave) (
+ void *instance,
+ const struct corosync_tpg_group *groups,
+ size_t group_cnt);
+
+ int (*tpg_joined_mcast) (
+ void *totempg_groups_instance,
+ const struct iovec *iovec,
+ unsigned int iov_len,
+ int guarantee);
+
+ int (*tpg_joined_reserve) (
+ void *totempg_groups_instance,
+ const struct iovec *iovec,
+ unsigned int iov_len);
+
+ int (*tpg_joined_release) (
+ int reserved_msgs);
+
+ int (*tpg_groups_mcast) (
+ void *instance,
+ int guarantee,
+ const struct corosync_tpg_group *groups,
+ size_t groups_cnt,
+ const struct iovec *iovec,
+ unsigned int iov_len);
+
+ int (*tpg_groups_reserve) (
+ void *instance,
+ const struct corosync_tpg_group *groups,
+ size_t groups_cnt,
+ const struct iovec *iovec,
+ unsigned int iov_len);
+
+ int (*tpg_groups_release) (
+ int reserved_msgs);
+
+ int (*schedwrk_create) (
+ hdb_handle_t *handle,
+ int (schedwrk_fn) (const void *),
+ const void *context);
+
+ void (*schedwrk_destroy) (hdb_handle_t handle);
+
+ int (*sync_request) (
+ const char *service_name);
+
+ /*
+ * User plugin-callable functions for quorum
+ */
+ int (*quorum_is_quorate) (void);
+ int (*quorum_register_callback) (quorum_callback_fn_t callback_fn, void *context);
+ int (*quorum_unregister_callback) (quorum_callback_fn_t callback_fn, void *context);
+
+ /*
+ * This one is for the quorum management plugin's use
+ */
+ int (*quorum_initialize)(struct quorum_callin_functions *fns);
+
+ /*
+ * Plugin loading and unloading
+ */
+ int (*plugin_interface_reference) (
+ hdb_handle_t *handle,
+ const char *iface_name,
+ int version,
+ void **interface,
+ void *context);
+
+ int (*plugin_interface_release) (hdb_handle_t handle);
+
+ /*
+ * Service loading and unloading APIs
+ */
+ unsigned int (*service_link_and_init) (
+ struct corosync_api_v1 *corosync_api_v1,
+ const char *service_name,
+ unsigned int service_ver);
+
+ unsigned int (*service_unlink_and_exit) (
+ struct corosync_api_v1 *corosync_api_v1,
+ const char *service_name,
+ unsigned int service_ver);
+
+ /*
+ * Error handling APIs
+ */
+ void (*error_memory_failure) (void) __attribute__ ((noreturn));
+
+#define corosync_fatal_error(err) api->fatal_error ((err), __FILE__, __LINE__)
+ void (*fatal_error) (cs_fatal_error_t err,
+ const char *file,
+ unsigned int line) __attribute__ ((noreturn));
+
+ void (*shutdown_request) (void);
+
+ void (*state_dump) (void);
+
+ qb_loop_t *(*poll_handle_get) (void);
+
+ void *(*totem_get_stats)(void);
+
+ int (*schedwrk_create_nolock) (
+ hdb_handle_t *handle,
+ int (schedwrk_fn) (const void *),
+ const void *context);
+
+ int (*poll_dispatch_add) (qb_loop_t * handle,
+ int fd,
+ int events,
+ void *data,
+
+ int (*dispatch_fn) (int fd,
+ int revents,
+ void *data));
+
+
+ int (*poll_dispatch_delete) (
+ qb_loop_t * handle,
+ int fd);
+
+};
+
+#define SERVICE_ID_MAKE(a,b) ( ((a)<<16) | (b) )
+
+#define SERVICE_HANDLER_MAXIMUM_COUNT 64
+
+#define SERVICES_COUNT_MAX 64
+
+/**
+ * @brief The corosync_lib_handler struct
+ */
+struct corosync_lib_handler {
+ void (*lib_handler_fn) (void *conn, const void *msg);
+ enum cs_lib_flow_control flow_control;
+};
+
+/**
+ * @brief The corosync_exec_handler struct
+ */
+struct corosync_exec_handler {
+ void (*exec_handler_fn) (const void *msg, unsigned int nodeid);
+ void (*exec_endian_convert_fn) (void *msg);
+};
+
+/**
+ * @brief The corosync_service_engine_iface_ver0 struct
+ */
+struct corosync_service_engine_iface_ver0 {
+ struct corosync_service_engine *(*corosync_get_service_engine_ver0) (void);
+};
+
+/**
+ * @brief The corosync_service_engine struct
+ */
+struct corosync_service_engine {
+ const char *name;
+ unsigned short id;
+ unsigned short priority; /* Lower priority are loaded first, unloaded last.
+ * 0 is a special case which always loaded _and_ unloaded last
+ */
+ size_t private_data_size;
+ enum cs_lib_flow_control flow_control;
+ enum cs_lib_allow_inquorate allow_inquorate;
+ char *(*exec_init_fn) (struct corosync_api_v1 *);
+ int (*exec_exit_fn) (void);
+ void (*exec_dump_fn) (void);
+ int (*lib_init_fn) (void *conn);
+ int (*lib_exit_fn) (void *conn);
+ struct corosync_lib_handler *lib_engine;
+ int lib_engine_count;
+ struct corosync_exec_handler *exec_engine;
+ int exec_engine_count;
+ int (*config_init_fn) (struct corosync_api_v1 *);
+ void (*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);
+ void (*sync_init) (
+ const unsigned int *trans_list,
+ size_t trans_list_entries,
+ const unsigned int *member_list,
+ size_t member_list_entries,
+ const struct memb_ring_id *ring_id);
+ int (*sync_process) (void);
+ void (*sync_activate) (void);
+ void (*sync_abort) (void);
+};
+
+#endif /* COROAPI_H_DEFINED */
diff --git a/include/corosync/corodefs.h b/include/corosync/corodefs.h
new file mode 100644
index 0000000..17d59d6
--- /dev/null
+++ b/include/corosync/corodefs.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2009-2011 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Author: Steven Dake (sdake@redhat.com)
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of the MontaVista Software, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef CORODEFS_H_DEFINED
+#define CORODEFS_H_DEFINED
+
+#include <netinet/in.h>
+
+/**
+ * @brief The corosync_service_types enum
+ */
+enum corosync_service_types {
+ CMAP_SERVICE = 0,
+ CFG_SERVICE = 1,
+ CPG_SERVICE = 2,
+ QUORUM_SERVICE = 3,
+ PLOAD_SERVICE = 4,
+ VOTEQUORUM_SERVICE = 5,
+ MON_SERVICE = 6,
+ WD_SERVICE = 7,
+};
+
+#ifdef HAVE_SMALL_MEMORY_FOOTPRINT
+#define PROCESSOR_COUNT_MAX 16
+#else
+#define PROCESSOR_COUNT_MAX 384
+#endif /* HAVE_SMALL_MEMORY_FOOTPRINT */
+
+#define TOTEMIP_ADDRLEN (sizeof(struct in6_addr))
+
+#endif /* CORODEFS_H_DEFINED */
diff --git a/include/corosync/corotypes.h b/include/corosync/corotypes.h
new file mode 100644
index 0000000..a661cb6
--- /dev/null
+++ b/include/corosync/corotypes.h
@@ -0,0 +1,189 @@
+/*
+ * Copyright (c) 2008 Allied Telesis Labs.
+ * Copyright (c) 2012 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Author: Angus Salkeld (ahsalkeld@gmail.com)
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of the MontaVista Software, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef COROTYPES_H_DEFINED
+#define COROTYPES_H_DEFINED
+
+#include <stdint.h>
+#include <errno.h>
+#include <time.h>
+#include <sys/time.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief cs_time_t
+ */
+typedef int64_t cs_time_t;
+
+#define CS_FALSE 0
+#define CS_TRUE !CS_FALSE
+#define CS_MAX_NAME_LENGTH 256
+#define CS_TIME_END ((cs_time_t)0x7FFFFFFFFFFFFFFFULL)
+#define CS_MAX(x, y) (((x) > (y)) ? (x) : (y))
+
+#define CS_PRI_NODE_ID "%" PRIu32
+#define CS_PRI_NODE_ID_PADDED "%10" PRIu32
+#define CS_PRI_RING_ID_SEQ "%" PRIx64
+#define CS_PRI_RING_ID "%" PRIx32 ".%" PRIx64
+/**
+ * @brief The cs_name_t struct
+ */
+typedef struct {
+ uint16_t length;
+ uint8_t value[CS_MAX_NAME_LENGTH];
+} cs_name_t;
+
+
+/**
+ * @brief The cs_version_t struct
+ */
+typedef struct {
+ char releaseCode;
+ unsigned char majorVersion;
+ unsigned char minorVersion;
+} cs_version_t;
+
+/**
+ * @brief The cs_dispatch_flags_t enum
+ */
+typedef enum {
+ CS_DISPATCH_ONE = 1,
+ CS_DISPATCH_ALL = 2,
+ CS_DISPATCH_BLOCKING = 3,
+ CS_DISPATCH_ONE_NONBLOCKING = 4
+} cs_dispatch_flags_t;
+
+#define CS_TRACK_CURRENT 0x01
+#define CS_TRACK_CHANGES 0x02
+#define CS_TRACK_CHANGES_ONLY 0x04
+
+/**
+ * @brief The cs_error_t enum
+ */
+typedef enum {
+ CS_OK = 1,
+ CS_ERR_LIBRARY = 2,
+ CS_ERR_VERSION = 3,
+ CS_ERR_INIT = 4,
+ CS_ERR_TIMEOUT = 5,
+ CS_ERR_TRY_AGAIN = 6,
+ CS_ERR_INVALID_PARAM = 7,
+ CS_ERR_NO_MEMORY = 8,
+ CS_ERR_BAD_HANDLE = 9,
+ CS_ERR_BUSY = 10,
+ CS_ERR_ACCESS = 11,
+ CS_ERR_NOT_EXIST = 12,
+ CS_ERR_NAME_TOO_LONG = 13,
+ CS_ERR_EXIST = 14,
+ CS_ERR_NO_SPACE = 15,
+ CS_ERR_INTERRUPT = 16,
+ CS_ERR_NAME_NOT_FOUND = 17,
+ CS_ERR_NO_RESOURCES = 18,
+ CS_ERR_NOT_SUPPORTED = 19,
+ CS_ERR_BAD_OPERATION = 20,
+ CS_ERR_FAILED_OPERATION = 21,
+ CS_ERR_MESSAGE_ERROR = 22,
+ CS_ERR_QUEUE_FULL = 23,
+ CS_ERR_QUEUE_NOT_AVAILABLE = 24,
+ CS_ERR_BAD_FLAGS = 25,
+ CS_ERR_TOO_BIG = 26,
+ CS_ERR_NO_SECTIONS = 27,
+ CS_ERR_CONTEXT_NOT_FOUND = 28,
+ CS_ERR_TOO_MANY_GROUPS = 30,
+ CS_ERR_SECURITY = 100
+} cs_error_t;
+
+#define CS_IPC_TIMEOUT_MS -1
+
+#define CS_TIME_MS_IN_SEC 1000ULL
+#define CS_TIME_US_IN_SEC 1000000ULL
+#define CS_TIME_NS_IN_SEC 1000000000ULL
+#define CS_TIME_US_IN_MSEC 1000ULL
+#define CS_TIME_NS_IN_MSEC 1000000ULL
+#define CS_TIME_NS_IN_USEC 1000ULL
+
+/**
+ * @brief cs_timestamp_get
+ * @return
+ */
+static inline uint64_t cs_timestamp_get(void)
+{
+ uint64_t result;
+
+#if defined _POSIX_MONOTONIC_CLOCK && _POSIX_MONOTONIC_CLOCK >= 0
+ struct timespec ts;
+
+ clock_gettime (CLOCK_MONOTONIC, &ts);
+ result = (ts.tv_sec * CS_TIME_NS_IN_SEC) + (uint64_t)ts.tv_nsec;
+#else
+ struct timeval time_from_epoch;
+
+ gettimeofday (&time_from_epoch, 0);
+ result = ((time_from_epoch.tv_sec * CS_TIME_NS_IN_SEC) +
+ (time_from_epoch.tv_usec * CS_TIME_NS_IN_USEC));
+#endif
+
+ return result;
+}
+/**
+ * @brief qb_to_cs_error
+ * @param result
+ * @return
+ */
+cs_error_t qb_to_cs_error (int result);
+
+/**
+ * @brief cs_strerror
+ * @param err
+ * @return
+ */
+const char * cs_strerror(cs_error_t err);
+
+/**
+ * @brief hdb_error_to_cs
+ * @param res
+ * @return
+ */
+cs_error_t hdb_error_to_cs (int res);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* COROTYPES_H_DEFINED */
+
diff --git a/include/corosync/cpg.h b/include/corosync/cpg.h
new file mode 100644
index 0000000..39200fd
--- /dev/null
+++ b/include/corosync/cpg.h
@@ -0,0 +1,440 @@
+/*
+ * Copyright (c) 2006-2019 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Author: Christine Caulfield (ccaulfi@redhat.com)
+ * Author: Jan Friesse (jfriesse@redhat.com)
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of the MontaVista Software, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef COROSYNC_CPG_H_DEFINED
+#define COROSYNC_CPG_H_DEFINED
+
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <corosync/corotypes.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup cpg_corosync
+ *
+ * @{
+ */
+/**
+ * @brief cpg_handle_t
+ */
+typedef uint64_t cpg_handle_t;
+
+/**
+ * @brief cpg_iteration_handle_t
+ */
+typedef uint64_t cpg_iteration_handle_t;
+
+/**
+ * @brief The cpg_guarantee_t enum
+ */
+typedef enum {
+ CPG_TYPE_UNORDERED, /**< not implemented */
+ CPG_TYPE_FIFO, /**< same as agreed */
+ CPG_TYPE_AGREED,
+ CPG_TYPE_SAFE /**< not implemented */
+} cpg_guarantee_t;
+
+/**
+ * @brief The cpg_flow_control_state_t enum
+ */
+typedef enum {
+ CPG_FLOW_CONTROL_DISABLED, /**< flow control is disabled - new messages may be sent */
+ CPG_FLOW_CONTROL_ENABLED /**< flow control is enabled - new messages should not be sent */
+} cpg_flow_control_state_t;
+
+
+/**
+ * @brief The cpg_reason_t enum
+ */
+typedef enum {
+ CPG_REASON_UNDEFINED = 0,
+ CPG_REASON_JOIN = 1,
+ CPG_REASON_LEAVE = 2,
+ CPG_REASON_NODEDOWN = 3,
+ CPG_REASON_NODEUP = 4,
+ CPG_REASON_PROCDOWN = 5
+} cpg_reason_t;
+
+/**
+ * @brief The cpg_iteration_type_t enum
+ */
+typedef enum {
+ CPG_ITERATION_NAME_ONLY = 1,
+ CPG_ITERATION_ONE_GROUP = 2,
+ CPG_ITERATION_ALL = 3,
+} cpg_iteration_type_t;
+
+/**
+ * @brief The cpg_model_t enum
+ */
+typedef enum {
+ CPG_MODEL_V1 = 1,
+} cpg_model_t;
+
+/**
+ * @brief The cpg_address struct
+ */
+struct cpg_address {
+ uint32_t nodeid;
+ uint32_t pid;
+ uint32_t reason;
+};
+
+#define CPG_MAX_NAME_LENGTH 128
+/**
+ * @brief The cpg_name struct
+ */
+struct cpg_name {
+ uint32_t length;
+ char value[CPG_MAX_NAME_LENGTH];
+};
+
+#define CPG_MEMBERS_MAX 128
+
+/**
+ * @brief The cpg_iteration_description_t struct
+ */
+struct cpg_iteration_description_t {
+ struct cpg_name group;
+ uint32_t nodeid;
+ uint32_t pid;
+};
+
+/**
+ * @brief The cpg_ring_id struct
+ */
+struct cpg_ring_id {
+ uint32_t nodeid;
+ uint64_t seq;
+};
+
+/**
+ * @brief The cpg_deliver_fn_t callback
+ */
+typedef void (*cpg_deliver_fn_t) (
+ cpg_handle_t handle,
+ const struct cpg_name *group_name,
+ uint32_t nodeid,
+ uint32_t pid,
+ /**
+ * Unlike many "msg" pointers, this one is deliberately *not*
+ * declared const in order to permit in-place endian conversion.
+ */
+ void *msg,
+ size_t msg_len);
+
+/**
+ * @brief The cpg_confchg_fn_t callback
+ */
+typedef void (*cpg_confchg_fn_t) (
+ cpg_handle_t handle,
+ const struct cpg_name *group_name,
+ const struct cpg_address *member_list, size_t member_list_entries,
+ const struct cpg_address *left_list, size_t left_list_entries,
+ const struct cpg_address *joined_list, size_t joined_list_entries);
+
+/**
+ * @brief The cpg_totem_confchg_fn_t callback
+ */
+typedef void (*cpg_totem_confchg_fn_t) (
+ cpg_handle_t handle,
+ struct cpg_ring_id ring_id,
+ uint32_t member_list_entries,
+ const uint32_t *member_list);
+
+/**
+ * @brief The cpg_callbacks_t struct
+ */
+typedef struct {
+ cpg_deliver_fn_t cpg_deliver_fn;
+ cpg_confchg_fn_t cpg_confchg_fn;
+} cpg_callbacks_t;
+
+/**
+ * @brief The cpg_model_data_t struct
+ */
+typedef struct {
+ cpg_model_t model;
+} cpg_model_data_t;
+
+#define CPG_MODEL_V1_DELIVER_INITIAL_TOTEM_CONF 0x01
+
+/**
+ * @brief The cpg_model_v1_data_t struct
+ */
+typedef struct {
+ cpg_model_t model;
+ cpg_deliver_fn_t cpg_deliver_fn;
+ cpg_confchg_fn_t cpg_confchg_fn;
+ cpg_totem_confchg_fn_t cpg_totem_confchg_fn;
+ unsigned int flags;
+} cpg_model_v1_data_t;
+
+
+/** @} */
+
+/**
+ * @brief Create a new cpg connection
+ * @param handle
+ * @param callbacks
+ * @return
+ */
+cs_error_t cpg_initialize (
+ cpg_handle_t *handle,
+ cpg_callbacks_t *callbacks);
+
+/**
+ * @brief Create a new cpg connection, initialize with model
+ * @param handle
+ * @param model
+ * @param model_data
+ * @param context
+ * @return
+ */
+cs_error_t cpg_model_initialize (
+ cpg_handle_t *handle,
+ cpg_model_t model,
+ cpg_model_data_t *model_data,
+ void *context);
+
+/**
+ * @brief Close the cpg handle
+ * @param handle
+ * @return
+ */
+cs_error_t cpg_finalize (
+ cpg_handle_t handle);
+
+/**
+ * @brief Get a file descriptor on which to poll.
+ *
+ * cpg_handle_t is NOT a file descriptor and may not be used directly.
+ *
+ * @param handle
+ * @param fd
+ * @return
+ */
+cs_error_t cpg_fd_get (
+ cpg_handle_t handle,
+ int *fd);
+
+/**
+ * @brief Get maximum size of a message that will not be fragmented
+ * @param handle
+ * @param size
+ * @return
+ */
+cs_error_t cpg_max_atomic_msgsize_get (
+ cpg_handle_t handle,
+ uint32_t *size);
+
+/**
+ * @brief Get contexts for a CPG handle
+ * @param handle
+ * @param context
+ * @return
+ */
+cs_error_t cpg_context_get (
+ cpg_handle_t handle,
+ void **context);
+
+/**
+ * @brief Set contexts for a CPG handle
+ * @param handle
+ * @param context
+ * @return
+ */
+cs_error_t cpg_context_set (
+ cpg_handle_t handle,
+ void *context);
+
+/**
+ * @brief Dispatch messages and configuration changes
+ * @param handle
+ * @param dispatch_types
+ * @return
+ */
+cs_error_t cpg_dispatch (
+ cpg_handle_t handle,
+ cs_dispatch_flags_t dispatch_types);
+
+/**
+ * @brief Join one or more groups.
+ *
+ * messages multicasted with cpg_mcast_joined will be sent to every
+ * group that has been joined on handle handle. Any message multicasted
+ * to a group that has been previously joined will be delivered in cpg_dispatch
+ *
+ * @param handle
+ * @param group
+ * @return
+ */
+cs_error_t cpg_join (
+ cpg_handle_t handle,
+ const struct cpg_name *group);
+
+/**
+ * @brief Leave one or more groups
+ * @param handle
+ * @param group
+ * @return
+ */
+cs_error_t cpg_leave (
+ cpg_handle_t handle,
+ const struct cpg_name *group);
+
+/**
+ * @brief Multicast to groups joined with cpg_join.
+ *
+ * @param handle
+ * @param guarantee
+ * @param iovec This iovec will be multicasted to all groups joined with
+ * the cpg_join interface for handle.
+ * @param iov_len
+ */
+cs_error_t cpg_mcast_joined (
+ cpg_handle_t handle,
+ cpg_guarantee_t guarantee,
+ const struct iovec *iovec,
+ unsigned int iov_len);
+
+/**
+ * @brief Get membership information from cpg
+ * @param handle
+ * @param groupName
+ * @param member_list
+ * @param member_list_entries
+ * @return
+ */
+cs_error_t cpg_membership_get (
+ cpg_handle_t handle,
+ struct cpg_name *groupName,
+ struct cpg_address *member_list,
+ int *member_list_entries);
+/**
+ * @brief cpg_local_get
+ * @param handle
+ * @param local_nodeid
+ * @return
+ */
+cs_error_t cpg_local_get (
+ cpg_handle_t handle,
+ unsigned int *local_nodeid);
+
+/**
+ * @brief cpg_flow_control_state_get
+ * @param handle
+ * @param flow_control_enabled
+ * @return
+ */
+cs_error_t cpg_flow_control_state_get (
+ cpg_handle_t handle,
+ cpg_flow_control_state_t *flow_control_enabled);
+
+/**
+ * @brief cpg_zcb_alloc
+ * @param handle
+ * @param size
+ * @param buffer
+ * @return
+ */
+cs_error_t cpg_zcb_alloc (
+ cpg_handle_t handle,
+ size_t size,
+ void **buffer);
+
+/**
+ * @brief cpg_zcb_free
+ * @param handle
+ * @param buffer
+ * @return
+ */
+cs_error_t cpg_zcb_free (
+ cpg_handle_t handle,
+ void *buffer);
+
+/**
+ * @brief cpg_zcb_mcast_joined
+ * @param handle
+ * @param guarantee
+ * @param msg
+ * @param msg_len
+ * @return
+ */
+cs_error_t cpg_zcb_mcast_joined (
+ cpg_handle_t handle,
+ cpg_guarantee_t guarantee,
+ void *msg,
+ size_t msg_len);
+
+/**
+ * @brief cpg_iteration_initialize
+ * @param handle
+ * @param iteration_type
+ * @param group
+ * @param cpg_iteration_handle
+ * @return
+ */
+cs_error_t cpg_iteration_initialize(
+ cpg_handle_t handle,
+ cpg_iteration_type_t iteration_type,
+ const struct cpg_name *group,
+ cpg_iteration_handle_t *cpg_iteration_handle);
+
+/**
+ * @brief cpg_iteration_next
+ * @param handle
+ * @param description
+ * @return
+ */
+cs_error_t cpg_iteration_next(
+ cpg_iteration_handle_t handle,
+ struct cpg_iteration_description_t *description);
+
+/**
+ * @brief cpg_iteration_finalize
+ * @param handle
+ * @return
+ */
+cs_error_t cpg_iteration_finalize (
+ cpg_iteration_handle_t handle);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* COROSYNC_CPG_H_DEFINED */
diff --git a/include/corosync/hdb.h b/include/corosync/hdb.h
new file mode 100644
index 0000000..01f379b
--- /dev/null
+++ b/include/corosync/hdb.h
@@ -0,0 +1,250 @@
+/*
+ * Copyright (c) 2002-2006 MontaVista Software, Inc.
+ * Copyright (c) 2006-2011 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Author: Steven Dake (sdake@redhat.com)
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of the MontaVista Software, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef HDB_H_DEFINED
+#define HDB_H_DEFINED
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+
+#include <errno.h>
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+#include <pthread.h>
+#include <stdint.h>
+#include <inttypes.h>
+#include <qb/qbhdb.h>
+
+typedef qb_handle_t hdb_handle_t;
+
+/*
+ * Formatting for string printing on 32/64 bit systems
+ */
+#define HDB_D_FORMAT QB_HDB_D_FORMAT
+#define HDB_X_FORMAT QB_HDB_X_FORMAT
+
+#define hdb_handle_database qb_hdb
+
+/**
+ * @brief hdb_database_lock
+ * @param mutex
+ */
+static inline void hdb_database_lock (pthread_mutex_t *mutex)
+{
+ pthread_mutex_lock (mutex);
+}
+
+/**
+ * @brief hdb_database_unlock
+ * @param mutex
+ */
+static inline void hdb_database_unlock (pthread_mutex_t *mutex)
+{
+ pthread_mutex_unlock (mutex);
+}
+
+/**
+ * @brief hdb_database_lock_init
+ * @param mutex
+ */
+static inline void hdb_database_lock_init (pthread_mutex_t *mutex)
+{
+ pthread_mutex_init (mutex, NULL);
+}
+
+/**
+ * @brief hdb_database_lock_destroy
+ * @param mutex
+ */
+static inline void hdb_database_lock_destroy (pthread_mutex_t *mutex)
+{
+ pthread_mutex_destroy (mutex);
+}
+
+#define DECLARE_HDB_DATABASE QB_HDB_DECLARE
+
+/**
+ * @brief hdb_create
+ * @param handle_database
+ */
+static inline void hdb_create (
+ struct hdb_handle_database *handle_database)
+{
+ qb_hdb_create (handle_database);
+}
+
+/**
+ * @brief hdb_destroy
+ * @param handle_database
+ */
+static inline void hdb_destroy (
+ struct hdb_handle_database *handle_database)
+{
+ qb_hdb_destroy (handle_database);
+}
+
+/**
+ * @brief hdb_handle_create
+ * @param handle_database
+ * @param instance_size
+ * @param handle_id_out
+ * @return
+ */
+static inline int hdb_handle_create (
+ struct hdb_handle_database *handle_database,
+ int instance_size,
+ hdb_handle_t *handle_id_out)
+{
+ return (qb_hdb_handle_create (handle_database, instance_size,
+ handle_id_out));
+}
+
+/**
+ * @brief hdb_handle_get
+ * @param handle_database
+ * @param handle_in
+ * @param instance
+ * @return
+ */
+static inline int hdb_handle_get (
+ struct hdb_handle_database *handle_database,
+ hdb_handle_t handle_in,
+ void **instance)
+{
+ return (qb_hdb_handle_get (handle_database, handle_in, instance));
+}
+
+/**
+ * @brief hdb_handle_get_always
+ * @param handle_database
+ * @param handle_in
+ * @param instance
+ * @return
+ */
+static inline int hdb_handle_get_always (
+ struct hdb_handle_database *handle_database,
+ hdb_handle_t handle_in,
+ void **instance)
+{
+ return (qb_hdb_handle_get_always (handle_database, handle_in, instance));
+}
+
+/**
+ * @brief hdb_handle_put
+ * @param handle_database
+ * @param handle_in
+ * @return
+ */
+static inline int hdb_handle_put (
+ struct hdb_handle_database *handle_database,
+ hdb_handle_t handle_in)
+{
+ return (qb_hdb_handle_put (handle_database, handle_in));
+}
+
+/**
+ * @brief hdb_handle_destroy
+ * @param handle_database
+ * @param handle_in
+ * @return
+ */
+static inline int hdb_handle_destroy (
+ struct hdb_handle_database *handle_database,
+ hdb_handle_t handle_in)
+{
+ return (qb_hdb_handle_destroy (handle_database, handle_in));
+}
+
+/**
+ * @brief hdb_handle_refcount_get
+ * @param handle_database
+ * @param handle_in
+ * @return
+ */
+static inline int hdb_handle_refcount_get (
+ struct hdb_handle_database *handle_database,
+ hdb_handle_t handle_in)
+{
+ return (qb_hdb_handle_refcount_get (handle_database, handle_in));
+}
+
+/**
+ * @brief hdb_iterator_reset
+ * @param handle_database
+ */
+static inline void hdb_iterator_reset (
+ struct hdb_handle_database *handle_database)
+{
+ qb_hdb_iterator_reset (handle_database);
+}
+
+/**
+ * @brief hdb_iterator_next
+ * @param handle_database
+ * @param instance
+ * @param handle
+ * @return
+ */
+static inline int hdb_iterator_next (
+ struct hdb_handle_database *handle_database,
+ void **instance,
+ hdb_handle_t *handle)
+{
+ return (qb_hdb_iterator_next (handle_database, instance, handle));
+}
+
+/**
+ * @brief hdb_base_convert
+ * @param handle
+ * @return
+ */
+static inline unsigned int hdb_base_convert (hdb_handle_t handle)
+{
+ return (qb_hdb_base_convert (handle));
+}
+
+/**
+ * @brief hdb_nocheck_convert
+ * @param handle
+ * @return
+ */
+static inline unsigned long long hdb_nocheck_convert (unsigned int handle)
+{
+ return (qb_hdb_nocheck_convert (handle));
+}
+
+#endif /* HDB_H_DEFINED */
diff --git a/include/corosync/icmap.h b/include/corosync/icmap.h
new file mode 100644
index 0000000..b168376
--- /dev/null
+++ b/include/corosync/icmap.h
@@ -0,0 +1,565 @@
+/*
+ * Copyright (c) 2011-2017 Red Hat, Inc.
+ *
+ * Author: Jan Friesse (jfriesse@redhat.com)
+ *
+ * All rights reserved.
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of the Red Hat, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef ICMAP_H_DEFINED
+#define ICMAP_H_DEFINED
+
+#include <stdlib.h>
+#include <corosync/corotypes.h>
+#include <qb/qbmap.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Maximum length of key in icmap
+ */
+#define ICMAP_KEYNAME_MAXLEN 255
+
+/**
+ * Minimum lenght of key in icmap
+ */
+#define ICMAP_KEYNAME_MINLEN 3
+
+/**
+ * Possible types of value. Binary is raw data without trailing zero with given length
+ */
+typedef enum {
+ ICMAP_VALUETYPE_INT8 = 1,
+ ICMAP_VALUETYPE_UINT8 = 2,
+ ICMAP_VALUETYPE_INT16 = 3,
+ ICMAP_VALUETYPE_UINT16 = 4,
+ ICMAP_VALUETYPE_INT32 = 5,
+ ICMAP_VALUETYPE_UINT32 = 6,
+ ICMAP_VALUETYPE_INT64 = 7,
+ ICMAP_VALUETYPE_UINT64 = 8,
+ ICMAP_VALUETYPE_FLOAT = 9,
+ ICMAP_VALUETYPE_DOUBLE = 10,
+ ICMAP_VALUETYPE_STRING = 11,
+ ICMAP_VALUETYPE_BINARY = 12,
+} icmap_value_types_t;
+
+/*
+ * Tracking values.
+ */
+#define ICMAP_TRACK_ADD 4
+#define ICMAP_TRACK_DELETE 1
+#define ICMAP_TRACK_MODIFY 2
+
+/**
+ * Whole prefix is tracked, instead of key only (so "totem." tracking means that
+ * "totem.nodeid", "totem.version", ... applies). This value is also never returned
+ * inside of callback and is used only in adding track
+ */
+#define ICMAP_TRACK_PREFIX 8
+
+/**
+ * Structure passed as new_value and old_value in change callback. It contains type of
+ * key, length of key and pointer to value of key
+ */
+struct icmap_notify_value {
+ icmap_value_types_t type;
+ size_t len;
+ const void *data;
+};
+
+/**
+ * Prototype for notify callback function. Even is one of ICMAP_TRACK_* event, key_name is
+ * changed key, new and old_value contains values or are zeroed (in other words, type is non
+ * existing 0 type) if there were no old (creating of key) or new (deleting of key) value.
+ * user_data are passed when adding tracking.
+ */
+typedef void (*icmap_notify_fn_t) (
+ int32_t event,
+ const char *key_name,
+ struct icmap_notify_value new_value,
+ struct icmap_notify_value old_value,
+ void *user_data);
+
+/**
+ * @brief icmap type.
+ *
+ * icmap.c contains global variable (icmap_global_map) of this type. This
+ * is used in every non-reentant call. Also only in this table are implemented
+ * operations like set_ro and tracking of values. Other tables (created by
+ * icmap_init_r) are simple map tables with get/set/iter operations.
+ */
+typedef struct icmap_map *icmap_map_t;
+
+/**
+ * @brief Itterator type
+ */
+typedef qb_map_iter_t *icmap_iter_t;
+
+/**
+ * @brief Track type
+ */
+typedef struct icmap_track *icmap_track_t;
+
+/**
+ * @brief Initialize global icmap
+ * @return
+ */
+extern cs_error_t icmap_init(void);
+
+/**
+ * @brief Initialize additional (local, reentrant) icmap_map. Content of variable
+ * result is undefined if return code is not CS_OK.
+ * @param result
+ * @return
+ */
+extern cs_error_t icmap_init_r(icmap_map_t *result);
+
+/**
+ * @brief Finalize global icmap
+ */
+extern void icmap_fini(void);
+
+/**
+ * @brief Finalize local, reentrant icmap
+ * @param map
+ */
+extern void icmap_fini_r(const icmap_map_t map);
+
+/**
+ * @brief Return global icmap
+ * @return
+ */
+extern icmap_map_t icmap_get_global_map(void);
+
+/**
+ * @brief Compare value of key with name key_name1 in map1 with key with name key_name2
+ * in map2.
+ *
+ * Two values must have same type, length and value to be considered equal.
+ * Function returns 0 when any of map1, key_name1, map2, key_name2 are NULL, or
+ * key_name is not found in map, or keys are not equal. != 0 is returned when
+ * values are equal.
+ *
+ * @param map1
+ * @param key_name1
+ * @param map2
+ * @param key_name2
+ * @return
+ */
+extern int icmap_key_value_eq(
+ const icmap_map_t map1,
+ const char *key_name1,
+ const icmap_map_t map2,
+ const char *key_name2);
+
+/**
+ * @brief Store value with value_len length and type as key_name name in global icmap.
+ * @param key_name
+ * @param value
+ * @param value_len
+ * @param type
+ * @return
+ */
+extern cs_error_t icmap_set(
+ const char *key_name,
+ const void *value,
+ size_t value_len,
+ icmap_value_types_t type);
+
+/**
+ * @brief Reentrant version of icmap_set
+ * @param map
+ * @param key_name
+ * @param value
+ * @param value_len
+ * @param type
+ * @return
+ */
+extern cs_error_t icmap_set_r(
+ const icmap_map_t map,
+ const char *key_name,
+ const void *value,
+ size_t value_len,
+ icmap_value_types_t type);
+
+/*
+ * Shortcuts for setting values
+ */
+extern cs_error_t icmap_set_int8(const char *key_name, int8_t value);
+extern cs_error_t icmap_set_uint8(const char *key_name, uint8_t value);
+extern cs_error_t icmap_set_int16(const char *key_name, int16_t value);
+extern cs_error_t icmap_set_uint16(const char *key_name, uint16_t value);
+extern cs_error_t icmap_set_int32(const char *key_name, int32_t value);
+extern cs_error_t icmap_set_uint32(const char *key_name, uint32_t value);
+extern cs_error_t icmap_set_int64(const char *key_name, int64_t value);
+extern cs_error_t icmap_set_uint64(const char *key_name, uint64_t value);
+extern cs_error_t icmap_set_float(const char *key_name, float value);
+extern cs_error_t icmap_set_double(const char *key_name, double value);
+extern cs_error_t icmap_set_string(const char *key_name, const char *value);
+
+extern cs_error_t icmap_set_int8_r(const icmap_map_t map, const char *key_name, int8_t value);
+extern cs_error_t icmap_set_uint8_r(const icmap_map_t map, const char *key_name, uint8_t value);
+extern cs_error_t icmap_set_int16_r(const icmap_map_t map, const char *key_name, int16_t value);
+extern cs_error_t icmap_set_uint16_r(const icmap_map_t map, const char *key_name, uint16_t value);
+extern cs_error_t icmap_set_int32_r(const icmap_map_t map, const char *key_name, int32_t value);
+extern cs_error_t icmap_set_uint32_r(const icmap_map_t map, const char *key_name, uint32_t value);
+extern cs_error_t icmap_set_int64_r(const icmap_map_t map, const char *key_name, int64_t value);
+extern cs_error_t icmap_set_uint64_r(const icmap_map_t map, const char *key_name, uint64_t value);
+extern cs_error_t icmap_set_float_r(const icmap_map_t map, const char *key_name, float value);
+extern cs_error_t icmap_set_double_r(const icmap_map_t map, const char *key_name, double value);
+extern cs_error_t icmap_set_string_r(const icmap_map_t map, const char *key_name, const char *value);
+
+/**
+ * @brief Delete key from map
+ * @param key_name
+ * @return
+ */
+extern cs_error_t icmap_delete(const char *key_name);
+
+/**
+ * @brief icmap_delete_r
+ * @param map
+ * @param key_name
+ * @return
+ */
+extern cs_error_t icmap_delete_r(const icmap_map_t map, const char *key_name);
+
+/**
+ * @brief Retrieve value of key key_name and store it in user preallocated value pointer.
+ *
+ * Value can be NULL, and then only value_len and/or type is returned (both of them
+ * can also be NULL). If value is not NULL, actual length of value in map is checked
+ * against value_len. If *value_len is shorter then length of value in map, error
+ * CS_ERR_INVALID_PARAM is returned. After successful copy of value, value_len is
+ * set to actual length of value in map.
+ *
+ * @param key_name
+ * @param value
+ * @param value_len
+ * @param type
+ * @return
+ */
+extern cs_error_t icmap_get(
+ const char *key_name,
+ void *value,
+ size_t *value_len,
+ icmap_value_types_t *type);
+
+/**
+ * @brief Same as icmap_get but it's reentrant and operates on given icmap_map
+ * @param map
+ * @param key_name
+ * @param value
+ * @param value_len
+ * @param type
+ * @return
+ */
+extern cs_error_t icmap_get_r(
+ const icmap_map_t map,
+ const char *key_name,
+ void *value,
+ size_t *value_len,
+ icmap_value_types_t *type);
+
+/*
+ * Shortcuts for icmap_get
+ */
+extern cs_error_t icmap_get_int8(const char *key_name, int8_t *i8);
+extern cs_error_t icmap_get_uint8(const char *key_name, uint8_t *u8);
+extern cs_error_t icmap_get_int16(const char *key_name, int16_t *i16);
+extern cs_error_t icmap_get_uint16(const char *key_name, uint16_t *u16);
+extern cs_error_t icmap_get_int32(const char *key_name, int32_t *i32);
+extern cs_error_t icmap_get_uint32(const char *key_name, uint32_t *u32);
+extern cs_error_t icmap_get_int64(const char *key_name, int64_t *i64);
+extern cs_error_t icmap_get_uint64(const char *key_name, uint64_t *u64);
+extern cs_error_t icmap_get_float(const char *key_name, float *flt);
+extern cs_error_t icmap_get_double(const char *key_name, double *dbl);
+
+/*
+ * Shortcuts for icmap_get_r
+ */
+extern cs_error_t icmap_get_int8_r(const icmap_map_t map, const char *key_name, int8_t *i8);
+extern cs_error_t icmap_get_uint8_r(const icmap_map_t map, const char *key_name, uint8_t *u8);
+extern cs_error_t icmap_get_int16_r(const icmap_map_t map, const char *key_name, int16_t *i16);
+extern cs_error_t icmap_get_uint16_r(const icmap_map_t map, const char *key_name, uint16_t *u16);
+extern cs_error_t icmap_get_int32_r(const icmap_map_t map, const char *key_name, int32_t *i32);
+extern cs_error_t icmap_get_uint32_r(const icmap_map_t map, const char *key_name, uint32_t *u32);
+extern cs_error_t icmap_get_int64_r(const icmap_map_t map, const char *key_name, int64_t *i64);
+extern cs_error_t icmap_get_uint64_r(const icmap_map_t map, const char *key_name, uint64_t *u64);
+extern cs_error_t icmap_get_float_r(const icmap_map_t map, const char *key_name, float *flt);
+extern cs_error_t icmap_get_double_r(const icmap_map_t map, const char *key_name, double *dbl);
+extern cs_error_t icmap_get_string_r(const icmap_map_t map, const char *key_name, char **str);
+
+/**
+ * @brief Shortcut for icmap_get for string type.
+ *
+ * Returned string is newly allocated and
+ * caller is responsible for freeing memory
+ *
+ * @param key_name
+ * @param str
+ * @return
+ */
+extern cs_error_t icmap_get_string(const char *key_name, char **str);
+
+/**
+ * @brief icmap_adjust_int
+ *
+ * Defined only for [u]int* values. It adds step to current value.
+ *
+ * @param key_name
+ * @param step
+ * @return
+ */
+extern cs_error_t icmap_adjust_int(const char *key_name, int32_t step);
+
+/**
+ * @brief icmap_adjust_int_r
+ * @param map
+ * @param key_name
+ * @param step
+ * @return
+ */
+extern cs_error_t icmap_adjust_int_r(const icmap_map_t map, const char *key_name, int32_t step);
+
+/**
+ * @brief icmap_fast_adjust_int
+ *
+ * Defined only for [u]int* values. It adds step to current value. Difference
+ * between this function and icmap_adjust_int is given in fact, that in
+ * tracking callback, old value is undefined, but whole process is done
+ * without malloc/memcpy.
+ *
+ * @param key_name
+ * @param step
+ * @return
+ */
+extern cs_error_t icmap_fast_adjust_int(const char *key_name, int32_t step);
+
+/**
+ * @brief icmap_fast_adjust_int_r
+ * @param map
+ * @param key_name
+ * @param step
+ * @return
+ */
+extern cs_error_t icmap_fast_adjust_int_r(const icmap_map_t map, const char *key_name, int32_t step);
+
+/**
+ * @brief Increase stored value by one
+ * @param key_name
+ * @return
+ */
+extern cs_error_t icmap_inc(const char *key_name);
+
+/**
+ * @brief icmap_inc_r
+ * @param map
+ * @param key_name
+ * @return
+ */
+extern cs_error_t icmap_inc_r(const icmap_map_t map, const char *key_name);
+
+/**
+ * @brief Decrease stored value by one
+ * @param key_name
+ * @return
+ */
+extern cs_error_t icmap_dec(const char *key_name);
+
+/**
+ * @brief icmap_dec_r
+ * @param map
+ * @param key_name
+ * @return
+ */
+extern cs_error_t icmap_dec_r(const icmap_map_t map, const char *key_name);
+
+/**
+ * @brief Increase stored value by one.
+ *
+ * Difference between this function and icmap_inc
+ * is same as between icmap_adjust_int and icmap_fast_adjust_int.
+ *
+ * @param key_name
+ * @return
+ */
+extern cs_error_t icmap_fast_inc(const char *key_name);
+
+/**
+ * @brief icmap_fast_inc_r
+ * @param map
+ * @param key_name
+ * @return
+ */
+extern cs_error_t icmap_fast_inc_r(const icmap_map_t map, const char *key_name);
+
+/**
+ * @brief Decrease stored value by one.
+ *
+ * Difference between this function and icmap_dec
+ * is same as between icmap_adjust_int and icmap_fast_adjust_int.
+ *
+ * @param key_name
+ * @return
+ */
+extern cs_error_t icmap_fast_dec(const char *key_name);
+
+/**
+ * @brief icmap_fast_dec_r
+ * @param map
+ * @param key_name
+ * @return
+ */
+extern cs_error_t icmap_fast_dec_r(const icmap_map_t map, const char *key_name);
+
+/**
+ * @brief Initialize iterator with given prefix
+ * @param prefix
+ * @return
+ */
+extern icmap_iter_t icmap_iter_init(const char *prefix);
+
+/**
+ * @brief icmap_iter_init_r
+ * @param map
+ * @param prefix
+ * @return
+ */
+extern icmap_iter_t icmap_iter_init_r(const icmap_map_t map, const char *prefix);
+
+/**
+ * @brief Return next item in iterator iter.
+ *
+ * value_len and type are optional (= can be NULL), but if set, length of returned value
+ * and/or type is returned. Function returns following key_name or NULL if iteration is over.
+ *
+ * @param iter
+ * @param value_len
+ * @param type
+ * @return
+ */
+extern const char *icmap_iter_next(icmap_iter_t iter, size_t *value_len, icmap_value_types_t *type);
+
+/**
+ * @brief Finalize iterator
+ * @param iter
+ */
+extern void icmap_iter_finalize(icmap_iter_t iter);
+
+/**
+ * @brief Add tracking function for given key_name.
+ *
+ * Tracked changes (add|modify|delete) depend on track_type, which is bitwise or of ICMAP_TRACK_* values.
+ * notify_fn is called on change, where user_data pointer is passed (unchanged).
+ * Value which can be used to delete tracking is passed as icmap_track.
+ *
+ * @param key_name
+ * @param track_type
+ * @param notify_fn
+ * @param user_data
+ * @param icmap_track
+ * @return
+ */
+extern cs_error_t icmap_track_add(
+ const char *key_name,
+ int32_t track_type,
+ icmap_notify_fn_t notify_fn,
+ void *user_data,
+ icmap_track_t *icmap_track);
+
+/**
+ * @brief Return user data associated with given track
+ * @param icmap_track
+ * @return
+ */
+extern void *icmap_track_get_user_data(icmap_track_t icmap_track);
+
+/**
+ * @brief Remove previously added track
+ * @param icmap_track
+ * @return
+ */
+extern cs_error_t icmap_track_delete(icmap_track_t icmap_track);
+
+/**
+ * @brief Set read-only access for given key (key_name) or prefix,
+ * If prefix is set. ro_access can be !0, which means, that old information
+ * about ro of this key is deleted. Read-only access is used only in CMAP service!
+ * (in other word it prevents users from deleting/changing key, but doesn't
+ * guarantee anything for internal icmap users.)
+ * @param key_name
+ * @param prefix
+ * @param ro_access
+ * @return
+ */
+extern cs_error_t icmap_set_ro_access(const char *key_name, int prefix, int ro_access);
+
+/**
+ * @brief Check in given key is read only. Returns !0 if so, otherwise (key is rw) 0.
+ * @param key_name
+ * @return
+ */
+extern int icmap_is_key_ro(const char *key_name);
+
+/**
+ * @brief Converts given key_name to valid key name (replacing all prohibited characters by _)
+ * @param key_name
+ */
+extern void icmap_convert_name_to_valid_name(char *key_name);
+
+/**
+ * @brief Copy content of src_map icmap to dst_map icmap.
+ * @param dst_map
+ * @param src_map
+ * @return
+ */
+extern cs_error_t icmap_copy_map(icmap_map_t dst_map, const icmap_map_t src_map);
+
+/*
+ * Returns length of value of given type, or 0 for string and binary data type
+ */
+size_t icmap_get_valuetype_len(icmap_value_types_t type);
+
+/*
+ * Converts track type of icmap to qb
+ */
+int32_t icmap_tt_to_qbtt(int32_t track_type);
+
+/*
+ * Convert track type of qb to icmap
+ */
+int32_t icmap_qbtt_to_tt(int32_t track_type);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ICMAP_H_DEFINED */
diff --git a/include/corosync/ipc_cfg.h b/include/corosync/ipc_cfg.h
new file mode 100644
index 0000000..07e4adc
--- /dev/null
+++ b/include/corosync/ipc_cfg.h
@@ -0,0 +1,307 @@
+/*
+ * Copyright (c) 2005 MontaVista Software, Inc.
+ * Copyright (c) 2009-2013 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Author: Steven Dake (sdake@redhat.com)
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of the MontaVista Software, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef IPC_CFG_H_DEFINED
+#define IPC_CFG_H_DEFINED
+
+#include <netinet/in.h>
+#include <corosync/corotypes.h>
+#include <corosync/mar_gen.h>
+
+#define CFG_INTERFACE_NAME_MAX_LEN 128
+#define CFG_INTERFACE_STATUS_MAX_LEN 512
+/*
+ * Too keep future ABI compatibility, this value
+ * is intentionaly bigger then INTERFACE_MAX
+ */
+#define CFG_MAX_INTERFACES 16
+
+/**
+ * @brief The req_lib_cfg_types enum
+ */
+enum req_lib_cfg_types {
+ MESSAGE_REQ_CFG_RINGSTATUSGET = 0,
+ MESSAGE_REQ_CFG_RINGREENABLE = 1,
+ MESSAGE_REQ_CFG_KILLNODE = 2,
+ MESSAGE_REQ_CFG_TRYSHUTDOWN = 3,
+ MESSAGE_REQ_CFG_REPLYTOSHUTDOWN = 4,
+ MESSAGE_REQ_CFG_GET_NODE_ADDRS = 5,
+ MESSAGE_REQ_CFG_LOCAL_GET = 6,
+ MESSAGE_REQ_CFG_RELOAD_CONFIG = 7,
+ MESSAGE_REQ_CFG_REOPEN_LOG_FILES = 8,
+ MESSAGE_REQ_CFG_NODESTATUSGET = 9,
+ MESSAGE_REQ_CFG_TRACKSTART = 10,
+ MESSAGE_REQ_CFG_TRACKSTOP = 11
+};
+
+/**
+ * @brief The res_lib_cfg_types enum
+ */
+enum res_lib_cfg_types {
+ MESSAGE_RES_CFG_RINGSTATUSGET = 0,
+ MESSAGE_RES_CFG_RINGREENABLE = 1,
+ MESSAGE_RES_CFG_STATETRACKSTART = 2,
+ MESSAGE_RES_CFG_STATETRACKSTOP = 3,
+ MESSAGE_RES_CFG_ADMINISTRATIVESTATESET = 4,
+ MESSAGE_RES_CFG_ADMINISTRATIVESTATEGET = 5,
+ MESSAGE_RES_CFG_SERVICELOAD = 6,
+ MESSAGE_RES_CFG_SERVICEUNLOAD = 7,
+ MESSAGE_RES_CFG_KILLNODE = 8,
+ MESSAGE_RES_CFG_TRYSHUTDOWN = 9,
+ MESSAGE_RES_CFG_TESTSHUTDOWN = 10,
+ MESSAGE_RES_CFG_GET_NODE_ADDRS = 11,
+ MESSAGE_RES_CFG_LOCAL_GET = 12,
+ MESSAGE_RES_CFG_REPLYTOSHUTDOWN = 13,
+ MESSAGE_RES_CFG_RELOAD_CONFIG = 14,
+ MESSAGE_RES_CFG_REOPEN_LOG_FILES = 15,
+ MESSAGE_RES_CFG_NODESTATUSGET = 16
+};
+
+/**
+ * @brief The req_lib_cfg_ringstatusget struct
+ */
+struct req_lib_cfg_ringstatusget {
+ struct qb_ipc_request_header header __attribute__((aligned(8)));
+};
+
+/**
+ * @brief The res_lib_cfg_ringstatusget struct
+ */
+struct res_lib_cfg_ringstatusget {
+ struct qb_ipc_response_header header __attribute__((aligned(8)));
+ mar_uint32_t interface_count __attribute__((aligned(8)));
+ char interface_name[CFG_MAX_INTERFACES][CFG_INTERFACE_NAME_MAX_LEN] __attribute__((aligned(8)));
+ char interface_status[CFG_MAX_INTERFACES][CFG_INTERFACE_STATUS_MAX_LEN] __attribute__((aligned(8)));
+};
+
+/**
+ * @brief The req_lib_cfg_nodestatusget struct
+ */
+struct req_lib_cfg_nodestatusget {
+ struct qb_ipc_request_header header __attribute__((aligned(8)));
+ unsigned int nodeid __attribute__((aligned(8)));
+ mar_uint32_t version __attribute__((aligned(8)));
+};
+
+struct res_lib_cfg_nodestatusget_version {
+ struct qb_ipc_response_header header __attribute__((aligned(8)));
+ corosync_cfg_node_status_version_t version __attribute__((aligned(8)));
+};
+
+/**
+ * @brief The res_lib_cfg_nodestatusget struct
+ */
+struct res_lib_cfg_nodestatusget_v1 {
+ struct qb_ipc_response_header header __attribute__((aligned(8)));
+ struct corosync_cfg_node_status_v1 node_status __attribute__((aligned(8)));
+};
+
+/**
+ * @brief The req_lib_cfg_ringreenable struct
+ */
+struct req_lib_cfg_ringreenable {
+ struct qb_ipc_request_header header __attribute__((aligned(8)));
+};
+
+/**
+ * @brief The res_lib_cfg_ringreenable struct
+ */
+struct res_lib_cfg_ringreenable {
+ struct qb_ipc_response_header header __attribute__((aligned(8)));
+};
+
+/**
+ * @brief The req_lib_cfg_killnode struct
+ */
+struct req_lib_cfg_killnode {
+ struct qb_ipc_request_header header __attribute__((aligned(8)));
+ unsigned int nodeid __attribute__((aligned(8)));
+ cs_name_t reason __attribute__((aligned(8)));
+};
+
+/**
+ * @brief The res_lib_cfg_killnode struct
+ */
+struct res_lib_cfg_killnode {
+ struct qb_ipc_response_header header __attribute__((aligned(8)));
+};
+
+/**
+ * @brief The req_lib_cfg_tryshutdown struct
+ */
+struct req_lib_cfg_tryshutdown {
+ struct qb_ipc_request_header header __attribute__((aligned(8)));
+ unsigned int flags;
+};
+
+/**
+ * @brief The res_lib_cfg_tryshutdown struct
+ */
+struct res_lib_cfg_tryshutdown {
+ struct qb_ipc_response_header header __attribute__((aligned(8)));
+};
+
+/**
+ * @brief The req_lib_cfg_replytoshutdown struct
+ */
+struct req_lib_cfg_replytoshutdown {
+ struct qb_ipc_request_header header __attribute__((aligned(8)));
+ unsigned int response;
+};
+
+/**
+ * @brief The res_lib_cfg_replytoshutdown struct
+ */
+struct res_lib_cfg_replytoshutdown {
+ struct qb_ipc_response_header header __attribute__((aligned(8)));
+};
+
+/**
+ * @brief The res_lib_cfg_testshutdown struct
+ */
+struct res_lib_cfg_testshutdown {
+ struct qb_ipc_response_header header __attribute__((aligned(8)));
+ unsigned int flags;
+};
+
+/**
+ * @brief The req_lib_cfg_get_node_addrs struct
+ */
+struct req_lib_cfg_get_node_addrs {
+ struct qb_ipc_request_header header __attribute__((aligned(8)));
+ unsigned int nodeid;
+};
+
+/**
+ * @brief The res_lib_cfg_get_node_addrs struct
+ */
+struct res_lib_cfg_get_node_addrs {
+ struct qb_ipc_response_header header __attribute__((aligned(8)));
+ unsigned int family;
+ unsigned int num_addrs;
+ /* array of TOTEMIP_ADDRLEN items */
+ char addrs[];
+};
+
+/**
+ * @brief The req_lib_cfg_local_get struct
+ */
+struct req_lib_cfg_local_get {
+ struct qb_ipc_request_header header __attribute__((aligned(8)));
+};
+
+/**
+ * @brief The res_lib_cfg_local_get struct
+ */
+struct res_lib_cfg_local_get {
+ struct qb_ipc_response_header header __attribute__((aligned(8)));
+ mar_uint32_t local_nodeid __attribute__((aligned(8)));
+};
+
+/**
+ * @brief The req_lib_cfg_reload_config struct
+ */
+struct req_lib_cfg_reload_config {
+ struct qb_ipc_request_header header __attribute__((aligned(8)));
+};
+
+/**
+ * @brief The res_lib_cfg_reload_config struct
+ */
+struct res_lib_cfg_reload_config {
+ struct qb_ipc_response_header header __attribute__((aligned(8)));
+};
+
+/**
+ * @brief The req_lib_cfg_reopen_log_files struct
+ */
+struct req_lib_cfg_reopen_log_files {
+ struct qb_ipc_request_header header __attribute__((aligned(8)));
+};
+
+/**
+ * @brief The res_lib_cfg_reopen_log_files struct
+ */
+struct res_lib_cfg_reopen_log_files {
+ struct qb_ipc_response_header header __attribute__((aligned(8)));
+};
+
+struct req_lib_cfg_trackstart {
+ struct qb_ipc_request_header header;
+ uint8_t track_flags;
+};
+
+struct res_lib_cfg_trackstart {
+ struct qb_ipc_response_header header;
+};
+
+struct req_lib_cfg_trackstop {
+ struct qb_ipc_request_header header;
+};
+
+struct res_lib_cfg_trackstop {
+ struct qb_ipc_response_header header;
+};
+
+
+/**
+ * @brief corosync_administrative_target_t enum
+ */
+typedef enum {
+ AIS_AMF_ADMINISTRATIVETARGET_SERVICEUNIT = 0,
+ AIS_AMF_ADMINISTRATIVETARGET_SERVICEGROUP = 1,
+ AIS_AMF_ADMINISTRATIVETARGET_COMPONENTSERVICEINSTANCE = 2,
+ AIS_AMF_ADMINISTRATIVETARGET_NODE = 3
+} corosync_administrative_target_t;
+
+/**
+ * @brief corosync_administrative_state_t enum
+ */
+typedef enum {
+ AIS_AMF_ADMINISTRATIVESTATE_UNLOCKED = 0,
+ AIS_AMF_ADMINISTRATIVESTATE_LOCKED = 1,
+ AIS_AMF_ADMINISTRATIVESTATE_STOPPING = 2
+} corosync_administrative_state_t;
+
+/**
+ * @brief corosync_shutdown_flags_t enum
+ */
+typedef enum {
+ CFG_SHUTDOWN_FLAG_REQUEST = 0,
+ CFG_SHUTDOWN_FLAG_REGARDLESS = 1,
+ CFG_SHUTDOWN_FLAG_IMMEDIATE = 2,
+} corosync_shutdown_flags_t;
+
+
+#endif /* IPC_CFG_H_DEFINED */
diff --git a/include/corosync/ipc_cmap.h b/include/corosync/ipc_cmap.h
new file mode 100644
index 0000000..8a39b03
--- /dev/null
+++ b/include/corosync/ipc_cmap.h
@@ -0,0 +1,263 @@
+/*
+ * Copyright (c) 2011-2017 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Author: Jan Friesse (jfriesse@redhat.com)
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of the Red Hat, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef IPC_CMAP_H_DEFINED
+#define IPC_CMAP_H_DEFINED
+
+#include <netinet/in.h>
+#include <corosync/corotypes.h>
+#include <corosync/mar_gen.h>
+
+/**
+ * @brief The req_cmap_types enum
+ */
+enum req_cmap_types {
+ MESSAGE_REQ_CMAP_SET = 0,
+ MESSAGE_REQ_CMAP_DELETE = 1,
+ MESSAGE_REQ_CMAP_GET = 2,
+ MESSAGE_REQ_CMAP_ADJUST_INT = 3,
+ MESSAGE_REQ_CMAP_ITER_INIT = 4,
+ MESSAGE_REQ_CMAP_ITER_NEXT = 5,
+ MESSAGE_REQ_CMAP_ITER_FINALIZE = 6,
+ MESSAGE_REQ_CMAP_TRACK_ADD = 7,
+ MESSAGE_REQ_CMAP_TRACK_DELETE = 8,
+ MESSAGE_REQ_CMAP_SET_CURRENT_MAP = 9,
+};
+
+/**
+ * @brief The res_cmap_types enum
+ */
+enum res_cmap_types {
+ MESSAGE_RES_CMAP_SET = 0,
+ MESSAGE_RES_CMAP_DELETE = 1,
+ MESSAGE_RES_CMAP_GET = 2,
+ MESSAGE_RES_CMAP_ADJUST_INT = 3,
+ MESSAGE_RES_CMAP_ITER_INIT = 4,
+ MESSAGE_RES_CMAP_ITER_NEXT = 5,
+ MESSAGE_RES_CMAP_ITER_FINALIZE = 6,
+ MESSAGE_RES_CMAP_TRACK_ADD = 7,
+ MESSAGE_RES_CMAP_TRACK_DELETE = 8,
+ MESSAGE_RES_CMAP_NOTIFY_CALLBACK = 9,
+ MESSAGE_RES_CMAP_SET_CURRENT_MAP = 10,
+};
+
+enum {
+ CMAP_SETMAP_DEFAULT = 0,
+ CMAP_SETMAP_STATS = 1,
+};
+
+/**
+ * @brief The req_lib_cmap_set struct
+ */
+struct req_lib_cmap_set {
+ struct qb_ipc_request_header header __attribute__((aligned(8)));
+ mar_name_t key_name __attribute__((aligned(8)));
+ mar_size_t value_len __attribute__((aligned(8)));
+ mar_uint8_t type __attribute__((aligned(8)));
+ mar_uint8_t value[] __attribute__((aligned(8)));
+};
+
+/**
+ * @brief The res_lib_cmap_set struct
+ */
+struct res_lib_cmap_set {
+ struct qb_ipc_response_header header __attribute__((aligned(8)));
+};
+
+/**
+ * @brief The req_lib_cmap_delete struct
+ */
+struct req_lib_cmap_delete {
+ struct qb_ipc_request_header header __attribute__((aligned(8)));
+ mar_name_t key_name __attribute__((aligned(8)));
+};
+
+/**
+ * @brief The res_lib_cmap_delete struct
+ */
+struct res_lib_cmap_delete {
+ struct qb_ipc_response_header header __attribute__((aligned(8)));
+};
+
+/**
+ * @brief The req_lib_cmap_get struct
+ */
+struct req_lib_cmap_get {
+ struct qb_ipc_request_header header __attribute__((aligned(8)));
+ mar_name_t key_name __attribute__((aligned(8)));
+ mar_size_t value_len __attribute__((aligned(8)));
+};
+
+/**
+ * @brief The res_lib_cmap_get struct
+ */
+struct res_lib_cmap_get {
+ struct qb_ipc_response_header header __attribute__((aligned(8)));
+ mar_size_t value_len __attribute__((aligned(8)));
+ mar_uint8_t type __attribute__((aligned(8)));
+ mar_uint8_t value[] __attribute__((aligned(8)));
+};
+
+/**
+ * @brief The req_lib_cmap_adjust_int struct
+ */
+struct req_lib_cmap_adjust_int {
+ struct qb_ipc_request_header header __attribute__((aligned(8)));
+ mar_name_t key_name __attribute__((aligned(8)));
+ mar_int32_t step __attribute__((aligned(8)));
+};
+
+/**
+ * @brief The res_lib_cmap_adjust_int struct
+ */
+struct res_lib_cmap_adjust_int {
+ struct qb_ipc_response_header header __attribute__((aligned(8)));
+};
+
+/**
+ * @brief The req_lib_cmap_iter_init struct
+ */
+struct req_lib_cmap_iter_init {
+ struct qb_ipc_request_header header __attribute__((aligned(8)));
+ mar_name_t prefix __attribute__((aligned(8)));
+};
+
+/**
+ * @brief The res_lib_cmap_iter_init struct
+ */
+struct res_lib_cmap_iter_init {
+ struct qb_ipc_response_header header __attribute__((aligned(8)));
+ mar_uint64_t iter_handle __attribute__((aligned(8)));
+};
+
+/**
+ * @brief The req_lib_cmap_iter_next struct
+ */
+struct req_lib_cmap_iter_next {
+ struct qb_ipc_request_header header __attribute__((aligned(8)));
+ mar_uint64_t iter_handle __attribute__((aligned(8)));
+};
+
+/**
+ * @brief The res_lib_cmap_iter_next struct
+ */
+struct res_lib_cmap_iter_next {
+ struct qb_ipc_response_header header __attribute__((aligned(8)));
+ mar_name_t key_name __attribute__((aligned(8)));
+ mar_size_t value_len __attribute__((aligned(8)));
+ mar_uint8_t type __attribute__((aligned(8)));
+};
+
+/**
+ * @brief The req_lib_cmap_iter_finalize struct
+ */
+struct req_lib_cmap_iter_finalize {
+ struct qb_ipc_request_header header __attribute__((aligned(8)));
+ mar_uint64_t iter_handle __attribute__((aligned(8)));
+};
+
+/**
+ * @brief The res_lib_cmap_iter_finalize struct
+ */
+struct res_lib_cmap_iter_finalize {
+ struct qb_ipc_response_header header __attribute__((aligned(8)));
+};
+
+/**
+ * @brief The req_lib_cmap_track_add struct
+ */
+struct req_lib_cmap_track_add {
+ struct qb_ipc_request_header header __attribute__((aligned(8)));
+ mar_name_t key_name __attribute__((aligned(8)));
+ mar_int32_t track_type __attribute__((aligned(8)));
+ mar_uint64_t track_inst_handle __attribute__((aligned(8)));
+};
+
+/**
+ * @brief The res_lib_cmap_track_add struct
+ */
+struct res_lib_cmap_track_add {
+ struct qb_ipc_response_header header __attribute__((aligned(8)));
+ mar_uint64_t track_handle __attribute__((aligned(8)));
+};
+
+/**
+ * @brief The req_lib_cmap_track_delete struct
+ */
+struct req_lib_cmap_track_delete {
+ struct qb_ipc_request_header header __attribute__((aligned(8)));
+ mar_uint64_t track_handle __attribute__((aligned(8)));
+};
+
+/**
+ * @brief The res_lib_cmap_track_delete struct
+ */
+struct res_lib_cmap_track_delete {
+ struct qb_ipc_response_header header __attribute__((aligned(8)));
+ mar_uint64_t track_inst_handle __attribute__((aligned(8)));
+};
+
+/**
+ * @brief The res_lib_cmap_notify_callback struct
+ */
+struct res_lib_cmap_notify_callback {
+ struct qb_ipc_response_header header __attribute__((aligned(8)));
+ mar_uint64_t track_inst_handle __attribute__((aligned(8)));
+ mar_name_t key_name __attribute__((aligned(8)));
+ mar_int32_t event __attribute__((aligned(8)));
+ mar_uint8_t new_value_type __attribute__((aligned(8)));
+ mar_uint8_t old_value_type __attribute__((aligned(8)));
+ mar_size_t new_value_len __attribute__((aligned(8)));
+ mar_size_t old_value_len __attribute__((aligned(8)));
+ /*
+ * After old_vale_len, there are two items with length of new_value_len
+ * and old_value_len, only first (as a pointer) is defined
+ *
+ * mar_uint8_t *new_value;
+ * mar_uint8_t *old_value;
+ */
+ mar_uint8_t new_value[];
+};
+
+/**
+ * @brief The req_lib_cmap_set_current_map struct
+ * used by cmap_initialize_map()
+ */
+struct req_lib_cmap_set_current_map {
+ struct qb_ipc_request_header header __attribute__((aligned(8)));
+ mar_int32_t map __attribute__((aligned(8)));
+};
+
+
+#endif /* IPC_CMAP_H_DEFINED */
diff --git a/include/corosync/ipc_cpg.h b/include/corosync/ipc_cpg.h
new file mode 100644
index 0000000..67ef737
--- /dev/null
+++ b/include/corosync/ipc_cpg.h
@@ -0,0 +1,502 @@
+/*
+ * Copyright (c) 2006-2015 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Author: Christine Caulfield (ccaulfie@redhat.com)
+ * Author: Jan Friesse (jfriesse@redhat.com)
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of the MontaVista Software, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef IPC_CPG_H_DEFINED
+#define IPC_CPG_H_DEFINED
+
+#include <netinet/in.h>
+#include <qb/qbipc_common.h>
+#include <corosync/corotypes.h>
+#include <corosync/mar_gen.h>
+
+#define CPG_ZC_PATH_LEN 128
+
+/**
+ * @brief The req_cpg_types enum
+ */
+enum req_cpg_types {
+ MESSAGE_REQ_CPG_JOIN = 0,
+ MESSAGE_REQ_CPG_LEAVE = 1,
+ MESSAGE_REQ_CPG_MCAST = 2,
+ MESSAGE_REQ_CPG_MEMBERSHIP = 3,
+ MESSAGE_REQ_CPG_LOCAL_GET = 4,
+ MESSAGE_REQ_CPG_ITERATIONINITIALIZE = 5,
+ MESSAGE_REQ_CPG_ITERATIONNEXT = 6,
+ MESSAGE_REQ_CPG_ITERATIONFINALIZE = 7,
+ MESSAGE_REQ_CPG_FINALIZE = 8,
+ MESSAGE_REQ_CPG_ZC_ALLOC = 9,
+ MESSAGE_REQ_CPG_ZC_FREE = 10,
+ MESSAGE_REQ_CPG_ZC_EXECUTE = 11,
+ MESSAGE_REQ_CPG_PARTIAL_MCAST = 12,
+};
+
+/**
+ * @brief The res_cpg_types enum
+ */
+enum res_cpg_types {
+ MESSAGE_RES_CPG_JOIN = 0,
+ MESSAGE_RES_CPG_LEAVE = 1,
+ MESSAGE_RES_CPG_MCAST = 2,
+ MESSAGE_RES_CPG_MEMBERSHIP = 3,
+ MESSAGE_RES_CPG_CONFCHG_CALLBACK = 4,
+ MESSAGE_RES_CPG_DELIVER_CALLBACK = 5,
+ MESSAGE_RES_CPG_FLOW_CONTROL_STATE_SET = 6,
+ MESSAGE_RES_CPG_LOCAL_GET = 7,
+ MESSAGE_RES_CPG_FLOWCONTROL_CALLBACK = 8,
+ MESSAGE_RES_CPG_ITERATIONINITIALIZE = 9,
+ MESSAGE_RES_CPG_ITERATIONNEXT = 10,
+ MESSAGE_RES_CPG_ITERATIONFINALIZE = 11,
+ MESSAGE_RES_CPG_FINALIZE = 12,
+ MESSAGE_RES_CPG_TOTEM_CONFCHG_CALLBACK = 13,
+ MESSAGE_RES_CPG_ZC_ALLOC = 14,
+ MESSAGE_RES_CPG_ZC_FREE = 15,
+ MESSAGE_RES_CPG_ZC_EXECUTE = 16,
+ MESSAGE_RES_CPG_PARTIAL_DELIVER_CALLBACK = 17,
+ MESSAGE_RES_CPG_PARTIAL_SEND = 18,
+};
+
+/**
+ * @brief The lib_cpg_confchg_reason enum
+ */
+enum lib_cpg_confchg_reason {
+ CONFCHG_CPG_REASON_JOIN = 1,
+ CONFCHG_CPG_REASON_LEAVE = 2,
+ CONFCHG_CPG_REASON_NODEDOWN = 3,
+ CONFCHG_CPG_REASON_NODEUP = 4,
+ CONFCHG_CPG_REASON_PROCDOWN = 5
+};
+
+/**
+ * @brief The lib_cpg_partial_types enum
+ */
+enum lib_cpg_partial_types {
+ LIBCPG_PARTIAL_FIRST = 1,
+ LIBCPG_PARTIAL_CONTINUED = 2,
+ LIBCPG_PARTIAL_LAST = 3,
+};
+
+/**
+ * @brief mar_cpg_name_t struct
+ */
+typedef struct {
+ uint32_t length __attribute__((aligned(8)));
+ char value[CPG_MAX_NAME_LENGTH] __attribute__((aligned(8)));
+} mar_cpg_name_t;
+
+/**
+ * @brief swab_mar_cpg_name_t
+ * @param to_swab
+ */
+static inline void swab_mar_cpg_name_t (mar_cpg_name_t *to_swab)
+{
+ swab_mar_uint32_t (&to_swab->length);
+}
+
+/**
+ * @brief marshall_from_mar_cpg_name_t
+ * @param dest
+ * @param src
+ */
+static inline void marshall_from_mar_cpg_name_t (
+ struct cpg_name *dest,
+ const mar_cpg_name_t *src)
+{
+ dest->length = src->length;
+ memcpy (&dest->value, &src->value, CPG_MAX_NAME_LENGTH);
+}
+
+/**
+ * @brief marshall_to_mar_cpg_name_t
+ * @param dest
+ * @param src
+ */
+static inline void marshall_to_mar_cpg_name_t (
+ mar_cpg_name_t *dest,
+ const struct cpg_name *src)
+{
+ dest->length = src->length;
+ memcpy (&dest->value, &src->value, CPG_MAX_NAME_LENGTH);
+}
+
+/**
+ * @brief mar_cpg_address_t struct
+ */
+typedef struct {
+ mar_uint32_t nodeid __attribute__((aligned(8)));
+ mar_uint32_t pid __attribute__((aligned(8)));
+ mar_uint32_t reason __attribute__((aligned(8)));
+} mar_cpg_address_t;
+
+/**
+ * @brief marshall_from_mar_cpg_address_t
+ * @param dest
+ * @param src
+ */
+static inline void marshall_from_mar_cpg_address_t (
+ struct cpg_address *dest,
+ const mar_cpg_address_t *src)
+{
+ dest->nodeid = src->nodeid;
+ dest->pid = src->pid;
+ dest->reason = src->reason;
+}
+
+/**
+ * @brief marshall_to_mar_cpg_address_t
+ * @param dest
+ * @param src
+ */
+static inline void marshall_to_mar_cpg_address_t (
+ mar_cpg_address_t *dest,
+ const struct cpg_address *src)
+{
+ dest->nodeid = src->nodeid;
+ dest->pid = src->pid;
+ dest->reason = src->reason;
+}
+
+/**
+ * @brief mar_name_compare
+ * @param g1
+ * @param g2
+ * @return
+ */
+static inline int mar_name_compare (
+ const mar_cpg_name_t *g1,
+ const mar_cpg_name_t *g2)
+{
+ return (g1->length == g2->length?
+ memcmp (g1->value, g2->value, g1->length):
+ g1->length - g2->length);
+}
+
+/**
+ * @brief mar_cpg_iteration_description_t struct
+ */
+typedef struct {
+ mar_cpg_name_t group;
+ mar_uint32_t nodeid;
+ mar_uint32_t pid;
+} mar_cpg_iteration_description_t;
+
+/**
+ * @brief marshall_from_mar_cpg_iteration_description_t
+ * @param dest
+ * @param src
+ */
+static inline void marshall_from_mar_cpg_iteration_description_t(
+ struct cpg_iteration_description_t *dest,
+ const mar_cpg_iteration_description_t *src)
+{
+ dest->nodeid = src->nodeid;
+ dest->pid = src->pid;
+ marshall_from_mar_cpg_name_t (&dest->group, &src->group);
+};
+
+/**
+ * @brief mar_cpg_ring_id_t struct
+ */
+typedef struct {
+ mar_uint32_t nodeid __attribute__((aligned(8)));
+ mar_uint64_t seq __attribute__((aligned(8)));
+} mar_cpg_ring_id_t;
+
+/**
+ * @brief marshall_from_mar_cpg_ring_id_t
+ * @param dest
+ * @param src
+ */
+static inline void marshall_from_mar_cpg_ring_id_t (
+ struct cpg_ring_id *dest,
+ const mar_cpg_ring_id_t *src)
+{
+ dest->nodeid = src->nodeid;
+ dest->seq = src->seq;
+}
+
+/**
+ * @brief The req_lib_cpg_join struct
+ */
+struct req_lib_cpg_join {
+ struct qb_ipc_request_header header __attribute__((aligned(8)));
+ mar_cpg_name_t group_name __attribute__((aligned(8)));
+ mar_uint32_t pid __attribute__((aligned(8)));
+ mar_uint32_t flags __attribute__((aligned(8)));
+};
+
+/**
+ * @brief The res_lib_cpg_join struct
+ */
+struct res_lib_cpg_join {
+ struct qb_ipc_response_header header __attribute__((aligned(8)));
+};
+
+/**
+ * @brief The req_lib_cpg_finalize struct
+ */
+struct req_lib_cpg_finalize {
+ struct qb_ipc_request_header header __attribute__((aligned(8)));
+};
+
+/**
+ * @brief The res_lib_cpg_finalize struct
+ */
+struct res_lib_cpg_finalize {
+ struct qb_ipc_response_header header __attribute__((aligned(8)));
+};
+
+/**
+ * @brief The req_lib_cpg_local_get struct
+ */
+struct req_lib_cpg_local_get {
+ struct qb_ipc_request_header header __attribute__((aligned(8)));
+};
+
+/**
+ * @brief The res_lib_cpg_local_get struct
+ */
+struct res_lib_cpg_local_get {
+ struct qb_ipc_response_header header __attribute__((aligned(8)));
+ mar_uint32_t local_nodeid __attribute__((aligned(8)));
+};
+
+/**
+ * @brief The res_lib_cpg_partial_send struct
+ */
+struct res_lib_cpg_partial_send {
+ struct qb_ipc_response_header header __attribute__((aligned(8)));
+};
+
+/**
+ * @brief The req_lib_cpg_mcast struct
+ */
+struct req_lib_cpg_mcast {
+ struct qb_ipc_response_header header __attribute__((aligned(8)));
+ mar_uint32_t guarantee __attribute__((aligned(8)));
+ mar_uint32_t msglen __attribute__((aligned(8)));
+ mar_uint8_t message[] __attribute__((aligned(8)));
+};
+
+/**
+ * @brief The req_lib_cpg_partial_mcast struct
+ */
+struct req_lib_cpg_partial_mcast {
+ struct qb_ipc_response_header header __attribute__((aligned(8)));
+ mar_uint32_t guarantee __attribute__((aligned(8)));
+ mar_uint32_t msglen __attribute__((aligned(8)));
+ mar_uint32_t fraglen __attribute__((aligned(8)));
+ mar_uint32_t type __attribute__((aligned(8)));
+ mar_uint8_t message[] __attribute__((aligned(8)));
+};
+
+/**
+ * @brief The res_lib_cpg_mcast struct
+ */
+struct res_lib_cpg_mcast {
+ struct qb_ipc_response_header header __attribute__((aligned(8)));
+};
+
+/**
+ * Message from another node
+ */
+struct res_lib_cpg_deliver_callback {
+ struct qb_ipc_response_header header __attribute__((aligned(8)));
+ mar_cpg_name_t group_name __attribute__((aligned(8)));
+ mar_uint32_t msglen __attribute__((aligned(8)));
+ mar_uint32_t nodeid __attribute__((aligned(8)));
+ mar_uint32_t pid __attribute__((aligned(8)));
+ mar_uint8_t message[] __attribute__((aligned(8)));
+};
+
+/**
+ * @brief The res_lib_cpg_partial_deliver_callback struct
+ */
+struct res_lib_cpg_partial_deliver_callback {
+ struct qb_ipc_response_header header __attribute__((aligned(8)));
+ mar_cpg_name_t group_name __attribute__((aligned(8)));
+ mar_uint32_t msglen __attribute__((aligned(8)));
+ mar_uint32_t fraglen __attribute__((aligned(8)));
+ mar_uint32_t nodeid __attribute__((aligned(8)));
+ mar_uint32_t pid __attribute__((aligned(8)));
+ mar_uint32_t type __attribute__((aligned(8)));
+ mar_uint8_t message[] __attribute__((aligned(8)));
+};
+
+/**
+ * @brief The res_lib_cpg_flowcontrol_callback struct
+ */
+struct res_lib_cpg_flowcontrol_callback {
+ struct qb_ipc_response_header header __attribute__((aligned(8)));
+ mar_uint32_t flow_control_state __attribute__((aligned(8)));
+};
+
+/**
+ * @brief The req_lib_cpg_membership_get struct
+ */
+struct req_lib_cpg_membership_get {
+ struct qb_ipc_request_header header __attribute__((aligned(8)));
+ mar_cpg_name_t group_name __attribute__((aligned(8)));
+};
+
+/**
+ * @brief The res_lib_cpg_membership_get struct
+ */
+struct res_lib_cpg_membership_get {
+ struct qb_ipc_response_header header __attribute__((aligned(8)));
+ mar_uint32_t member_count __attribute__((aligned(8)));
+ mar_cpg_address_t member_list[PROCESSOR_COUNT_MAX];
+};
+
+/**
+ * @brief The res_lib_cpg_confchg_callback struct
+ */
+struct res_lib_cpg_confchg_callback {
+ struct qb_ipc_response_header header __attribute__((aligned(8)));
+ mar_cpg_name_t group_name __attribute__((aligned(8)));
+ mar_uint32_t member_list_entries __attribute__((aligned(8)));
+ mar_uint32_t joined_list_entries __attribute__((aligned(8)));
+ mar_uint32_t left_list_entries __attribute__((aligned(8)));
+ mar_cpg_address_t member_list[];
+// struct cpg_address left_list[];
+// struct cpg_address joined_list[];
+};
+
+/**
+ * @brief The res_lib_cpg_totem_confchg_callback struct
+ */
+struct res_lib_cpg_totem_confchg_callback {
+ struct qb_ipc_response_header header __attribute__((aligned(8)));
+ mar_cpg_ring_id_t ring_id __attribute__((aligned(8)));
+ mar_uint32_t member_list_entries __attribute__((aligned(8)));
+ mar_uint32_t member_list[];
+};
+
+/**
+ * @brief The req_lib_cpg_leave struct
+ */
+struct req_lib_cpg_leave {
+ struct qb_ipc_request_header header __attribute__((aligned(8)));
+ mar_cpg_name_t group_name __attribute__((aligned(8)));
+ mar_uint32_t pid __attribute__((aligned(8)));
+};
+
+/**
+ * @brief The res_lib_cpg_leave struct
+ */
+struct res_lib_cpg_leave {
+ struct qb_ipc_response_header header __attribute__((aligned(8)));
+};
+
+/**
+ * @brief The req_lib_cpg_iterationinitialize struct
+ */
+struct req_lib_cpg_iterationinitialize {
+ struct qb_ipc_request_header header __attribute__((aligned(8)));
+ mar_cpg_name_t group_name __attribute__((aligned(8)));
+ mar_uint32_t iteration_type __attribute__((aligned(8)));
+};
+
+/**
+ * @brief The res_lib_cpg_iterationinitialize struct
+ */
+struct res_lib_cpg_iterationinitialize {
+ struct qb_ipc_response_header header __attribute__((aligned(8)));
+ hdb_handle_t iteration_handle __attribute__((aligned(8)));
+};
+
+/**
+ * @brief The req_lib_cpg_iterationnext struct
+ */
+struct req_lib_cpg_iterationnext {
+ struct qb_ipc_request_header header __attribute__((aligned(8)));
+ hdb_handle_t iteration_handle __attribute__((aligned(8)));
+};
+
+/**
+ * @brief The res_lib_cpg_iterationnext struct
+ */
+struct res_lib_cpg_iterationnext {
+ struct qb_ipc_response_header header __attribute__((aligned(8)));
+ mar_cpg_iteration_description_t description __attribute__((aligned(8)));
+};
+
+/**
+ * @brief The req_lib_cpg_iterationfinalize struct
+ */
+struct req_lib_cpg_iterationfinalize {
+ struct qb_ipc_request_header header __attribute__((aligned(8)));
+ hdb_handle_t iteration_handle __attribute__((aligned(8)));
+};
+
+/**
+ * @brief The res_lib_cpg_iterationfinalize struct
+ */
+struct res_lib_cpg_iterationfinalize {
+ struct qb_ipc_response_header header __attribute__((aligned(8)));
+};
+
+/**
+ * @brief mar_req_coroipcc_zc_alloc_t struct
+ */
+typedef struct {
+ struct qb_ipc_request_header header __attribute__((aligned(8)));
+ size_t map_size __attribute__((aligned(8)));
+ char path_to_file[CPG_ZC_PATH_LEN] __attribute__((aligned(8)));
+} mar_req_coroipcc_zc_alloc_t __attribute__((aligned(8)));
+
+/**
+ * @brief mar_req_coroipcc_zc_free_t struct
+ */
+typedef struct {
+ struct qb_ipc_request_header header __attribute__((aligned(8)));
+ size_t map_size __attribute__((aligned(8)));
+ uint64_t server_address __attribute__((aligned(8)));
+} mar_req_coroipcc_zc_free_t __attribute__((aligned(8)));
+
+/**
+ * @brief mar_req_coroipcc_zc_execute_t struct
+ */
+typedef struct {
+ struct qb_ipc_request_header header __attribute__((aligned(8)));
+ uint64_t server_address __attribute__((aligned(8)));
+} mar_req_coroipcc_zc_execute_t __attribute__((aligned(8)));
+
+/**
+ * @brief coroipcs_zc_header struct
+ */
+struct coroipcs_zc_header {
+ int map_size;
+ uint64_t server_address;
+};
+#endif /* IPC_CPG_H_DEFINED */
diff --git a/include/corosync/ipc_quorum.h b/include/corosync/ipc_quorum.h
new file mode 100644
index 0000000..62c7ddf
--- /dev/null
+++ b/include/corosync/ipc_quorum.h
@@ -0,0 +1,142 @@
+/*
+ * Copyright (c) 2008-2020 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Author: Christine Caulfield (ccaulfie@redhat.com)
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of the MontaVista Software, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef IPC_QUORUM_H_DEFINED
+#define IPC_QUORUM_H_DEFINED
+
+#include <corosync/corotypes.h>
+#include <corosync/mar_gen.h>
+
+/**
+ * @brief The req_quorum_types enum
+ */
+enum req_quorum_types {
+ MESSAGE_REQ_QUORUM_GETQUORATE = 0,
+ MESSAGE_REQ_QUORUM_TRACKSTART,
+ MESSAGE_REQ_QUORUM_TRACKSTOP,
+ MESSAGE_REQ_QUORUM_GETTYPE,
+ MESSAGE_REQ_QUORUM_MODEL_GETTYPE
+};
+
+/**
+ * @brief The res_quorum_types enum
+ */
+enum res_quorum_types {
+ MESSAGE_RES_QUORUM_GETQUORATE = 0,
+ MESSAGE_RES_QUORUM_TRACKSTART,
+ MESSAGE_RES_QUORUM_TRACKSTOP,
+ MESSAGE_RES_QUORUM_NOTIFICATION,
+ MESSAGE_RES_QUORUM_GETTYPE,
+ MESSAGE_RES_QUORUM_MODEL_GETTYPE,
+ MESSAGE_RES_QUORUM_V1_QUORUM_NOTIFICATION,
+ MESSAGE_RES_QUORUM_V1_NODELIST_NOTIFICATION
+};
+
+/*
+ * Must be in sync with definition in quorum.h
+ */
+enum lib_quorum_model {
+ LIB_QUORUM_MODEL_V0 = 0,
+ LIB_QUORUM_MODEL_V1 = 1,
+};
+
+typedef struct {
+ mar_uint32_t nodeid __attribute__((aligned(8)));
+ mar_uint64_t seq __attribute__((aligned(8)));
+} mar_quorum_ring_id_t;
+
+/**
+ * @brief The req_lib_quorum_trackstart struct
+ */
+struct req_lib_quorum_trackstart {
+ struct qb_ipc_request_header header __attribute__((aligned(8)));
+ unsigned int track_flags;
+};
+
+/**
+ * @brief The res_lib_quorum_getquorate struct
+ */
+struct res_lib_quorum_getquorate {
+ struct qb_ipc_response_header header __attribute__((aligned(8)));
+ mar_uint32_t quorate;
+};
+
+/**
+ * @brief The res_lib_quorum_notification struct
+ */
+struct res_lib_quorum_notification {
+ struct qb_ipc_response_header header __attribute__((aligned(8)));
+ mar_int32_t quorate __attribute__((aligned(8)));
+ mar_uint64_t ring_seq __attribute__((aligned(8)));
+ mar_uint32_t view_list_entries __attribute__((aligned(8)));
+ mar_uint32_t view_list[];
+};
+
+struct res_lib_quorum_v1_quorum_notification {
+ struct qb_ipc_response_header header __attribute__((aligned(8)));
+ mar_int32_t quorate __attribute__((aligned(8)));
+ mar_quorum_ring_id_t ring_id __attribute__((aligned(8)));
+ mar_uint32_t view_list_entries __attribute__((aligned(8)));
+ mar_uint32_t view_list[];
+};
+
+struct res_lib_quorum_v1_nodelist_notification {
+ struct qb_ipc_response_header header __attribute__((aligned(8)));
+ mar_quorum_ring_id_t ring_id __attribute__((aligned(8)));
+ mar_uint32_t member_list_entries __attribute__((aligned(8)));
+ mar_uint32_t joined_list_entries __attribute__((aligned(8)));
+ mar_uint32_t left_list_entries __attribute__((aligned(8)));
+ mar_uint32_t member_list[];
+// mar_uint32_t joined_list[];
+// mar_uint32_t left_list[];
+};
+
+/**
+ * @brief The res_lib_quorum_gettype struct
+ */
+struct res_lib_quorum_gettype {
+ struct qb_ipc_response_header header __attribute__((aligned(8)));
+ mar_uint32_t quorum_type;
+};
+
+struct req_lib_quorum_model_gettype {
+ struct qb_ipc_request_header header __attribute__((aligned(8)));
+ mar_uint32_t model __attribute__((aligned(8)));
+};
+
+struct res_lib_quorum_model_gettype {
+ struct qb_ipc_response_header header __attribute__((aligned(8)));
+ mar_uint32_t quorum_type __attribute__((aligned(8)));
+};
+
+#endif
diff --git a/include/corosync/ipc_votequorum.h b/include/corosync/ipc_votequorum.h
new file mode 100644
index 0000000..5f855d0
--- /dev/null
+++ b/include/corosync/ipc_votequorum.h
@@ -0,0 +1,265 @@
+/*
+ * Copyright (c) 2009-2012 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Authors: Christine Caulfield (ccaulfie@redhat.com)
+ * Fabio M. Di Nitto (fdinitto@redhat.com)
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of the MontaVista Software, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef IPC_VOTEQUORUM_H_DEFINED
+#define IPC_VOTEQUORUM_H_DEFINED
+
+#include <corosync/mar_gen.h>
+#define VOTEQUORUM_QDEVICE_NODEID 0
+#define VOTEQUORUM_QDEVICE_MAX_NAME_LEN 255
+#define VOTEQUORUM_QDEVICE_DEFAULT_TIMEOUT 10000
+
+/**
+ * @brief The req_votequorum_types enum
+ */
+enum req_votequorum_types {
+ MESSAGE_REQ_VOTEQUORUM_GETINFO = 0,
+ MESSAGE_REQ_VOTEQUORUM_SETEXPECTED,
+ MESSAGE_REQ_VOTEQUORUM_SETVOTES,
+ MESSAGE_REQ_VOTEQUORUM_TRACKSTART,
+ MESSAGE_REQ_VOTEQUORUM_TRACKSTOP,
+ MESSAGE_REQ_VOTEQUORUM_QDEVICE_REGISTER,
+ MESSAGE_REQ_VOTEQUORUM_QDEVICE_UNREGISTER,
+ MESSAGE_REQ_VOTEQUORUM_QDEVICE_UPDATE,
+ MESSAGE_REQ_VOTEQUORUM_QDEVICE_POLL,
+ MESSAGE_REQ_VOTEQUORUM_QDEVICE_MASTER_WINS
+};
+
+/**
+ * @brief The res_votequorum_types enum
+ */
+enum res_votequorum_types {
+ MESSAGE_RES_VOTEQUORUM_STATUS = 0,
+ MESSAGE_RES_VOTEQUORUM_GETINFO,
+ MESSAGE_RES_VOTEQUORUM_TRACKSTART,
+ MESSAGE_RES_VOTEQUORUM_QUORUM_NOTIFICATION,
+ MESSAGE_RES_VOTEQUORUM_EXPECTEDVOTES_NOTIFICATION,
+ MESSAGE_RES_VOTEQUORUM_NODELIST_NOTIFICATION,
+};
+
+/**
+ * @brief The mar_votequorum_ring_id struct
+ */
+struct mar_votequorum_ring_id {
+ mar_uint32_t nodeid;
+ mar_uint64_t seq;
+};
+
+/**
+ * @brief The req_lib_votequorum_qdevice_register struct
+ */
+struct req_lib_votequorum_qdevice_register {
+ struct qb_ipc_request_header header __attribute__((aligned(8)));
+ char name[VOTEQUORUM_QDEVICE_MAX_NAME_LEN];
+};
+
+/**
+ * @brief The req_lib_votequorum_qdevice_unregister struct
+ */
+struct req_lib_votequorum_qdevice_unregister {
+ struct qb_ipc_request_header header __attribute__((aligned(8)));
+ char name[VOTEQUORUM_QDEVICE_MAX_NAME_LEN];
+};
+
+/**
+ * @brief The req_lib_votequorum_qdevice_update struct
+ */
+struct req_lib_votequorum_qdevice_update {
+ struct qb_ipc_request_header header __attribute__((aligned(8)));
+ char oldname[VOTEQUORUM_QDEVICE_MAX_NAME_LEN];
+ char newname[VOTEQUORUM_QDEVICE_MAX_NAME_LEN];
+};
+
+/**
+ * @brief The req_lib_votequorum_qdevice_poll struct
+ */
+struct req_lib_votequorum_qdevice_poll {
+ struct qb_ipc_request_header header __attribute__((aligned(8)));
+ char name[VOTEQUORUM_QDEVICE_MAX_NAME_LEN];
+ int cast_vote;
+ struct mar_votequorum_ring_id ring_id __attribute__((aligned(8)));
+};
+
+/**
+ * @brief The req_lib_votequorum_qdevice_master_wins struct
+ */
+struct req_lib_votequorum_qdevice_master_wins {
+ struct qb_ipc_request_header header __attribute__((aligned(8)));
+ char name[VOTEQUORUM_QDEVICE_MAX_NAME_LEN];
+ unsigned int allow;
+};
+
+/**
+ * @brief The req_lib_votequorum_setvotes struct
+ */
+struct req_lib_votequorum_setvotes {
+ struct qb_ipc_request_header header __attribute__((aligned(8)));
+ unsigned int votes;
+ int nodeid;
+};
+
+/**
+ * @brief The req_lib_votequorum_setexpected struct
+ */
+struct req_lib_votequorum_setexpected {
+ struct qb_ipc_request_header header __attribute__((aligned(8)));
+ unsigned int expected_votes;
+};
+
+/**
+ * @brief The req_lib_votequorum_trackstart struct
+ */
+struct req_lib_votequorum_trackstart {
+ struct qb_ipc_request_header header __attribute__((aligned(8)));
+ uint64_t context;
+ unsigned int track_flags;
+};
+
+/**
+ * @brief The req_lib_votequorum_general struct
+ */
+struct req_lib_votequorum_general {
+ struct qb_ipc_request_header header __attribute__((aligned(8)));
+};
+
+/**
+ * @brief The req_lib_votequorum_getinfo struct
+ */
+struct req_lib_votequorum_getinfo {
+ struct qb_ipc_request_header header __attribute__((aligned(8)));
+ int nodeid;
+};
+
+/**
+ * @brief The res_lib_votequorum_status struct
+ */
+struct res_lib_votequorum_status {
+ struct qb_ipc_response_header header __attribute__((aligned(8)));
+};
+
+#define VOTEQUORUM_INFO_TWONODE 1
+#define VOTEQUORUM_INFO_QUORATE 2
+#define VOTEQUORUM_INFO_WAIT_FOR_ALL 4
+#define VOTEQUORUM_INFO_LAST_MAN_STANDING 8
+#define VOTEQUORUM_INFO_AUTO_TIE_BREAKER 16
+#define VOTEQUORUM_INFO_ALLOW_DOWNSCALE 32
+#define VOTEQUORUM_INFO_QDEVICE_REGISTERED 64
+#define VOTEQUORUM_INFO_QDEVICE_ALIVE 128
+#define VOTEQUORUM_INFO_QDEVICE_CAST_VOTE 256
+#define VOTEQUORUM_INFO_QDEVICE_MASTER_WINS 512
+
+#define VOTEQUORUM_NODESTATE_MEMBER 1
+#define VOTEQUORUM_NODESTATE_DEAD 2
+#define VOTEQUORUM_NODESTATE_LEAVING 3
+
+/**
+ * @brief The res_lib_votequorum_getinfo struct
+ */
+struct res_lib_votequorum_getinfo {
+ struct qb_ipc_response_header header __attribute__((aligned(8)));
+ unsigned int nodeid;
+ unsigned int state;
+ unsigned int votes;
+ unsigned int expected_votes;
+ unsigned int highest_expected;
+ unsigned int total_votes;
+ unsigned int quorum;
+ unsigned int flags;
+ unsigned int qdevice_votes;
+ char qdevice_name[VOTEQUORUM_QDEVICE_MAX_NAME_LEN];
+};
+
+/**
+ * @brief The votequorum_node struct
+ */
+struct votequorum_node {
+ mar_uint32_t nodeid;
+ mar_uint32_t state;
+};
+
+/**
+ * @brief The res_lib_votequorum_quorum_notification struct
+ */
+struct res_lib_votequorum_quorum_notification {
+ struct qb_ipc_response_header header __attribute__((aligned(8)));
+ mar_uint32_t quorate __attribute__((aligned(8)));
+ mar_uint64_t context __attribute__((aligned(8)));
+ mar_uint32_t node_list_entries __attribute__((aligned(8)));
+ struct votequorum_node node_list[] __attribute__((aligned(8)));
+};
+
+struct res_lib_votequorum_nodelist_notification {
+ struct qb_ipc_response_header header __attribute__((aligned(8)));
+ mar_uint64_t context __attribute__((aligned(8)));
+ struct mar_votequorum_ring_id ring_id __attribute__((aligned(8)));
+ mar_uint32_t node_list_entries __attribute__((aligned(8)));
+ mar_uint32_t node_list[] __attribute__((aligned(8)));
+};
+
+/**
+ * @brief The res_lib_votequorum_expectedvotes_notification struct
+ */
+struct res_lib_votequorum_expectedvotes_notification {
+ struct qb_ipc_response_header header __attribute__((aligned(8)));
+ mar_uint64_t context __attribute__((aligned(8)));
+ mar_uint32_t expected_votes __attribute__((aligned(8)));
+};
+
+/**
+ * @brief marshall_from_mar_votequorum_ring_id
+ * @param dest
+ * @param src
+ */
+static inline void marshall_from_mar_votequorum_ring_id (
+ votequorum_ring_id_t *dest,
+ const struct mar_votequorum_ring_id *src)
+{
+ dest->nodeid = src->nodeid;
+ dest->seq = src->seq;
+};
+
+/**
+ * @brief marshall_to_mar_votequorum_ring_id
+ * @param dest
+ * @param src
+ */
+static inline void marshall_to_mar_votequorum_ring_id (
+ struct mar_votequorum_ring_id *dest,
+ const votequorum_ring_id_t *src)
+{
+ dest->nodeid = src->nodeid;
+ dest->seq = src->seq;
+};
+
+#endif
diff --git a/include/corosync/logsys.h b/include/corosync/logsys.h
new file mode 100644
index 0000000..325b24b
--- /dev/null
+++ b/include/corosync/logsys.h
@@ -0,0 +1,350 @@
+/*
+ * Copyright (c) 2002-2004 MontaVista Software, Inc.
+ * Copyright (c) 2006-2012 Red Hat, Inc.
+ *
+ * Author: Steven Dake (sdake@redhat.com)
+ * Author: Lon Hohberger (lhh@redhat.com)
+ * Author: Fabio M. Di Nitto (fdinitto@redhat.com)
+ *
+ * All rights reserved.
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of the MontaVista Software, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef LOGSYS_H_DEFINED
+#define LOGSYS_H_DEFINED
+
+#include <stdarg.h>
+#include <stdlib.h>
+#include <syslog.h>
+#include <pthread.h>
+#include <limits.h>
+
+#include <corosync/corotypes.h>
+
+#include <qb/qbconfig.h>
+#include <qb/qblog.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * All of the LOGSYS_MODE's can be ORed together for combined behavior
+ *
+ * FORK and THREADED are ignored for SUBSYSTEMS
+ */
+#define LOGSYS_MODE_OUTPUT_FILE (1<<0)
+#define LOGSYS_MODE_OUTPUT_STDERR (1<<1)
+#define LOGSYS_MODE_OUTPUT_SYSLOG (1<<2)
+#define LOGSYS_MODE_FORK (1<<3)
+#define LOGSYS_MODE_THREADED (1<<4)
+
+/*
+ * Log priorities, compliant with syslog and SA Forum Log spec.
+ */
+#define LOGSYS_LEVEL_EMERG LOG_EMERG
+#define LOGSYS_LEVEL_ALERT LOG_ALERT
+#define LOGSYS_LEVEL_CRIT LOG_CRIT
+#define LOGSYS_LEVEL_ERROR LOG_ERR
+#define LOGSYS_LEVEL_WARNING LOG_WARNING
+#define LOGSYS_LEVEL_NOTICE LOG_NOTICE
+#define LOGSYS_LEVEL_INFO LOG_INFO
+#define LOGSYS_LEVEL_DEBUG LOG_DEBUG
+#define LOGSYS_LEVEL_TRACE LOG_TRACE
+
+/*
+ * logsys_logger bits
+ *
+ * SUBSYS_COUNT defines the maximum number of subsystems
+ * SUBSYS_NAMELEN defines the maximum len of a subsystem name
+ */
+#define LOGSYS_MAX_SUBSYS_COUNT 32
+#define LOGSYS_MAX_SUBSYS_NAMELEN 64
+#define LOGSYS_MAX_PERROR_MSG_LEN 128
+
+/*
+ * Debug levels
+ */
+#define LOGSYS_DEBUG_OFF 0
+#define LOGSYS_DEBUG_ON 1
+#define LOGSYS_DEBUG_TRACE 2
+
+#ifndef LOGSYS_UTILS_ONLY
+
+/**
+ * @brief configuration bits that can only be done for the whole system
+ * @param format
+ * @return
+ */
+extern int logsys_format_set (
+ const char *format);
+
+/**
+ * @brief logsys_format_get
+ * @return
+ */
+extern char *logsys_format_get (void);
+
+/**
+ * @brief per system/subsystem settings.
+ *
+ * NOTE: once a subsystem is created and configured, changing
+ * the default does NOT affect the subsystems.
+ *
+ * Pass a NULL subsystem to change them all
+ *
+ * @param subsys
+ * @param facility
+ * @return
+ */
+extern int logsys_config_syslog_facility_set (
+ const char *subsys,
+ unsigned int facility);
+
+/**
+ * @brief logsys_config_syslog_priority_set
+ * @param subsys
+ * @param priority
+ * @return
+ */
+extern int logsys_config_syslog_priority_set (
+ const char *subsys,
+ unsigned int priority);
+
+/**
+ * @brief logsys_config_mode_set
+ * @param subsys
+ * @param mode
+ * @return
+ */
+extern int logsys_config_mode_set (
+ const char *subsys,
+ unsigned int mode);
+
+/**
+ * @brief logsys_config_mode_get
+ * @param subsys
+ * @return
+ */
+extern unsigned int logsys_config_mode_get (
+ const char *subsys);
+
+/**
+ * @brief logsys_config_apply
+ */
+void logsys_config_apply(void);
+
+/**
+ * @brief to close a logfile, just invoke this function with a NULL
+ * file or if you want to change logfile, the old one will
+ * be closed for you.
+ *
+ * @param subsys
+ * @param error_string
+ * @param file
+ * @return
+ */
+extern int logsys_config_file_set (
+ const char *subsys,
+ const char **error_string,
+ const char *file);
+
+/**
+ * @brief logsys_config_logfile_priority_set
+ * @param subsys
+ * @param priority
+ * @return
+ */
+extern int logsys_config_logfile_priority_set (
+ const char *subsys,
+ unsigned int priority);
+
+/**
+ * @brief enabling debug, disable message priority filtering.
+ * everything is sent everywhere. priority values
+ * for file and syslog are not overwritten.
+ *
+ * @param subsys
+ * @param value
+ * @return
+ */
+extern int logsys_config_debug_set (
+ const char *subsys,
+ unsigned int value);
+
+/**
+ * @brief Return the debug flag for this subsys
+ *
+ * @param subsys
+ * @return LOGSYS_DEBUG_OFF | LOGSYS_DEBUG_ON | LOGSYS_DEBUG_TRACE
+ */
+extern int logsys_config_debug_get (
+ const char *subsys);
+
+/*
+ * External API - helpers
+ *
+ * convert facility/priority to/from name/values
+ */
+/**
+ * @brief logsys_priority_id_get
+ * @param name
+ * @return
+ */
+extern int logsys_priority_id_get (
+ const char *name);
+
+/**
+ * @brief logsys_priority_name_get
+ * @param priority
+ * @return
+ */
+extern const char *logsys_priority_name_get (
+ unsigned int priority);
+
+/**
+ * @brief _logsys_system_setup
+ * @param mainsystem
+ * @param mode
+ * @param syslog_facility
+ * @param syslog_priority
+ * @return
+ */
+extern int _logsys_system_setup(
+ const char *mainsystem,
+ unsigned int mode,
+ int syslog_facility,
+ int syslog_priority);
+
+/**
+ * @brief logsys_system_fini
+ */
+extern void logsys_system_fini (void);
+
+/**
+ * @brief _logsys_config_subsys_get
+ * @param subsys
+ * @return
+ */
+extern int _logsys_config_subsys_get (
+ const char *subsys);
+
+/**
+ * @brief _logsys_subsys_create
+ * @param subsys
+ * @param filename
+ * @return
+ */
+extern int _logsys_subsys_create (const char *subsys, const char *filename);
+
+/**
+ * @brief logsys_thread_start
+ * @return
+ */
+extern int logsys_thread_start (void);
+
+extern void logsys_blackbox_set(int enable);
+
+extern void logsys_blackbox_prefork(void);
+
+extern void logsys_blackbox_postfork(void);
+
+extern cs_error_t logsys_reopen_log_files(void);
+
+/**
+ * @brief logsys_subsys_id
+ */
+static int logsys_subsys_id __attribute__((unused)) = LOGSYS_MAX_SUBSYS_COUNT;
+
+/**
+ * @brief The LOGSYS_DECLARE_SYSTEM macro
+ * @param name
+ * @param mode
+ * @param syslog_facility
+ * @param syslog_priority
+ */
+#define LOGSYS_DECLARE_SYSTEM(name,mode,syslog_facility,syslog_priority)\
+QB_LOG_INIT_DATA(logsys_qb_init); \
+__attribute__ ((constructor)) \
+static void logsys_system_init (void) \
+{ \
+ if (_logsys_system_setup (name,mode,syslog_facility,syslog_priority) < 0) { \
+ fprintf (stderr, \
+ "Unable to setup logging system: %s.\n", name); \
+ exit (-1); \
+ } \
+}
+
+/**
+ * @brief The LOGSYS_DECLARE_SUBSYS macro
+ * @param subsys
+ */
+#define LOGSYS_DECLARE_SUBSYS(subsys) \
+__attribute__ ((constructor)) \
+static void logsys_subsys_init (void) \
+{ \
+ logsys_subsys_id = \
+ _logsys_subsys_create ((subsys), __FILE__); \
+ if (logsys_subsys_id == -1) { \
+ fprintf (stderr, \
+ "Unable to create logging subsystem: %s.\n", subsys); \
+ exit (-1); \
+ } \
+}
+
+/**
+ * @brief The LOGSYS_PERROR macro
+ * @param err_num
+ * @param level
+ * @param fmt
+ * @param args
+ */
+#define LOGSYS_PERROR(err_num, level, fmt, args...) do { \
+ char _error_str[LOGSYS_MAX_PERROR_MSG_LEN]; \
+ const char *_error_ptr = qb_strerror_r(err_num, _error_str, sizeof(_error_str)); \
+ qb_log(level, fmt ": %s (%d)", ##args, _error_ptr, err_num); \
+ } while(0)
+
+#define log_printf(level, format, args...) qb_log(level, format, ##args)
+#define ENTER qb_enter
+#define LEAVE qb_leave
+#define TRACE1(format, args...) qb_log(LOG_TRACE, "TRACE1:" #format, ##args)
+#define TRACE2(format, args...) qb_log(LOG_TRACE, "TRACE2:" #format, ##args)
+#define TRACE3(format, args...) qb_log(LOG_TRACE, "TRACE3:" #format, ##args)
+#define TRACE4(format, args...) qb_log(LOG_TRACE, "TRACE4:" #format, ##args)
+#define TRACE5(format, args...) qb_log(LOG_TRACE, "TRACE5:" #format, ##args)
+#define TRACE6(format, args...) qb_log(LOG_TRACE, "TRACE6:" #format, ##args)
+#define TRACE7(format, args...) qb_log(LOG_TRACE, "TRACE7:" #format, ##args)
+#define TRACE8(format, args...) qb_log(LOG_TRACE, "TRACE8:" #format, ##args)
+
+#endif /* LOGSYS_UTILS_ONLY */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LOGSYS_H_DEFINED */
diff --git a/include/corosync/mar_gen.h b/include/corosync/mar_gen.h
new file mode 100644
index 0000000..7aa7f78
--- /dev/null
+++ b/include/corosync/mar_gen.h
@@ -0,0 +1,307 @@
+/*
+ * Copyright (c) 2006-2011 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Author: Steven Dake (sdake@redhat.com)
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of the MontaVista Software, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef MAR_GEN_H_DEFINED
+#define MAR_GEN_H_DEFINED
+
+#include <stdint.h>
+#include <string.h>
+
+#include <corosync/corotypes.h>
+#include <corosync/swab.h>
+
+#define MAR_ALIGN_UP(addr,size) (((addr)+((size)-1))&(~((size)-1)))
+
+typedef int8_t mar_int8_t;
+typedef int16_t mar_int16_t;
+typedef int32_t mar_int32_t;
+typedef int64_t mar_int64_t;
+
+typedef uint8_t mar_uint8_t;
+typedef uint16_t mar_uint16_t;
+typedef uint32_t mar_uint32_t;
+typedef uint64_t mar_uint64_t;
+
+/**
+ * @brief swab_mar_int8_t
+ * @param to_swab
+ */
+static inline void swab_mar_int8_t (mar_int8_t *to_swab)
+{
+ return;
+}
+
+/**
+ * @brief swab_mar_int16_t
+ * @param to_swab
+ */
+static inline void swab_mar_int16_t (mar_int16_t *to_swab)
+{
+ *to_swab = swab16 (*to_swab);
+}
+
+/**
+ * @brief swab_mar_int32_t
+ * @param to_swab
+ */
+static inline void swab_mar_int32_t (mar_int32_t *to_swab)
+{
+ *to_swab = swab32 (*to_swab);
+}
+
+/**
+ * @brief swab_mar_int64_t
+ * @param to_swab
+ */
+static inline void swab_mar_int64_t (mar_int64_t *to_swab)
+{
+ *to_swab = swab64 (*to_swab);
+}
+
+/**
+ * @brief swab_mar_uint8_t
+ * @param to_swab
+ */
+static inline void swab_mar_uint8_t (mar_uint8_t *to_swab)
+{
+ return;
+}
+
+/**
+ * @brief swab_mar_uint16_t
+ * @param to_swab
+ */
+static inline void swab_mar_uint16_t (mar_uint16_t *to_swab)
+{
+ *to_swab = swab16 (*to_swab);
+}
+
+/**
+ * @brief swab_mar_uint32_t
+ * @param to_swab
+ */
+static inline void swab_mar_uint32_t (mar_uint32_t *to_swab)
+{
+ *to_swab = swab32 (*to_swab);
+}
+
+/**
+ * @brief swab_mar_uint64_t
+ * @param to_swab
+ */
+static inline void swab_mar_uint64_t (mar_uint64_t *to_swab)
+{
+ *to_swab = swab64 (*to_swab);
+}
+
+/**
+ * @brief swabbin
+ * @param data
+ * @param len
+ */
+static inline void swabbin(char *data, size_t len)
+{
+ int i;
+ char tmp;
+
+ for (i = 0; i < len / 2; i++) {
+ tmp = data[i];
+ data[i] = data[len - i - 1];
+ data[len - i - 1] = tmp;
+ }
+}
+
+/**
+ * @brief swabflt
+ * @param flt
+ */
+static inline void swabflt(float *flt)
+{
+ swabbin((char *)flt, sizeof(*flt));
+}
+
+/**
+ * @brief swabdbl
+ * @param dbl
+ */
+static inline void swabdbl(double *dbl)
+{
+ swabbin((char *)dbl, sizeof(*dbl));
+}
+
+/**
+ * @brief mar_name_t struct
+ */
+typedef struct {
+ mar_uint16_t length __attribute__((aligned(8)));
+ mar_uint8_t value[CS_MAX_NAME_LENGTH] __attribute__((aligned(8)));
+} mar_name_t;
+
+/**
+ * @brief get_mar_name_t
+ * @param name
+ * @return
+ */
+static inline const char *get_mar_name_t (const mar_name_t *name) {
+ return ((const char *)name->value);
+}
+
+/**
+ * @brief mar_name_match
+ * @param name1
+ * @param name2
+ * @return
+ */
+static inline int mar_name_match(const mar_name_t *name1, const mar_name_t *name2)
+{
+ if (name1->length == name2->length) {
+ return ((strncmp ((const char *)name1->value,
+ (const char *)name2->value,
+ name1->length)) == 0);
+ }
+ return 0;
+}
+
+/**
+ * @brief swab_mar_name_t
+ * @param to_swab
+ */
+static inline void swab_mar_name_t (mar_name_t *to_swab)
+{
+ swab_mar_uint16_t (&to_swab->length);
+}
+
+/**
+ * @brief marshall_from_mar_name_t
+ * @param dest
+ * @param src
+ */
+static inline void marshall_from_mar_name_t (
+ cs_name_t *dest,
+ const mar_name_t *src)
+{
+ dest->length = src->length;
+ memcpy (dest->value, src->value, CS_MAX_NAME_LENGTH);
+}
+
+/**
+ * @brief marshall_to_mar_name_t
+ * @param dest
+ * @param src
+ */
+static inline void marshall_to_mar_name_t (
+ mar_name_t *dest,
+ const cs_name_t *src)
+{
+ dest->length = src->length;
+ memcpy (dest->value, src->value, CS_MAX_NAME_LENGTH);
+}
+
+/**
+ * @brief mar_bool_t enum
+ */
+typedef enum {
+ MAR_FALSE = 0,
+ MAR_TRUE = 1
+} mar_bool_t;
+
+/**
+ * @brief mar_time_t
+ */
+typedef mar_uint64_t mar_time_t;
+
+/**
+ * @brief swab_mar_time_t
+ * @param to_swab
+ */
+static inline void swab_mar_time_t (mar_time_t *to_swab)
+{
+ swab_mar_uint64_t (to_swab);
+}
+
+#define MAR_TIME_END ((int64_t)0x7fffffffffffffffull)
+#define MAR_TIME_BEGIN 0x0ULL
+#define MAR_TIME_UNKNOWN 0x8000000000000000ULL
+
+#define MAR_TIME_ONE_MICROSECOND 1000ULL
+#define MAR_TIME_ONE_MILLISECOND 1000000ULL
+#define MAR_TIME_ONE_SECOND 1000000000ULL
+#define MAR_TIME_ONE_MINUTE 60000000000ULL
+#define MAR_TIME_ONE_HOUR 3600000000000ULL
+#define MAR_TIME_ONE_DAY 86400000000000ULL
+#define MAR_TIME_MAX CS_TIME_END
+
+#define MAR_TRACK_CURRENT 0x01
+#define MAR_TRACK_CHANGES 0x02
+#define MAR_TRACK_CHANGES_ONLY 0x04
+
+/**
+ * @brief mar_invocation_t
+ */
+typedef mar_uint64_t mar_invocation_t;
+
+/**
+ * @brief swab_mar_invocation_t
+ * @param to_swab
+ */
+static inline void swab_mar_invocation_t (mar_invocation_t *to_swab)
+{
+ swab_mar_uint64_t (to_swab);
+}
+
+/**
+ * @brief mar_size_t
+ */
+typedef mar_uint64_t mar_size_t;
+
+/**
+ * @brief swab_mar_size_t
+ * @param to_swab
+ */
+static inline void swab_mar_size_t (mar_size_t *to_swab)
+{
+ swab_mar_uint64_t (to_swab);
+}
+
+/**
+ * @brief swab_coroipc_request_header_t
+ * @param to_swab
+ */
+static inline void swab_coroipc_request_header_t (struct qb_ipc_request_header *to_swab)
+{
+ swab_mar_int32_t (&to_swab->size);
+ swab_mar_int32_t (&to_swab->id);
+}
+
+#endif /* MAR_GEN_H_DEFINED */
diff --git a/include/corosync/quorum.h b/include/corosync/quorum.h
new file mode 100644
index 0000000..93c46be
--- /dev/null
+++ b/include/corosync/quorum.h
@@ -0,0 +1,211 @@
+/*
+ * Copyright (c) 2008-2020 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Author: Christine Caulfield (ccaulfi@redhat.com)
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of the Red Hat, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef COROSYNC_QUORUM_H_DEFINED
+#define COROSYNC_QUORUM_H_DEFINED
+
+#include <corosync/corotypes.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum {
+ QUORUM_MODEL_V0 = 0,
+ QUORUM_MODEL_V1 = 1,
+} quorum_model_t;
+
+/**
+ * @brief quorum_handle_t
+ */
+typedef uint64_t quorum_handle_t;
+
+struct quorum_ring_id {
+ uint32_t nodeid;
+ uint64_t seq;
+};
+
+/**
+ * @brief The quorum_notification_fn_t callback
+ */
+typedef void (*quorum_notification_fn_t) (
+ quorum_handle_t handle,
+ uint32_t quorate,
+ uint64_t ring_seq,
+ uint32_t view_list_entries,
+ uint32_t *view_list
+ );
+
+typedef void (*quorum_v1_quorum_notification_fn_t) (
+ quorum_handle_t handle,
+ uint32_t quorate,
+ struct quorum_ring_id ring_id,
+ uint32_t member_list_entries, const uint32_t *member_list
+);
+
+typedef void (*quorum_v1_nodelist_notification_fn_t) (
+ quorum_handle_t handle,
+ struct quorum_ring_id ring_id,
+ uint32_t member_list_entries, const uint32_t *member_list,
+ uint32_t joined_list_entries, const uint32_t *joined_list,
+ uint32_t left_list_entries, const uint32_t *left_list
+);
+
+/**
+ * @brief The quorum_callbacks_t struct
+ */
+typedef struct {
+ quorum_notification_fn_t quorum_notify_fn;
+} quorum_callbacks_t;
+
+typedef struct {
+ quorum_model_t model;
+} quorum_model_data_t;
+
+typedef struct {
+ quorum_model_t model;
+ quorum_notification_fn_t quorum_notify_fn;
+} quorum_model_v0_data_t;
+
+typedef struct {
+ quorum_model_t model;
+ quorum_v1_quorum_notification_fn_t quorum_notify_fn;
+ quorum_v1_nodelist_notification_fn_t nodelist_notify_fn;
+} quorum_model_v1_data_t;
+
+#define QUORUM_FREE 0
+#define QUORUM_SET 1
+
+/**
+ * @brief Create a new quorum connection
+ * @param handle
+ * @param callbacks
+ * @param quorum_type
+ * @return
+ */
+cs_error_t quorum_initialize (
+ quorum_handle_t *handle,
+ quorum_callbacks_t *callbacks,
+ uint32_t *quorum_type);
+
+cs_error_t quorum_model_initialize (
+ quorum_handle_t *handle,
+ quorum_model_t model,
+ quorum_model_data_t *model_data,
+ uint32_t *quorum_type,
+ void *context);
+
+/**
+ * @brief Close the quorum handle
+ * @param handle
+ * @return
+ */
+cs_error_t quorum_finalize (
+ quorum_handle_t handle);
+
+/**
+ * @brief Get a file descriptor on which to poll.
+ *
+ * @note quorum_handle_t is NOT a file descriptor and may not be used directly.
+ *
+ * @param handle
+ * @param fd
+ * @return
+ */
+cs_error_t quorum_fd_get (
+ quorum_handle_t handle,
+ int *fd);
+
+/**
+ * @brief Dispatch messages and configuration changes
+ * @param handle
+ * @param dispatch_types
+ * @return
+ */
+cs_error_t quorum_dispatch (
+ quorum_handle_t handle,
+ cs_dispatch_flags_t dispatch_types);
+
+/**
+ * @brief Get quorum information.
+ * @param handle
+ * @param quorate
+ * @return
+ */
+cs_error_t quorum_getquorate (
+ quorum_handle_t handle,
+ int *quorate);
+
+/**
+ * @brief Track node and quorum changes
+ * @param handle
+ * @param flags
+ * @return
+ */
+cs_error_t quorum_trackstart (
+ quorum_handle_t handle,
+ unsigned int flags );
+
+/**
+ * @brief quorum_trackstop
+ * @param handle
+ * @return
+ */
+cs_error_t quorum_trackstop (
+ quorum_handle_t handle);
+
+/**
+ * @brief quorum_context_set
+ * @param handle
+ * @param context
+ * @return
+ */
+cs_error_t quorum_context_set (
+ quorum_handle_t handle,
+ const void *context);
+
+/**
+ * @brief quorum_context_get
+ * @param handle
+ * @param context
+ * @return
+ */
+cs_error_t quorum_context_get (
+ quorum_handle_t handle,
+ const void **context);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* COROSYNC_QUORUM_H_DEFINED */
diff --git a/include/corosync/sam.h b/include/corosync/sam.h
new file mode 100644
index 0000000..01f5a2f
--- /dev/null
+++ b/include/corosync/sam.h
@@ -0,0 +1,250 @@
+/*
+ * Copyright (c) 2009-2011 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Author: Jan Friesse (jfriesse@redhat.com)
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of the Red Hat, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef COROSYNC_SAM_H_DEFINED
+#define COROSYNC_SAM_H_DEFINED
+
+#include <corosync/corotypes.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief sam_recovery_policy_t enum
+ */
+typedef enum {
+ SAM_RECOVERY_POLICY_QUIT = 1,
+ SAM_RECOVERY_POLICY_RESTART = 2,
+ SAM_RECOVERY_POLICY_QUORUM = 0x08,
+ SAM_RECOVERY_POLICY_QUORUM_QUIT = SAM_RECOVERY_POLICY_QUORUM | SAM_RECOVERY_POLICY_QUIT,
+ SAM_RECOVERY_POLICY_QUORUM_RESTART = SAM_RECOVERY_POLICY_QUORUM | SAM_RECOVERY_POLICY_RESTART,
+ SAM_RECOVERY_POLICY_CMAP = 0x10,
+ SAM_RECOVERY_POLICY_CONFDB = 0x10,
+} sam_recovery_policy_t;
+
+/**
+ * @brief Callback definition for event driven checking
+ */
+typedef int (*sam_hc_callback_t)(void);
+
+/**
+ * @brief Create a new SAM connection.
+ *
+ * This function must be called before any other.
+ * It is recommended to call it as one of first in application.
+ *
+ * @param time_interval Time interval in milliseconds of healthcheck. After this time, application
+ * will be killed and recovery policy will be taken. This can be zero, which means,
+ * that there is no time limit (only fall of application is checked and only then
+ * recovery action is taken)
+ * @param recovery_policy One of SAM_RECOVERY_POLICY_RESTART, which means, that after
+ * timeout application will be killed and new instance will be started.
+ * SAM_RECOVERY_POLICY_QUIT will just stop application
+ *
+ * @retval CS_OK in case no problem appeared
+ * @retval CS_ERR_BAD_HANDLE in case user is trying to initialize initialized instance
+ * @retval CS_ERR_INVALID_PARAM in case recovery_policy had bad value
+ */
+cs_error_t sam_initialize (
+ int time_interval,
+ sam_recovery_policy_t recovery_policy);
+
+/**
+ * @brief Close the SAM handle.
+ *
+ * This function should be called as late as possible.
+ * (in reality, if you plan just quit, and checking is stopped, there is no need
+ * to call it). Function will stop healtchecking and put library to state, where
+ * no new start is possible.
+ *
+ * @retval CS_OK in case no problem appeared
+ * @retval CS_ERR_BAD_HANDLE library was not initialized by #sam_initialize
+ */
+cs_error_t sam_finalize (void);
+
+/**
+ * @brief Start healthchecking.
+ *
+ * From this time, you should call every time_interval
+ * sam_hc_send, otherwise, recovery action will be taken.
+ *
+ * @retval CS_OK in case no problem appeared
+ * @retval CS_ERR_BAD_HANDLE component was not registered by #sam_register
+ */
+cs_error_t sam_start (void);
+
+/**
+ * @brief Stop healthchecking.
+ *
+ * Oposite of #sam_start. You can call sam_start and sam_stop how many
+ * times you want.
+ *
+ * @retval CS_OK in case no problem appeared
+ * @retval CS_ERR_BAD_HANDLE healthchecking is not in running state (no sam_start
+ * was called)
+ */
+cs_error_t sam_stop (void);
+
+/**
+ * @brief Set warning signal to be sent.
+ *
+ * Default signal is SIGTERM. You can use SIGKILL to emulate NOT sending
+ * warning signal and just send SIGKILL.
+ *
+ * @retval CS_OK in case no problem appeared
+ * @retval CS_ERR_BAD_HANDLE library was not initialized by #sam_initialize or
+ * is finalized
+ */
+cs_error_t sam_warn_signal_set (int warn_signal);
+
+/**
+ * @brief Register application.
+ *
+ * This is one of most crucial function. In case, your
+ * application will be restarted, you will always return to point after calling
+ * this function. This function can be called only once, and SAM must be initialized
+ * by sam_initialize. You can choose any place in your application, where to call
+ * this function.
+ *
+ * @param instance_id NULL or pointer to int memory, where current instance
+ * of application will be returned. It's always safe to suppose, that first instance
+ * (this means, no recovery action was taken yet) will be always 1 and instance_id
+ * will be raising up to MAX_INT (after this, it will fall to 0).
+ *
+ * @retval CS_OK in case no problem appeared
+ * @retval CS_ERR_BAD_HANDLE in case, you call this function twice, or before sam_init
+ * @retval CS_ERR_LIBRARY internal library call failed. This can be one of pipe or fork
+ * creation. You can get more information from errno
+ */
+cs_error_t sam_register (
+ unsigned int *instance_id);
+
+/**
+ * @brief Send healthcheck confirmation.
+ *
+ * This should be called after #sam_start
+ *
+ * @retval CS_OK in case no problem appeared
+ * @retval CS_ERR_BAD_HANDLE healthchecking is not in running state (no sam_start was
+ * called, or called after sam_stop/sam_finalize)
+ */
+cs_error_t sam_hc_send (void);
+
+/**
+ * @brief Register healtcheck callback.
+ *
+ * After you will call this function, and set
+ * cb to something else then NULL, SAM is automatically switched from
+ * application driven healtchecking to event driven healtchecking. In other
+ * words, is not longer needed to call sam_hc_send, but your callback function
+ * must return 0 in case of healtchecking is correct, or value different then
+ * 0, in case something happend. After next hc iteration, warning signal and
+ * after that kill signal is sent back to your application.
+ *
+ * @param cb Pointer to healtcheck function, or NULL to switch back to application driven hc
+ *
+ * @retval CS_OK in case no problem appeared
+ * @retval CS_ERR_BAD_HANDLE in case, you call this function before sam_init or after sam_start
+ * @retval CS_ERR_LIBRARY internal library call failed. This can be one of pipe or pthread
+ * creation.
+ */
+cs_error_t sam_hc_callback_register (sam_hc_callback_t cb);
+
+/**
+ * @brief Return size of stored data.
+ *
+ * @param size Pointer to variable, where stored data size is returned. If
+ * nothing or NULL is stored, then 0 is returned.
+ *
+ * @retval CS_OK in case no problem appeared
+ * @retval CS_ERR_BAD_HANDLE in case you call this function before sam_init or after
+ * sam_finalize
+ * @retval CS_ERR_INVALID_PARAM if size parameter is NULL
+ */
+cs_error_t sam_data_getsize (size_t *size);
+
+/**
+ * @brief Return stored data.
+ *
+ * @param data Pointer to place, where to store data
+ * @param size Allocated size of data
+ *
+ * @retval CS_OK if no problem appeared
+ * @retval CS_ERR_BAD_HANDLE if you call this function before sam_init or after sam_finalize
+ * @retval CS_ERR_INVALID_PARAM if data is NULL or size is less then currently saved user data length
+ */
+cs_error_t sam_data_restore (
+ void *data,
+ size_t size);
+
+/**
+ * @brief Store user data.
+ *
+ * Such stored data survives restart of child.
+ *
+ * @param data Data to store. You can use NULL to delete data
+ * @param size Size of data to store.
+ *
+ * @retval CS_OK in case no problem appeared
+ * @retval CS_ERR_BAD_HANDLE if you call this function before sam_init or
+ * after sam_finalize
+ * @retval CS_ERR_NO_MEMORY if data is too large and malloc/realloc was not
+ * succesfull
+ * @retval CS_ERR_LIBRARY if some internal error appeared (communication with parent
+ * process)
+ */
+cs_error_t sam_data_store (
+ const void *data,
+ size_t size);
+
+/**
+ * @brief Marks child as failed.
+ *
+ * This can be called only with SAM_RECOVERY_POLICY_CMAP flag set and
+ * makes sense only for SAM_RECOVERY_POLICY_RESTART. This will kill child without sending warning
+ * signal. Cmap state key will be set to failed.
+ *
+ * @retval CS_OK in case no problem appeared
+ * @retval CS_ERR_BAD_HANDLE library was not initialized or was already finalized
+ * @retval CS_ERR_INVALID_PARAM recovery policy doesn't have SAM_RECOVERY_POLICY_CMAP flag set
+ * @retval CS_ERR_LIBRARY if some internal error appeared (communication with parent
+ * process)
+ */
+cs_error_t sam_mark_failed (void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* COROSYNC_SAM_H_DEFINED */
diff --git a/include/corosync/sq.h b/include/corosync/sq.h
new file mode 100644
index 0000000..39345d5
--- /dev/null
+++ b/include/corosync/sq.h
@@ -0,0 +1,404 @@
+/*
+ * Copyright (c) 2003-2004 MontaVista Software, Inc.
+ *
+ * All rights reserved.
+ *
+ * Author: Steven Dake (sdake@redhat.com)
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of the MontaVista Software, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef SORTQUEUE_H_DEFINED
+#define SORTQUEUE_H_DEFINED
+
+#include <errno.h>
+#include <string.h>
+
+/**
+ * @brief The sq struct
+ */
+struct sq {
+ unsigned int head;
+ unsigned int size;
+ void *items;
+ unsigned int *items_inuse;
+ unsigned int *items_miss_count;
+ unsigned int size_per_item;
+ unsigned int head_seqid;
+ unsigned int item_count;
+ unsigned int pos_max;
+};
+
+/*
+ * Compare a unsigned rollover-safe value to an unsigned rollover-safe value
+ */
+
+/**
+ * ADJUST_ROLLOVER_POINT is the value used to determine when a window should be
+ * used to calculate a less-then or less-then-equal comparison.
+ */
+#define ADJUST_ROLLOVER_POINT 0x80000000
+
+/**
+ * ADJUST_ROLLOVER_VALUE is the value by which both values in a comparison are
+ * adjusted if either value in a comparison is greater then
+ * ADJUST_ROLLOVER_POINT.
+ */
+#define ADJUST_ROLLOVER_VALUE 0x10000
+
+/**
+ * @brief sq_lt_compare
+ * @param a
+ * @param b
+ * @return
+ */
+static inline int sq_lt_compare (unsigned int a, unsigned int b) {
+ if ((a > ADJUST_ROLLOVER_POINT) || (b > ADJUST_ROLLOVER_POINT)) {
+ if ((a - ADJUST_ROLLOVER_VALUE) < (b - ADJUST_ROLLOVER_VALUE)) {
+ return (1);
+ }
+ } else {
+ if (a < b) {
+ return (1);
+ }
+ }
+ return (0);
+}
+
+/**
+ * @brief sq_lte_compare
+ * @param a
+ * @param b
+ * @return
+ */
+static inline int sq_lte_compare (unsigned int a, unsigned int b) {
+ if ((a > ADJUST_ROLLOVER_POINT) || (b > ADJUST_ROLLOVER_POINT)) {
+ if ((a - ADJUST_ROLLOVER_VALUE) <= (b - ADJUST_ROLLOVER_VALUE)) {
+ return (1);
+ }
+ } else {
+ if (a <= b) {
+ return (1);
+ }
+ }
+ return (0);
+}
+
+/**
+ * @brief sq_init
+ * @param sq
+ * @param item_count
+ * @param size_per_item
+ * @param head_seqid
+ * @return
+ */
+static inline int sq_init (
+ struct sq *sq,
+ int item_count,
+ int size_per_item,
+ int head_seqid)
+{
+ sq->head = 0;
+ sq->size = item_count;
+ sq->size_per_item = size_per_item;
+ sq->head_seqid = head_seqid;
+ sq->item_count = item_count;
+ sq->pos_max = 0;
+
+ sq->items = malloc (item_count * size_per_item);
+ if (sq->items == NULL) {
+ return (-ENOMEM);
+ }
+ memset (sq->items, 0, item_count * size_per_item);
+
+ if ((sq->items_inuse = malloc (item_count * sizeof (unsigned int)))
+ == NULL) {
+ return (-ENOMEM);
+ }
+ if ((sq->items_miss_count = malloc (item_count * sizeof (unsigned int)))
+ == NULL) {
+ return (-ENOMEM);
+ }
+ memset (sq->items_inuse, 0, item_count * sizeof (unsigned int));
+ memset (sq->items_miss_count, 0, item_count * sizeof (unsigned int));
+ return (0);
+}
+
+/**
+ * @brief sq_reinit
+ * @param sq
+ * @param head_seqid
+ */
+static inline void sq_reinit (struct sq *sq, unsigned int head_seqid)
+{
+ sq->head = 0;
+ sq->head_seqid = head_seqid;
+ sq->pos_max = 0;
+
+ memset (sq->items, 0, sq->item_count * sq->size_per_item);
+ memset (sq->items_inuse, 0, sq->item_count * sizeof (unsigned int));
+ memset (sq->items_miss_count, 0, sq->item_count * sizeof (unsigned int));
+}
+
+/**
+ * @brief sq_assert
+ * @param sq
+ * @param pos
+ */
+static inline void sq_assert (const struct sq *sq, unsigned int pos)
+{
+ unsigned int i;
+
+// printf ("Instrument[%d] Asserting from %d to %d\n",
+// pos, sq->pos_max, sq->size);
+ for (i = sq->pos_max + 1; i < sq->size; i++) {
+ assert (sq->items_inuse[i] == 0);
+ }
+}
+
+/**
+ * @brief sq_copy
+ * @param sq_dest
+ * @param sq_src
+ */
+static inline void sq_copy (struct sq *sq_dest, const struct sq *sq_src)
+{
+ sq_assert (sq_src, 20);
+ sq_dest->head = sq_src->head;
+ sq_dest->size = sq_src->item_count;
+ sq_dest->size_per_item = sq_src->size_per_item;
+ sq_dest->head_seqid = sq_src->head_seqid;
+ sq_dest->item_count = sq_src->item_count;
+ sq_dest->pos_max = sq_src->pos_max;
+ memcpy (sq_dest->items, sq_src->items,
+ sq_src->item_count * sq_src->size_per_item);
+ memcpy (sq_dest->items_inuse, sq_src->items_inuse,
+ sq_src->item_count * sizeof (unsigned int));
+ memcpy (sq_dest->items_miss_count, sq_src->items_miss_count,
+ sq_src->item_count * sizeof (unsigned int));
+}
+
+/**
+ * @brief sq_free
+ * @param sq
+ */
+static inline void sq_free (struct sq *sq) {
+ free (sq->items);
+ free (sq->items_inuse);
+ free (sq->items_miss_count);
+}
+
+/**
+ * @brief sq_item_add
+ * @param sq
+ * @param item
+ * @param seqid
+ * @return
+ */
+static inline void *sq_item_add (
+ struct sq *sq,
+ void *item,
+ unsigned int seqid)
+{
+ char *sq_item;
+ unsigned int sq_position;
+
+ sq_position = (sq->head + seqid - sq->head_seqid) % sq->size;
+ if (sq_position > sq->pos_max) {
+ sq->pos_max = sq_position;
+ }
+
+ sq_item = sq->items;
+ sq_item += sq_position * sq->size_per_item;
+ assert(sq->items_inuse[sq_position] == 0);
+ memcpy (sq_item, item, sq->size_per_item);
+ if (seqid == 0) {
+ sq->items_inuse[sq_position] = 1;
+ } else {
+ sq->items_inuse[sq_position] = seqid;
+ }
+ sq->items_miss_count[sq_position] = 0;
+
+ return (sq_item);
+}
+
+/**
+ * @brief sq_item_inuse
+ * @param sq
+ * @param seq_id
+ * @return
+ */
+static inline unsigned int sq_item_inuse (
+ const struct sq *sq,
+ unsigned int seq_id) {
+
+ unsigned int sq_position;
+
+ /*
+ * We need to say that the seqid is in use if it shouldn't
+ * be here in the first place.
+ * To keep old messages from being inserted.
+ */
+#ifdef COMPILE_OUT
+ if (seq_id < sq->head_seqid) {
+ fprintf(stderr, "sq_item_inuse: seqid %d, head %d\n",
+ seq_id, sq->head_seqid);
+ return 1;
+ }
+#endif
+ sq_position = (sq->head - sq->head_seqid + seq_id) % sq->size;
+ return (sq->items_inuse[sq_position] != 0);
+}
+
+/**
+ * @brief sq_item_miss_count
+ * @param sq
+ * @param seq_id
+ * @return
+ */
+static inline unsigned int sq_item_miss_count (
+ const struct sq *sq,
+ unsigned int seq_id)
+{
+ unsigned int sq_position;
+
+ sq_position = (sq->head - sq->head_seqid + seq_id) % sq->size;
+ sq->items_miss_count[sq_position]++;
+ return (sq->items_miss_count[sq_position]);
+}
+
+/**
+ * @brief sq_size_get
+ * @param sq
+ * @return
+ */
+static inline unsigned int sq_size_get (
+ const struct sq *sq)
+{
+ return sq->size;
+}
+
+/**
+ * @brief sq_in_range
+ * @param sq
+ * @param seq_id
+ * @return
+ */
+static inline unsigned int sq_in_range (
+ const struct sq *sq,
+ unsigned int seq_id)
+{
+ int res = 1;
+
+ if (sq->head_seqid > ADJUST_ROLLOVER_POINT) {
+ if (seq_id - ADJUST_ROLLOVER_VALUE <
+ sq->head_seqid - ADJUST_ROLLOVER_VALUE) {
+
+ res = 0;
+ }
+ if ((seq_id - ADJUST_ROLLOVER_VALUE) >=
+ ((sq->head_seqid - ADJUST_ROLLOVER_VALUE) + sq->size)) {
+
+ res = 0;
+ }
+ } else {
+ if (seq_id < sq->head_seqid) {
+ res = 0;
+ }
+ if ((seq_id) >= ((sq->head_seqid) + sq->size)) {
+ res = 0;
+ }
+ }
+ return (res);
+
+}
+
+/**
+ * @brief sq_item_get
+ * @param sq
+ * @param seq_id
+ * @param sq_item_out
+ * @return
+ */
+static inline unsigned int sq_item_get (
+ const struct sq *sq,
+ unsigned int seq_id,
+ void **sq_item_out)
+{
+ char *sq_item;
+ unsigned int sq_position;
+
+ if (seq_id > ADJUST_ROLLOVER_POINT) {
+ assert ((seq_id - ADJUST_ROLLOVER_POINT) <
+ ((sq->head_seqid - ADJUST_ROLLOVER_POINT) + sq->size));
+
+ sq_position = ((sq->head - ADJUST_ROLLOVER_VALUE) -
+ (sq->head_seqid - ADJUST_ROLLOVER_VALUE) + seq_id) % sq->size;
+ } else {
+ assert (seq_id < (sq->head_seqid + sq->size));
+ sq_position = (sq->head - sq->head_seqid + seq_id) % sq->size;
+ }
+//printf ("seqid %x head %x head %x pos %x\n", seq_id, sq->head, sq->head_seqid, sq_position);
+// sq_position = (sq->head - sq->head_seqid + seq_id) % sq->size;
+//printf ("sq_position = %x\n", sq_position);
+//printf ("ITEMGET %d %d %d %d\n", sq_position, sq->head, sq->head_seqid, seq_id);
+ if (sq->items_inuse[sq_position] == 0) {
+ return (ENOENT);
+ }
+ sq_item = sq->items;
+ sq_item += sq_position * sq->size_per_item;
+ *sq_item_out = sq_item;
+ return (0);
+}
+
+/**
+ * @brief sq_items_release
+ * @param sq
+ * @param seqid
+ */
+static inline void sq_items_release (struct sq *sq, unsigned int seqid)
+{
+ unsigned int oldhead;
+
+ oldhead = sq->head;
+
+ sq->head = (sq->head + seqid - sq->head_seqid + 1) % sq->size;
+ if ((oldhead + seqid - sq->head_seqid + 1) > sq->size) {
+// printf ("releasing %d for %d\n", oldhead, sq->size - oldhead);
+// printf ("releasing %d for %d\n", 0, sq->head);
+ memset (&sq->items_inuse[oldhead], 0, (sq->size - oldhead) * sizeof (unsigned int));
+ memset (sq->items_inuse, 0, sq->head * sizeof (unsigned int));
+ } else {
+// printf ("releasing %d for %d\n", oldhead, seqid - sq->head_seqid + 1);
+ memset (&sq->items_inuse[oldhead], 0,
+ (seqid - sq->head_seqid + 1) * sizeof (unsigned int));
+ memset (&sq->items_miss_count[oldhead], 0,
+ (seqid - sq->head_seqid + 1) * sizeof (unsigned int));
+ }
+ sq->head_seqid = seqid + 1;
+}
+
+#endif /* SORTQUEUE_H_DEFINED */
diff --git a/include/corosync/swab.h b/include/corosync/swab.h
new file mode 100644
index 0000000..256a82f
--- /dev/null
+++ b/include/corosync/swab.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2005 MontaVista Software, Inc.
+ * Copyright (c) 2006-2008 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of the MontaVista Software, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <sys/types.h>
+
+/**
+ * @brief The swab16 macro
+ * @param x
+ */
+#define swab16(x) \
+({ \
+ uint16_t __x = (x); \
+ ((uint16_t)( \
+ (((uint16_t)(__x) & (uint16_t)0x00ffU) << 8) | \
+ (((uint16_t)(__x) & (uint16_t)0xff00U) >> 8) )); \
+})
+
+/**
+ * @brief The swab32 macro
+ * @param x
+ */
+#define swab32(x) \
+({ \
+ uint32_t __x = (x); \
+ ((uint32_t)( \
+ (((uint32_t)(__x) & (uint32_t)0x000000ffUL) << 24) | \
+ (((uint32_t)(__x) & (uint32_t)0x0000ff00UL) << 8) | \
+ (((uint32_t)(__x) & (uint32_t)0x00ff0000UL) >> 8) | \
+ (((uint32_t)(__x) & (uint32_t)0xff000000UL) >> 24) )); \
+})
+
+/**
+ * @brief The swab64 macro
+ * @param x
+ */
+#define swab64(x) \
+({ \
+ uint64_t __x = (x); \
+ ((uint64_t)( \
+ (uint64_t)(((uint64_t)(__x) & (uint64_t)0x00000000000000ffULL) << 56) | \
+ (uint64_t)(((uint64_t)(__x) & (uint64_t)0x000000000000ff00ULL) << 40) | \
+ (uint64_t)(((uint64_t)(__x) & (uint64_t)0x0000000000ff0000ULL) << 24) | \
+ (uint64_t)(((uint64_t)(__x) & (uint64_t)0x00000000ff000000ULL) << 8) | \
+ (uint64_t)(((uint64_t)(__x) & (uint64_t)0x000000ff00000000ULL) >> 8) | \
+ (uint64_t)(((uint64_t)(__x) & (uint64_t)0x0000ff0000000000ULL) >> 24) | \
+ (uint64_t)(((uint64_t)(__x) & (uint64_t)0x00ff000000000000ULL) >> 40) | \
+ (uint64_t)(((uint64_t)(__x) & (uint64_t)0xff00000000000000ULL) >> 56) )); \
+})
diff --git a/include/corosync/totem/totem.h b/include/corosync/totem/totem.h
new file mode 100644
index 0000000..3268888
--- /dev/null
+++ b/include/corosync/totem/totem.h
@@ -0,0 +1,295 @@
+/*
+ * Copyright (c) 2005 MontaVista Software, Inc.
+ * Copyright (c) 2006-2022 Red Hat, Inc.
+ *
+ * Author: Steven Dake (sdake@redhat.com)
+ *
+ * All rights reserved.
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of the MontaVista Software, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef TOTEM_H_DEFINED
+#define TOTEM_H_DEFINED
+#include "totemip.h"
+#include <libknet.h>
+#include <corosync/hdb.h>
+#include <corosync/totem/totemstats.h>
+
+#ifdef HAVE_SMALL_MEMORY_FOOTPRINT
+#define PROCESSOR_COUNT_MAX 16
+#define MESSAGE_SIZE_MAX 1024*64
+#define MESSAGE_QUEUE_MAX 512
+#else
+#define PROCESSOR_COUNT_MAX 384
+#define MESSAGE_SIZE_MAX 1024*1024 /* (1MB) */
+#define MESSAGE_QUEUE_MAX ((4 * MESSAGE_SIZE_MAX) / totem_config->net_mtu)
+#endif /* HAVE_SMALL_MEMORY_FOOTPRINT */
+
+#define FRAME_SIZE_MAX KNET_MAX_PACKET_SIZE
+
+#define CONFIG_STRING_LEN_MAX 128
+/*
+ * Estimation of required buffer size for totemudp and totemudpu - it should be at least
+ * sizeof(memb_join) + PROCESSOR_MAX * 2 * sizeof(srp_addr))
+ * if we want to support PROCESSOR_MAX nodes, but because we don't have
+ * srp_addr and memb_join, we have to use estimation.
+ * TODO: Consider moving srp_addr/memb_join into totem headers instead of totemsrp.c
+ */
+#define UDP_RECEIVE_FRAME_SIZE_MAX (PROCESSOR_COUNT_MAX * (INTERFACE_MAX * 2 * sizeof(struct totem_ip_address)) + 1024)
+
+#define TRANSMITS_ALLOWED 16
+#define SEND_THREADS_MAX 16
+
+/* This must be <= KNET_MAX_LINK */
+#define INTERFACE_MAX 8
+
+#define BIND_MAX_RETRIES 10
+#define BIND_RETRIES_INTERVAL 100
+
+/**
+ * Maximum number of continuous gather states
+ */
+#define MAX_NO_CONT_GATHER 3
+/*
+ * Maximum number of continuous failures get from sendmsg call
+ */
+#define MAX_NO_CONT_SENDMSG_FAILURES 30
+
+struct totem_interface {
+ struct totem_ip_address bindnet;
+ struct totem_ip_address boundto;
+ struct totem_ip_address mcast_addr;
+ struct totem_ip_address local_ip;
+ uint16_t ip_port;
+ uint16_t ttl;
+ uint8_t configured;
+ int member_count;
+ int knet_link_priority;
+ int knet_ping_interval;
+ int knet_ping_timeout;
+ int knet_ping_precision;
+ int knet_pong_count;
+ int knet_transport;
+ struct totem_ip_address member_list[PROCESSOR_COUNT_MAX];
+};
+
+struct totem_logging_configuration {
+ void (*log_printf) (
+ int level,
+ int subsys,
+ const char *function_name,
+ const char *file_name,
+ int file_line,
+ const char *format,
+ ...) __attribute__((format(printf, 6, 7)));
+
+ int log_level_security;
+ int log_level_error;
+ int log_level_warning;
+ int log_level_notice;
+ int log_level_debug;
+ int log_level_trace;
+ int log_subsys_id;
+};
+
+
+/*
+ * COrosync TOtem. Also used as an endian_detector.
+ */
+#define TOTEM_MH_MAGIC 0xC070
+#define TOTEM_MH_VERSION 0x03
+
+struct totem_message_header {
+ unsigned short magic;
+ char version;
+ char type;
+ char encapsulated;
+ unsigned int nodeid;
+ unsigned int target_nodeid;
+} __attribute__((packed));
+
+enum {
+ TOTEM_PRIVATE_KEY_LEN_MIN = KNET_MIN_KEY_LEN,
+ TOTEM_PRIVATE_KEY_LEN_MAX = KNET_MAX_KEY_LEN
+};
+
+enum { TOTEM_LINK_MODE_BYTES = 64 };
+
+typedef enum {
+ TOTEM_TRANSPORT_UDP = 0,
+ TOTEM_TRANSPORT_UDPU = 1,
+ TOTEM_TRANSPORT_KNET = 2
+} totem_transport_t;
+
+#define MEMB_RING_ID
+struct memb_ring_id {
+ unsigned int rep;
+ unsigned long long seq;
+} __attribute__((packed));
+
+typedef enum {
+ CRYPTO_RECONFIG_PHASE_ACTIVATE = 1,
+ CRYPTO_RECONFIG_PHASE_CLEANUP = 2,
+} cfg_message_crypto_reconfig_phase_t;
+
+struct totem_config {
+ int version;
+
+ /*
+ * network
+ */
+ struct totem_interface *interfaces;
+ struct totem_interface *orig_interfaces; /* for reload */
+ unsigned int node_id;
+ unsigned int clear_node_high_bit;
+ unsigned int knet_pmtud_interval;
+ unsigned int knet_mtu;
+
+ /*
+ * key information
+ */
+ unsigned char private_key[TOTEM_PRIVATE_KEY_LEN_MAX];
+
+ unsigned int private_key_len;
+
+ /*
+ * Totem configuration parameters
+ */
+ unsigned int token_timeout;
+
+ unsigned int token_warning;
+
+ unsigned int token_retransmit_timeout;
+
+ unsigned int token_hold_timeout;
+
+ unsigned int token_retransmits_before_loss_const;
+
+ unsigned int join_timeout;
+
+ unsigned int send_join_timeout;
+
+ unsigned int consensus_timeout;
+
+ unsigned int merge_timeout;
+
+ unsigned int downcheck_timeout;
+
+ unsigned int fail_to_recv_const;
+
+ unsigned int seqno_unchanged_const;
+
+ char link_mode[TOTEM_LINK_MODE_BYTES];
+
+ struct totem_logging_configuration totem_logging_configuration;
+
+ unsigned int net_mtu;
+
+ unsigned int threads;
+
+ unsigned int heartbeat_failures_allowed;
+
+ unsigned int max_network_delay;
+
+ unsigned int window_size;
+
+ unsigned int max_messages;
+
+ unsigned int broadcast_use;
+
+ char crypto_model[CONFIG_STRING_LEN_MAX];
+
+ char crypto_cipher_type[CONFIG_STRING_LEN_MAX];
+
+ char crypto_hash_type[CONFIG_STRING_LEN_MAX];
+
+ int crypto_index; /* Num of crypto config currently loaded into knet ( 1 or 2 ) */
+
+ int crypto_changed; /* Has crypto changed since last time? (it's expensive to reload) */
+
+ char knet_compression_model[CONFIG_STRING_LEN_MAX];
+
+ uint32_t knet_compression_threshold;
+
+ int knet_compression_level;
+
+ totem_transport_t transport_number;
+
+ unsigned int miss_count_const;
+
+ enum totem_ip_version_enum ip_version;
+
+ unsigned int block_unlisted_ips;
+
+ unsigned int cancel_token_hold_on_retransmit;
+
+ void (*totem_memb_ring_id_create_or_load) (
+ struct memb_ring_id *memb_ring_id,
+ unsigned int nodeid);
+
+ void (*totem_memb_ring_id_store) (
+ const struct memb_ring_id *memb_ring_id,
+ unsigned int nodeid);
+};
+
+/*
+ * Node status returned from the API
+ * Usually the same as the cfg version (except for
+ * link_status)
+ */
+#define TOTEM_NODE_STATUS_STRUCTURE_VERSION 1
+struct totem_node_status {
+ uint32_t version; /* Structure version */
+ unsigned int nodeid;
+ uint8_t reachable;
+ uint8_t remote;
+ uint8_t external;
+ uint8_t onwire_min;
+ uint8_t onwire_max;
+ uint8_t onwire_ver;
+ struct knet_link_status link_status[KNET_MAX_LINK];
+};
+
+
+#define TOTEM_CONFIGURATION_TYPE
+enum totem_configuration_type {
+ TOTEM_CONFIGURATION_REGULAR,
+ TOTEM_CONFIGURATION_TRANSITIONAL
+};
+
+#define TOTEM_CALLBACK_TOKEN_TYPE
+enum totem_callback_token_type {
+ TOTEM_CALLBACK_TOKEN_RECEIVED = 1,
+ TOTEM_CALLBACK_TOKEN_SENT = 2
+};
+
+enum totem_event_type {
+ TOTEM_EVENT_DELIVERY_CONGESTED,
+ TOTEM_EVENT_NEW_MSG,
+};
+
+#endif /* TOTEM_H_DEFINED */
diff --git a/include/corosync/totem/totemip.h b/include/corosync/totem/totemip.h
new file mode 100644
index 0000000..842e8e9
--- /dev/null
+++ b/include/corosync/totem/totemip.h
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2005-2019 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Author: Patrick Caulfield (pcaulfie@redhat.com)
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of the MontaVista Software, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* IPv4/6 abstraction */
+
+#ifndef TOTEMIP_H_DEFINED
+#define TOTEMIP_H_DEFINED
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <stdint.h>
+#include <qb/qblist.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef SO_NOSIGPIPE
+#ifndef MSG_NOSIGNAL
+#define MSG_NOSIGNAL 0
+#endif
+void totemip_nosigpipe(int s);
+#else
+#define totemip_nosigpipe(s)
+#endif
+
+#define TOTEMIP_ADDRLEN (sizeof(struct in6_addr))
+
+/* These are the things that get passed around */
+#define TOTEM_IP_ADDRESS
+struct totem_ip_address
+{
+ unsigned int nodeid;
+ unsigned short family;
+ unsigned char addr[TOTEMIP_ADDRLEN];
+} __attribute__((packed));
+
+enum totem_ip_version_enum {
+ TOTEM_IP_VERSION_4, /* Use only AF_INET */
+ TOTEM_IP_VERSION_6, /* Use only AF_INET6 */
+ TOTEM_IP_VERSION_4_6, /* Use AF_UNSPEC and filter result preferring AF_INET */
+ TOTEM_IP_VERSION_6_4 /* Use AF_UNSPEC and filter result preferring AF_INET6 */
+};
+
+struct totem_ip_if_address
+{
+ struct totem_ip_address ip_addr;
+ struct totem_ip_address mask_addr;
+ int interface_up;
+ int interface_num;
+ char *name;
+ struct qb_list_head list;
+};
+
+extern int totemip_equal(const struct totem_ip_address *addr1,
+ const struct totem_ip_address *addr2);
+extern int totemip_sa_equal(const struct totem_ip_address *totem_ip,
+ const struct sockaddr *sa);
+extern int totemip_compare(const void *a, const void *b);
+extern int totemip_is_mcast(struct totem_ip_address *addr);
+extern void totemip_copy(struct totem_ip_address *addr1,
+ const struct totem_ip_address *addr2);
+int totemip_localhost(int family, struct totem_ip_address *localhost);
+extern int totemip_localhost_check(const struct totem_ip_address *addr);
+extern const char *totemip_print(const struct totem_ip_address *addr);
+extern const char *totemip_sa_print(const struct sockaddr *sa);
+extern int totemip_sockaddr_to_totemip_convert(const struct sockaddr_storage *saddr,
+ struct totem_ip_address *ip_addr);
+extern int totemip_totemip_to_sockaddr_convert(struct totem_ip_address *ip_addr,
+ uint16_t port, struct sockaddr_storage *saddr, int *addrlen);
+extern int totemip_parse(struct totem_ip_address *totemip, const char *addr,
+ enum totem_ip_version_enum ip_version);
+extern int totemip_iface_check(struct totem_ip_address *bindnet,
+ struct totem_ip_address *boundto,
+ int *interface_up,
+ int *interface_num,
+ int mask_high_bit);
+
+extern int totemip_getifaddrs(struct qb_list_head *addrs);
+
+extern void totemip_freeifaddrs(struct qb_list_head *addrs);
+
+/* These two simulate a zero in_addr by clearing the family field */
+static inline void totemip_zero_set(struct totem_ip_address *addr)
+{
+ addr->family = 0;
+}
+static inline int totemip_zero_check(const struct totem_ip_address *addr)
+{
+ return (addr->family == 0);
+}
+
+extern size_t totemip_udpip_header_size(int family);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/corosync/totem/totempg.h b/include/corosync/totem/totempg.h
new file mode 100644
index 0000000..d63540c
--- /dev/null
+++ b/include/corosync/totem/totempg.h
@@ -0,0 +1,210 @@
+/*
+ * Copyright (c) 2003-2005 MontaVista Software, Inc.
+ * Copyright (c) 2006-2011 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Author: Steven Dake (sdake@redhat.com)
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of the MontaVista Software, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file
+ * Totem Single Ring Protocol
+ *
+ * depends on poll abstraction, POSIX, IPV4
+ */
+
+#ifndef TOTEMPG_H_DEFINED
+#define TOTEMPG_H_DEFINED
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <sys/types.h>
+#include <netinet/in.h>
+#include "totem.h"
+#include <qb/qbloop.h>
+
+struct totempg_group {
+ const void *group;
+ size_t group_len;
+};
+
+#define TOTEMPG_AGREED 0
+#define TOTEMPG_SAFE 1
+
+/**
+ * Initialize the totem process groups abstraction
+ */
+extern int totempg_initialize (
+ qb_loop_t* poll_handle,
+ struct totem_config *totem_config
+);
+
+extern void totempg_finalize (void);
+
+extern int totempg_callback_token_create (void **handle_out,
+ enum totem_callback_token_type type,
+ int delete,
+ int (*callback_fn) (enum totem_callback_token_type type, const void *),
+ const void *data);
+
+extern void totempg_callback_token_destroy (void *handle);
+
+/**
+ * Initialize a groups instance
+ */
+extern int totempg_groups_initialize (
+ void **instance,
+
+ void (*deliver_fn) (
+ unsigned int nodeid,
+ const void *msg,
+ unsigned int msg_len,
+ int endian_conversion_required),
+
+ void (*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));
+
+extern int totempg_groups_finalize (void *instance);
+
+extern int totempg_groups_join (
+ void *instance,
+ const struct totempg_group *groups,
+ size_t group_cnt);
+
+extern int totempg_groups_leave (
+ void *instance,
+ const struct totempg_group *groups,
+ size_t group_cnt);
+
+extern int totempg_groups_mcast_joined (
+ void *instance,
+ const struct iovec *iovec,
+ unsigned int iov_len,
+ int guarantee);
+
+extern int totempg_groups_joined_reserve (
+ void *instance,
+ const struct iovec *iovec,
+ unsigned int iov_len);
+
+extern int totempg_groups_joined_release (
+ int msg_count);
+
+extern int totempg_groups_mcast_groups (
+ void *instance,
+ int guarantee,
+ const struct totempg_group *groups,
+ size_t groups_cnt,
+ const struct iovec *iovec,
+ unsigned int iov_len);
+
+extern int totempg_groups_send_ok_groups (
+ void *instance,
+ const struct totempg_group *groups,
+ size_t groups_cnt,
+ const struct iovec *iovec,
+ unsigned int iov_len);
+
+extern int totempg_ifaces_get (
+ unsigned int nodeid,
+ unsigned int *interface_id,
+ struct totem_ip_address *interfaces,
+ unsigned int interfaces_size,
+ char ***status,
+ unsigned int *iface_count);
+
+extern int totempg_nodestatus_get (unsigned int nodeid,
+ struct totem_node_status *node_status);
+
+extern void* totempg_get_stats (void);
+
+void totempg_event_signal (enum totem_event_type type, int value);
+
+extern const char *totempg_ifaces_print (unsigned int nodeid);
+
+extern unsigned int totempg_my_nodeid_get (void);
+
+extern int totempg_my_family_get (void);
+
+extern int totempg_crypto_set (const char *cipher_type, const char *hash_type);
+
+extern void totempg_service_ready_register (
+ void (*totem_service_ready) (void));
+
+extern int totempg_iface_set (
+ struct totem_ip_address *interface_addr,
+ unsigned short ip_port,
+ unsigned int iface_no);
+
+extern int totempg_member_add (
+ const struct totem_ip_address *member,
+ int ring_no);
+
+extern int totempg_member_remove (
+ const struct totem_ip_address *member,
+ int ring_no);
+
+enum totem_q_level {
+ TOTEM_Q_LEVEL_LOW,
+ TOTEM_Q_LEVEL_GOOD,
+ TOTEM_Q_LEVEL_HIGH,
+ TOTEM_Q_LEVEL_CRITICAL
+};
+
+void totempg_check_q_level(void *instance);
+
+typedef void (*totem_queue_level_changed_fn) (enum totem_q_level level);
+extern void totempg_queue_level_register_callback (totem_queue_level_changed_fn);
+
+extern void totempg_threaded_mode_enable (void);
+
+extern void totempg_trans_ack (void);
+
+extern int totempg_reconfigure (void);
+
+extern int totempg_crypto_reconfigure_phase (cfg_message_crypto_reconfig_phase_t phase);
+
+extern void totempg_force_gather (void);
+
+extern void totempg_get_config(struct totem_config *config);
+
+extern void totempg_put_config(struct totem_config *config);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* TOTEMPG_H_DEFINED */
diff --git a/include/corosync/totem/totemstats.h b/include/corosync/totem/totemstats.h
new file mode 100644
index 0000000..51e604c
--- /dev/null
+++ b/include/corosync/totem/totemstats.h
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 2017 Red Hat, Inc.
+ *
+ * Author: Christine Caulfield (ccaulfie@redhat.com)
+ *
+ * All rights reserved.
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of the MontaVista Software, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef TOTEMSTATS_H_DEFINED
+#define TOTEMSTATS_H_DEFINED
+
+typedef struct {
+ int is_dirty;
+ time_t last_updated;
+} totem_stats_header_t;
+
+typedef struct {
+ totem_stats_header_t hdr;
+ uint32_t iface_changes;
+} totemnet_stats_t;
+
+typedef struct {
+ uint32_t rx;
+ uint32_t tx;
+ int backlog_calc;
+} totemsrp_token_stats_t;
+
+typedef struct {
+ totem_stats_header_t hdr;
+ uint64_t orf_token_tx;
+ uint64_t orf_token_rx;
+ uint64_t memb_merge_detect_tx;
+ uint64_t memb_merge_detect_rx;
+ uint64_t memb_join_tx;
+ uint64_t memb_join_rx;
+ uint64_t mcast_tx;
+ uint64_t mcast_retx;
+ uint64_t mcast_rx;
+ uint64_t memb_commit_token_tx;
+ uint64_t memb_commit_token_rx;
+ uint64_t token_hold_cancel_tx;
+ uint64_t token_hold_cancel_rx;
+ uint64_t operational_entered;
+ uint64_t operational_token_lost;
+ uint64_t gather_entered;
+ uint64_t gather_token_lost;
+ uint64_t commit_entered;
+ uint64_t commit_token_lost;
+ uint64_t recovery_entered;
+ uint64_t recovery_token_lost;
+ uint64_t consensus_timeouts;
+ uint64_t rx_msg_dropped;
+ uint32_t continuous_gather;
+ uint32_t continuous_sendmsg_failures;
+ uint64_t time_since_token_last_received; // relative time
+
+ uint8_t firewall_enabled_or_nic_failure;
+ uint32_t mtt_rx_token;
+ uint32_t avg_token_workload;
+ uint32_t avg_backlog_calc;
+
+ int earliest_token;
+ int latest_token;
+#define TOTEM_TOKEN_STATS_MAX 100
+ totemsrp_token_stats_t token[TOTEM_TOKEN_STATS_MAX];
+
+} totemsrp_stats_t;
+
+typedef struct {
+ totem_stats_header_t hdr;
+ totemsrp_stats_t *srp;
+ uint32_t msg_reserved;
+ uint32_t msg_queue_avail;
+} totempg_stats_t;
+
+
+extern int totemknet_link_get_status (
+ knet_node_id_t node, uint8_t link,
+ struct knet_link_status *status);
+
+int totemknet_handle_get_stats (
+ struct knet_handle_stats *stats);
+
+void stats_knet_add_member(knet_node_id_t nodeid, uint8_t link);
+
+void stats_knet_del_member(knet_node_id_t nodeid, uint8_t link);
+
+void stats_knet_add_handle(void);
+
+#define TOTEMPG_STATS_CLEAR_TOTEM 1
+#define TOTEMPG_STATS_CLEAR_TRANSPORT 2
+
+extern void totempg_stats_clear (int flags);
+
+#endif /* TOTEMSTATS_H_DEFINED */
diff --git a/include/corosync/votequorum.h b/include/corosync/votequorum.h
new file mode 100644
index 0000000..7863046
--- /dev/null
+++ b/include/corosync/votequorum.h
@@ -0,0 +1,317 @@
+/*
+ * Copyright (c) 2009-2012 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Authors: Christine Caulfield (ccaulfie@redhat.com)
+ * Fabio M. Di Nitto (fdinitto@redhat.com)
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of the MontaVista Software, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef COROSYNC_VOTEQUORUM_H_DEFINED
+#define COROSYNC_VOTEQUORUM_H_DEFINED
+
+#include <corosync/corotypes.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief votequorum_handle_t
+ */
+typedef uint64_t votequorum_handle_t;
+
+#define VOTEQUORUM_INFO_TWONODE 1
+#define VOTEQUORUM_INFO_QUORATE 2
+#define VOTEQUORUM_INFO_WAIT_FOR_ALL 4
+#define VOTEQUORUM_INFO_LAST_MAN_STANDING 8
+#define VOTEQUORUM_INFO_AUTO_TIE_BREAKER 16
+#define VOTEQUORUM_INFO_ALLOW_DOWNSCALE 32
+#define VOTEQUORUM_INFO_QDEVICE_REGISTERED 64
+#define VOTEQUORUM_INFO_QDEVICE_ALIVE 128
+#define VOTEQUORUM_INFO_QDEVICE_CAST_VOTE 256
+#define VOTEQUORUM_INFO_QDEVICE_MASTER_WINS 512
+
+#define VOTEQUORUM_QDEVICE_NODEID 0
+#define VOTEQUORUM_QDEVICE_MAX_NAME_LEN 255
+#define VOTEQUORUM_QDEVICE_DEFAULT_TIMEOUT 10000
+#define VOTEQUORUM_QDEVICE_DEFAULT_SYNC_TIMEOUT 30000
+
+#define VOTEQUORUM_NODESTATE_MEMBER 1
+#define VOTEQUORUM_NODESTATE_DEAD 2
+#define VOTEQUORUM_NODESTATE_LEAVING 3
+
+/** @} */
+
+/**
+ * @brief The votequorum_info struct
+ */
+struct votequorum_info {
+ unsigned int node_id;
+ unsigned int node_state;
+ unsigned int node_votes;
+ unsigned int node_expected_votes;
+ unsigned int highest_expected;
+ unsigned int total_votes;
+ unsigned int quorum;
+ unsigned int flags;
+ unsigned int qdevice_votes;
+ char qdevice_name[VOTEQUORUM_QDEVICE_MAX_NAME_LEN];
+};
+
+/**
+ * @brief The votequorum_node_t struct
+ */
+typedef struct {
+ uint32_t nodeid;
+ uint32_t state;
+} votequorum_node_t;
+
+/**
+ * @brief The votequorum_ring_id_t struct
+ */
+typedef struct {
+ uint32_t nodeid;
+ uint64_t seq;
+} votequorum_ring_id_t;
+
+/**
+ * @brief The votequorum_quorum_notification_fn_t callback
+ */
+typedef void (*votequorum_quorum_notification_fn_t) (
+ votequorum_handle_t handle,
+ uint64_t context,
+ uint32_t quorate,
+ uint32_t node_list_entries,
+ votequorum_node_t node_list[]);
+
+typedef void (*votequorum_nodelist_notification_fn_t) (
+ votequorum_handle_t handle,
+ uint64_t context,
+ votequorum_ring_id_t ring_id,
+ uint32_t node_list_entries,
+ uint32_t node_list[]);
+
+/**
+ * @brief The votequorum_expectedvotes_notification_fn_t callback
+ */
+typedef void (*votequorum_expectedvotes_notification_fn_t) (
+ votequorum_handle_t handle,
+ uint64_t context,
+ uint32_t expected_votes);
+
+/**
+ * @brief The votequorum_callbacks_t struct
+ */
+typedef struct {
+ votequorum_quorum_notification_fn_t votequorum_quorum_notify_fn;
+ votequorum_expectedvotes_notification_fn_t votequorum_expectedvotes_notify_fn;
+ votequorum_nodelist_notification_fn_t votequorum_nodelist_notify_fn;
+} votequorum_callbacks_t;
+
+/**
+ * @brief Create a new quorum connection
+ * @param handle
+ * @param callbacks
+ * @return
+ */
+cs_error_t votequorum_initialize (
+ votequorum_handle_t *handle,
+ votequorum_callbacks_t *callbacks);
+
+/**
+ * @brief Close the quorum handle
+ * @param handle
+ * @return
+ */
+cs_error_t votequorum_finalize (
+ votequorum_handle_t handle);
+
+/**
+ * @brief Dispatch messages and configuration changes
+ * @param handle
+ * @param dispatch_types
+ * @return
+ */
+cs_error_t votequorum_dispatch (
+ votequorum_handle_t handle,
+ cs_dispatch_flags_t dispatch_types);
+
+/**
+ * @brief Get a file descriptor on which to poll.
+ *
+ * @note votequorum_handle_t is NOT a file descriptor and may not be used directly.
+ *
+ * @param handle
+ * @param fd
+ * @return
+ */
+cs_error_t votequorum_fd_get (
+ votequorum_handle_t handle,
+ int *fd);
+
+/**
+ * @brief Get quorum information.
+ * @param handle
+ * @param nodeid
+ * @param info
+ * @return
+ */
+cs_error_t votequorum_getinfo (
+ votequorum_handle_t handle,
+ unsigned int nodeid,
+ struct votequorum_info *info);
+
+/**
+ * @brief set expected_votes
+ * @param handle
+ * @param expected_votes
+ * @return
+ */
+cs_error_t votequorum_setexpected (
+ votequorum_handle_t handle,
+ unsigned int expected_votes);
+
+/**
+ * @brief set votes for a node
+ * @param handle
+ * @param nodeid
+ * @param votes
+ * @return
+ */
+cs_error_t votequorum_setvotes (
+ votequorum_handle_t handle,
+ unsigned int nodeid,
+ unsigned int votes);
+
+/**
+ * @brief Track node and quorum changes
+ * @param handle
+ * @param context
+ * @param flags
+ * @return
+ */
+cs_error_t votequorum_trackstart (
+ votequorum_handle_t handle,
+ uint64_t context,
+ unsigned int flags);
+
+/**
+ * @brief votequorum_trackstop
+ * @param handle
+ * @return
+ */
+cs_error_t votequorum_trackstop (
+ votequorum_handle_t handle);
+
+/**
+ * @brief Save and retrieve private data/context
+ * @param handle
+ * @param context
+ * @return
+ */
+cs_error_t votequorum_context_get (
+ votequorum_handle_t handle,
+ void **context);
+
+/**
+ * @brief votequorum_context_set
+ * @param handle
+ * @param context
+ * @return
+ */
+cs_error_t votequorum_context_set (
+ votequorum_handle_t handle,
+ void *context);
+
+/**
+ * @brief Register a quorum device
+ *
+ * it will be DEAD until polled
+ *
+ * @param handle
+ * @param name
+ * @return
+ */
+cs_error_t votequorum_qdevice_register (
+ votequorum_handle_t handle,
+ const char *name);
+
+/**
+ * @brief Unregister a quorum device
+ * @param handle
+ * @param name
+ * @return
+ */
+cs_error_t votequorum_qdevice_unregister (
+ votequorum_handle_t handle,
+ const char *name);
+
+/**
+ * @brief Update registered name of a quorum device
+ * @param handle
+ * @param oldname
+ * @param newname
+ * @return
+ */
+cs_error_t votequorum_qdevice_update (
+ votequorum_handle_t handle,
+ const char *oldname,
+ const char *newname);
+
+/**
+ * @brief Poll a quorum device
+ * @param handle
+ * @param name
+ * @param cast_vote
+ * @param ring_id
+ * @return
+ */
+cs_error_t votequorum_qdevice_poll (
+ votequorum_handle_t handle,
+ const char *name,
+ unsigned int cast_vote,
+ votequorum_ring_id_t ring_id);
+
+/**
+ * @brief Allow qdevice to tell votequorum if master_wins can be enabled or not
+ * @param handle
+ * @param name
+ * @param allow
+ * @return
+ */
+cs_error_t votequorum_qdevice_master_wins (
+ votequorum_handle_t handle,
+ const char *name,
+ unsigned int allow);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* COROSYNC_VOTEQUORUM_H_DEFINED */
diff --git a/init/Makefile.am b/init/Makefile.am
new file mode 100644
index 0000000..4219995
--- /dev/null
+++ b/init/Makefile.am
@@ -0,0 +1,65 @@
+# Copyright (c) 2004 MontaVista Software, Inc.
+# Copyright (c) 2009 Red Hat, Inc.
+#
+# Authors: Steven Dake (sdake@redhat.com)
+# Fabio M. Di Nitto (fdinitto@redhat.com)
+#
+# All rights reserved.
+#
+# This software licensed under BSD license, the text of which follows:
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# - Redistributions of source code must retain the above copyright notice,
+# this list of conditions and the following disclaimer.
+# - Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+# - Neither the name of the MontaVista Software, Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from this
+# software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+# THE POSSIBILITY OF SUCH DAMAGE.
+
+MAINTAINERCLEANFILES = Makefile.in
+
+EXTRA_DIST = corosync.in corosync-notifyd.in corosync.service.in \
+ corosync-notifyd.service.in \
+ corosync.sysconfig.example
+
+if INSTALL_SYSTEMD
+systemdconfdir = $(SYSTEMDDIR)
+systemdconf_DATA = corosync.service corosync-notifyd.service
+else
+initscriptdir = $(INITDDIR)
+initscript_SCRIPTS = corosync corosync-notifyd
+endif
+
+%: %.in Makefile
+ rm -f $@-t $@
+ cat $< | $(SED) \
+ -e 's#@''SBINDIR@#$(sbindir)#g' \
+ -e 's#@''BINDIR@#$(bindir)#g' \
+ -e 's#@''SYSCONFDIR@#$(sysconfdir)#g' \
+ -e 's#@''INITCONFIGDIR@#$(INITCONFIGDIR)#g' \
+ -e 's#@''INITDDIR@#$(INITDDIR)#g' \
+ -e 's#@''LOCALSTATEDIR@#$(localstatedir)#g' \
+ -e 's#@''BASHPATH@#${BASHPATH}#g' \
+ > $@-t
+ mv $@-t $@
+
+all-local: $(initscript_SCRIPTS) $(systemdconf_DATA)
+
+clean-local:
+ rm -rf $(initscript_SCRIPTS) $(systemdconf_DATA)
diff --git a/init/Makefile.in b/init/Makefile.in
new file mode 100644
index 0000000..69f5800
--- /dev/null
+++ b/init/Makefile.in
@@ -0,0 +1,635 @@
+# Makefile.in generated by automake 1.13.4 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+# Copyright (c) 2004 MontaVista Software, Inc.
+# Copyright (c) 2009 Red Hat, Inc.
+#
+# Authors: Steven Dake (sdake@redhat.com)
+# Fabio M. Di Nitto (fdinitto@redhat.com)
+#
+# All rights reserved.
+#
+# This software licensed under BSD license, the text of which follows:
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# - Redistributions of source code must retain the above copyright notice,
+# this list of conditions and the following disclaimer.
+# - Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+# - Neither the name of the MontaVista Software, Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from this
+# software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+# THE POSSIBILITY OF SUCH DAMAGE.
+
+
+VPATH = @srcdir@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = init
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/lib/libcfg.verso $(top_srcdir)/lib/libcpg.verso \
+ $(top_srcdir)/lib/libquorum.verso \
+ $(top_srcdir)/lib/libsam.verso \
+ $(top_srcdir)/lib/libvotequorum.verso \
+ $(top_srcdir)/lib/libcmap.verso $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/include/corosync/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+am__installdirs = "$(DESTDIR)$(initscriptdir)" \
+ "$(DESTDIR)$(systemdconfdir)"
+SCRIPTS = $(initscript_SCRIPTS)
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+SOURCES =
+DIST_SOURCES =
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+DATA = $(systemdconf_DATA)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALLOCA = @ALLOCA@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUGTOOL = @AUGTOOL@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BASHPATH = @BASHPATH@
+BINDGEN = @BINDGEN@
+CARGO = @CARGO@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFG_SONAME = @CFG_SONAME@
+CFLAGS = @CFLAGS@
+CLIPPY = @CLIPPY@
+CMAP_SONAME = @CMAP_SONAME@
+COROSYSCONFDIR = @COROSYSCONFDIR@
+CPG_SONAME = @CPG_SONAME@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DBUS_CFLAGS = @DBUS_CFLAGS@
+DBUS_LIBS = @DBUS_LIBS@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DOT = @DOT@
+DOXYGEN = @DOXYGEN@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GREP = @GREP@
+GROFF = @GROFF@
+INITCONFIGDIR = @INITCONFIGDIR@
+INITDDIR = @INITDDIR@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBQB_CFLAGS = @LIBQB_CFLAGS@
+LIBQB_LIBS = @LIBQB_LIBS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LINT_FLAGS = @LINT_FLAGS@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LOGDIR = @LOGDIR@
+LOGROTATEDIR = @LOGROTATEDIR@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+QUORUM_SONAME = @QUORUM_SONAME@
+RANLIB = @RANLIB@
+RUSTC = @RUSTC@
+RUSTDOC = @RUSTDOC@
+RUSTFMT = @RUSTFMT@
+RUST_FLAGS = @RUST_FLAGS@
+RUST_TARGET_DIR = @RUST_TARGET_DIR@
+SAM_SONAME = @SAM_SONAME@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SNMPCONFIG = @SNMPCONFIG@
+SNMP_LIBS = @SNMP_LIBS@
+SOMAJOR = @SOMAJOR@
+SOMICRO = @SOMICRO@
+SOMINOR = @SOMINOR@
+SONAME = @SONAME@
+STRIP = @STRIP@
+SYSTEMDDIR = @SYSTEMDDIR@
+VERSCRIPT_LDFLAGS = @VERSCRIPT_LDFLAGS@
+VERSION = @VERSION@
+VOTEQUORUM_SONAME = @VOTEQUORUM_SONAME@
+WITH_LIST = @WITH_LIST@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+corosyncrustver = @corosyncrustver@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+knet_CFLAGS = @knet_CFLAGS@
+knet_LIBS = @knet_LIBS@
+libdir = @libdir@
+libexecdir = @libexecdir@
+libsystemd_CFLAGS = @libsystemd_CFLAGS@
+libsystemd_LIBS = @libsystemd_LIBS@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+nozzle_CFLAGS = @nozzle_CFLAGS@
+nozzle_LIBS = @nozzle_LIBS@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+statgrab_CFLAGS = @statgrab_CFLAGS@
+statgrab_LIBS = @statgrab_LIBS@
+statgrabge090_CFLAGS = @statgrabge090_CFLAGS@
+statgrabge090_LIBS = @statgrabge090_LIBS@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+MAINTAINERCLEANFILES = Makefile.in
+EXTRA_DIST = corosync.in corosync-notifyd.in corosync.service.in \
+ corosync-notifyd.service.in \
+ corosync.sysconfig.example
+
+@INSTALL_SYSTEMD_TRUE@systemdconfdir = $(SYSTEMDDIR)
+@INSTALL_SYSTEMD_TRUE@systemdconf_DATA = corosync.service corosync-notifyd.service
+@INSTALL_SYSTEMD_FALSE@initscriptdir = $(INITDDIR)
+@INSTALL_SYSTEMD_FALSE@initscript_SCRIPTS = corosync corosync-notifyd
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign init/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign init/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+install-initscriptSCRIPTS: $(initscript_SCRIPTS)
+ @$(NORMAL_INSTALL)
+ @list='$(initscript_SCRIPTS)'; test -n "$(initscriptdir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(initscriptdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(initscriptdir)" || exit 1; \
+ fi; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ if test -f "$$d$$p"; then echo "$$d$$p"; echo "$$p"; else :; fi; \
+ done | \
+ sed -e 'p;s,.*/,,;n' \
+ -e 'h;s|.*|.|' \
+ -e 'p;x;s,.*/,,;$(transform)' | sed 'N;N;N;s,\n, ,g' | \
+ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1; } \
+ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
+ if ($$2 == $$4) { files[d] = files[d] " " $$1; \
+ if (++n[d] == $(am__install_max)) { \
+ print "f", d, files[d]; n[d] = 0; files[d] = "" } } \
+ else { print "f", d "/" $$4, $$1 } } \
+ END { for (d in files) print "f", d, files[d] }' | \
+ while read type dir files; do \
+ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
+ test -z "$$files" || { \
+ echo " $(INSTALL_SCRIPT) $$files '$(DESTDIR)$(initscriptdir)$$dir'"; \
+ $(INSTALL_SCRIPT) $$files "$(DESTDIR)$(initscriptdir)$$dir" || exit $$?; \
+ } \
+ ; done
+
+uninstall-initscriptSCRIPTS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(initscript_SCRIPTS)'; test -n "$(initscriptdir)" || exit 0; \
+ files=`for p in $$list; do echo "$$p"; done | \
+ sed -e 's,.*/,,;$(transform)'`; \
+ dir='$(DESTDIR)$(initscriptdir)'; $(am__uninstall_files_from_dir)
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+install-systemdconfDATA: $(systemdconf_DATA)
+ @$(NORMAL_INSTALL)
+ @list='$(systemdconf_DATA)'; test -n "$(systemdconfdir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(systemdconfdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(systemdconfdir)" || exit 1; \
+ fi; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(systemdconfdir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(systemdconfdir)" || exit $$?; \
+ done
+
+uninstall-systemdconfDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(systemdconf_DATA)'; test -n "$(systemdconfdir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ dir='$(DESTDIR)$(systemdconfdir)'; $(am__uninstall_files_from_dir)
+tags TAGS:
+
+ctags CTAGS:
+
+cscope cscopelist:
+
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(SCRIPTS) $(DATA) all-local
+installdirs:
+ for dir in "$(DESTDIR)$(initscriptdir)" "$(DESTDIR)$(systemdconfdir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+ -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-local mostlyclean-am
+
+distclean: distclean-am
+ -rm -f Makefile
+distclean-am: clean-am distclean-generic
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-initscriptSCRIPTS install-systemdconfDATA
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-initscriptSCRIPTS uninstall-systemdconfDATA
+
+.MAKE: install-am install-strip
+
+.PHONY: all all-am all-local check check-am clean clean-generic \
+ clean-libtool clean-local cscopelist-am ctags-am distclean \
+ distclean-generic distclean-libtool distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-dvi install-dvi-am install-exec \
+ install-exec-am install-html install-html-am install-info \
+ install-info-am install-initscriptSCRIPTS install-man \
+ install-pdf install-pdf-am install-ps install-ps-am \
+ install-strip install-systemdconfDATA installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-generic \
+ mostlyclean-libtool pdf pdf-am ps ps-am tags-am uninstall \
+ uninstall-am uninstall-initscriptSCRIPTS \
+ uninstall-systemdconfDATA
+
+
+%: %.in Makefile
+ rm -f $@-t $@
+ cat $< | $(SED) \
+ -e 's#@''SBINDIR@#$(sbindir)#g' \
+ -e 's#@''BINDIR@#$(bindir)#g' \
+ -e 's#@''SYSCONFDIR@#$(sysconfdir)#g' \
+ -e 's#@''INITCONFIGDIR@#$(INITCONFIGDIR)#g' \
+ -e 's#@''INITDDIR@#$(INITDDIR)#g' \
+ -e 's#@''LOCALSTATEDIR@#$(localstatedir)#g' \
+ -e 's#@''BASHPATH@#${BASHPATH}#g' \
+ > $@-t
+ mv $@-t $@
+
+all-local: $(initscript_SCRIPTS) $(systemdconf_DATA)
+
+clean-local:
+ rm -rf $(initscript_SCRIPTS) $(systemdconf_DATA)
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/init/corosync-notifyd.in b/init/corosync-notifyd.in
new file mode 100755
index 0000000..5f36b9a
--- /dev/null
+++ b/init/corosync-notifyd.in
@@ -0,0 +1,150 @@
+#!@BASHPATH@
+
+# Authors:
+# Angus Salkeld <asalkeld@redhat.com>
+#
+# License: Revised BSD
+
+# chkconfig: - 23 77
+# description: Corosync Dbus and snmp notifier
+# processname: corosync-notifyd
+#
+### BEGIN INIT INFO
+# Provides: corosync-notifyd
+# Required-Start: corosync cman
+# Required-Stop: corosync cman
+# Default-Start:
+# Default-Stop:
+# Short-Description: Starts and stops Corosync Notifier.
+# Description: Starts and stops Corosync Notifier.
+### END INIT INFO
+
+desc="Corosync Notifier"
+prog="corosync-notifyd"
+
+# set secure PATH
+PATH="/sbin:/bin:/usr/sbin:/usr/bin:@SBINDIR@"
+
+success()
+{
+ echo -ne "[ OK ]\r"
+}
+
+failure()
+{
+ echo -ne "[FAILED]\r"
+}
+
+status()
+{
+ pid=$(pidof $1 2>/dev/null)
+ rtrn=$?
+ if [ $rtrn -ne 0 ]; then
+ echo "$1 is stopped"
+ else
+ echo "$1 (pid $pid) is running..."
+ fi
+ return $rtrn
+}
+
+[ -f @INITCONFIGDIR@/$prog ] && . @INITCONFIGDIR@/$prog
+
+case '@INITCONFIGDIR@' in
+ */sysconfig) # rpm based distros
+ [ -f @INITDDIR@/functions ] && . @INITDDIR@/functions
+ [ -z "$LOCK_FILE" ] && LOCK_FILE="@LOCALSTATEDIR@/lock/subsys/$prog";;
+ */default) # deb based distros
+ [ -z "$LOCK_FILE" ] && LOCK_FILE="@LOCALSTATEDIR@/lock/$prog";;
+esac
+
+# The version of __pids_pidof in /etc/init.d/functions calls pidof with -x
+# This means it matches scripts, including this one.
+# Redefine it here so that status (from the same file) works.
+# Otherwise simultaneous calls to stop() will loop forever
+__pids_pidof() {
+ pidof -c -o $$ -o $PPID -o %PPID "$1" || \
+ pidof -c -o $$ -o $PPID -o %PPID "${1##*/}"
+}
+
+start()
+{
+ echo -n "Starting $desc ($prog): "
+
+ # most recent distributions use tmpfs for @LOCALSTATEDIR@/run
+ # to avoid to clean it up on every boot.
+ # they also assume that init scripts will create
+ # required subdirectories for proper operations
+ mkdir -p @LOCALSTATEDIR@/run
+
+ if status $prog > /dev/null 2>&1; then
+ success
+ else
+ $prog $OPTIONS > /dev/null 2>&1
+
+ # give it time to fail
+ sleep 2
+ if status $prog > /dev/null 2>&1; then
+ touch $LOCK_FILE
+ success
+ else
+ failure
+ rtrn=1
+ fi
+ fi
+ echo
+}
+
+stop()
+{
+ ! status $prog > /dev/null 2>&1 && return
+
+ echo -n "Signaling $desc ($prog) to terminate: "
+ kill -TERM "$(pidof $prog)" > /dev/null 2>&1
+ success
+ echo
+
+ echo -n "Waiting for $prog services to unload:"
+ while status $prog > /dev/null 2>&1; do
+ sleep 1
+ echo -n "."
+ done
+
+ rm -f $LOCK_FILE
+ success
+ echo
+}
+
+restart()
+{
+ stop
+ start
+}
+
+rtrn=0
+
+case "$1" in
+start)
+ start
+;;
+restart|reload|force-reload)
+ restart
+;;
+condrestart|try-restart)
+ if status $prog > /dev/null 2>&1; then
+ restart
+ fi
+;;
+status)
+ status $prog
+ rtrn=$?
+;;
+stop)
+ stop
+;;
+*)
+ echo "usage: $0 {start|stop|restart|reload|force-reload|condrestart|try-restart|status}"
+ rtrn=2
+;;
+esac
+
+exit $rtrn
diff --git a/init/corosync-notifyd.service.in b/init/corosync-notifyd.service.in
new file mode 100644
index 0000000..410a683
--- /dev/null
+++ b/init/corosync-notifyd.service.in
@@ -0,0 +1,14 @@
+[Unit]
+Description=Corosync Dbus and snmp notifier
+Documentation=man:corosync-notifyd
+Requires=corosync.service
+After=corosync.service
+
+[Service]
+EnvironmentFile=-@INITCONFIGDIR@/corosync-notifyd
+ExecStart=@SBINDIR@/corosync-notifyd -f $OPTIONS
+Type=notify
+Restart=on-failure
+
+[Install]
+WantedBy=multi-user.target
diff --git a/init/corosync.in b/init/corosync.in
new file mode 100755
index 0000000..30a0683
--- /dev/null
+++ b/init/corosync.in
@@ -0,0 +1,230 @@
+#!@BASHPATH@
+
+# Authors:
+# Andrew Beekhof <abeekhof@redhat.com>
+# Fabio M. Di Nitto <fdinitto@redhat.com>
+#
+# License: Revised BSD
+
+# chkconfig: - 20 80
+# description: Corosync Cluster Engine
+# processname: corosync
+#
+### BEGIN INIT INFO
+# Provides: corosync
+# Required-Start: $network $syslog
+# Required-Stop: $network $syslog
+# Default-Start:
+# Default-Stop:
+# Short-Description: Starts and stops Corosync Cluster Engine.
+# Description: Starts and stops Corosync Cluster Engine.
+### END INIT INFO
+
+desc="Corosync Cluster Engine"
+prog="corosync"
+prog_pid_file="@LOCALSTATEDIR@/run/$prog.pid"
+
+# set secure PATH
+PATH="/sbin:/bin:/usr/sbin:/usr/bin:@SBINDIR@"
+
+success()
+{
+ echo -ne "[ OK ]\r"
+}
+
+failure()
+{
+ echo -ne "[FAILED]\r"
+}
+
+warning()
+{
+ echo -ne "[WARNING]\r"
+}
+
+# pid_var_run pid_file
+# Echo pid from given pid_file.
+# Returns LSB exit code for the 'status' action.
+pid_var_run()
+{
+ local pid_file="$1"
+ local pid
+
+ if [ -f "$pid_file" ]; then
+ [ ! -r "$pid_file" ] && return 4
+ pid=$(cat "$pid_file")
+ [ -z "$pid" ] && return 1
+ [ -n "${pid//[0-9]/}" ] && return 1
+ if kill -n 0 "$pid" 2>/dev/null;then
+ echo "$pid"
+ return 0
+ else
+ return 1
+ fi
+ fi
+
+ return 3
+}
+
+# status [-p pid_file] {program}
+status()
+{
+ local pid_file
+
+ if [ "$1" = "-p" ]; then
+ pid_file=$2
+ shift 2
+ fi
+
+ pid=$(pid_var_run "$pid_file" 2>/dev/null)
+ res=$?
+ if [ $res -ne 0 -a -z "$pid_file" ]; then
+ pid=$(__pids_pidof "$1")
+ [ -n "$pid" ]
+ res=$?
+ fi
+
+ if [ $res -ne 0 ]; then
+ echo "$1 is stopped"
+ else
+ echo "$1 (pid $pid) is running..."
+ fi
+ return $res
+}
+
+[ -f @INITCONFIGDIR@/$prog ] && . @INITCONFIGDIR@/$prog
+
+case '@INITCONFIGDIR@' in
+ */sysconfig) # rpm based distros
+ [ -f @INITDDIR@/functions ] && . @INITDDIR@/functions
+ [ -z "$LOCK_FILE" ] && LOCK_FILE="@LOCALSTATEDIR@/lock/subsys/$prog";;
+ */default) # deb based distros
+ [ -z "$LOCK_FILE" ] && LOCK_FILE="@LOCALSTATEDIR@/lock/$prog";;
+esac
+
+# The version of __pids_pidof in /etc/init.d/functions calls pidof with -x
+# This means it matches scripts, including this one.
+# Redefine it here so that status (from the same file) works.
+# Otherwise simultaneous calls to stop() will loop forever
+__pids_pidof() {
+ pidof -c -o $$ -o $PPID -o %PPID "$1" || \
+ pidof -c -o $$ -o $PPID -o %PPID "${1##*/}"
+}
+
+cluster_disabled_at_boot()
+{
+ if grep -q nocluster /proc/cmdline && \
+ [ "$(tty)" = "/dev/console" ]; then
+ echo -e "not configured to run at boot"
+ failure
+ return 1
+ fi
+ return 0
+}
+
+wait_for_ipc()
+{
+ try=0
+ max_try=$((COROSYNC_INIT_TIMEOUT*2-1))
+ [ "$max_try" -le "0" ] && max_try=120
+
+ while [ "$try" -le "$max_try" ]; do
+ if corosync-cpgtool > /dev/null 2>&1; then
+ return 0
+ fi
+ sleep 0.5
+ try=$((try + 1))
+ done
+
+ return 1
+}
+
+start()
+{
+ echo -n "Starting $desc ($prog): "
+
+ ! cluster_disabled_at_boot && return
+
+ # most recent distributions use tmpfs for @LOCALSTATEDIR@/run
+ # to avoid to clean it up on every boot.
+ # they also assume that init scripts will create
+ # required subdirectories for proper operations
+ mkdir -p @LOCALSTATEDIR@/run
+
+ if status -p "$prog_pid_file" "$prog" > /dev/null 2>&1; then
+ success
+ else
+ $prog $COROSYNC_OPTIONS > /dev/null 2>&1
+
+ if [ "$?" != 0 ] || ! wait_for_ipc; then
+ failure
+ rtrn=1
+ else
+ touch $LOCK_FILE
+ if corosync-cfgtool -s > /dev/null 2>&1; then
+ success
+ else
+ warning
+ fi
+ fi
+ fi
+ echo
+}
+
+stop()
+{
+ ! status -p "$prog_pid_file" "$prog" > /dev/null 2>&1 && return
+
+ echo -n "Signaling $desc ($prog) to terminate: "
+ # Call cfgtool to trigger shutdown callbacks
+ corosync-cfgtool -H --force > /dev/null 2>&1
+ # Send TERM signal (if cfgtool -H failed)
+ kill -TERM "$(pid_var_run $prog_pid_file)" > /dev/null 2>&1
+ success
+ echo
+
+ echo -n "Waiting for $prog services to unload:"
+ while status -p "$prog_pid_file" "$prog" > /dev/null 2>&1; do
+ sleep 1
+ echo -n "."
+ done
+
+ rm -f $LOCK_FILE
+ success
+ echo
+}
+
+restart()
+{
+ stop
+ start
+}
+
+rtrn=0
+
+case "$1" in
+start)
+ start
+;;
+restart|reload|force-reload)
+ restart
+;;
+condrestart|try-restart)
+ if status -p "$prog_pid_file" "$prog" > /dev/null 2>&1; then
+ restart
+ fi
+;;
+status)
+ status -p "$prog_pid_file" "$prog"
+ rtrn=$?
+;;
+stop)
+ stop
+;;
+*)
+ echo "usage: $0 {start|stop|restart|reload|force-reload|condrestart|try-restart|status}"
+ rtrn=2
+;;
+esac
+
+exit $rtrn
diff --git a/init/corosync.service.in b/init/corosync.service.in
new file mode 100644
index 0000000..bd2a48a
--- /dev/null
+++ b/init/corosync.service.in
@@ -0,0 +1,34 @@
+[Unit]
+Description=Corosync Cluster Engine
+Documentation=man:corosync man:corosync.conf man:corosync_overview
+ConditionKernelCommandLine=!nocluster
+Requires=network-online.target
+After=network-online.target
+
+[Service]
+EnvironmentFile=-@INITCONFIGDIR@/corosync
+ExecStart=@SBINDIR@/corosync -f $COROSYNC_OPTIONS
+ExecStop=@SBINDIR@/corosync-cfgtool -H --force
+Type=notify
+
+# In typical systemd deployments, both standard outputs are forwarded to
+# journal (stderr is what's relevant in the pristine corosync configuration),
+# which hazards a message redundancy since the syslog stream usually ends there
+# as well; before editing this line, you may want to check DefaultStandardError
+# in systemd-system.conf(5) and whether /dev/log is a systemd related symlink.
+StandardError=null
+
+# The following config is for corosync with enabled watchdog service.
+#
+# When corosync watchdog service is being enabled and using with
+# pacemaker.service, and if you want to exert the watchdog when a
+# corosync process is terminated abnormally,
+# uncomment the line of the following Restart= and RestartSec=.
+#Restart=on-failure
+# Specify a period longer than soft_margin as RestartSec.
+#RestartSec=70
+# rewrite according to environment.
+#ExecStartPre=/sbin/modprobe softdog
+
+[Install]
+WantedBy=multi-user.target
diff --git a/init/corosync.sysconfig.example b/init/corosync.sysconfig.example
new file mode 100644
index 0000000..b0050e3
--- /dev/null
+++ b/init/corosync.sysconfig.example
@@ -0,0 +1,10 @@
+# Corosync init script configuration file
+
+# COROSYNC_INIT_TIMEOUT specifies number of seconds to wait for corosync
+# initialization (default is one minute).
+COROSYNC_INIT_TIMEOUT=60
+
+# COROSYNC_OPTIONS specifies options passed to corosync command
+# (default is no options).
+# See "man corosync" for detailed descriptions of the options.
+COROSYNC_OPTIONS=""
diff --git a/install-sh b/install-sh
new file mode 100755
index 0000000..377bb86
--- /dev/null
+++ b/install-sh
@@ -0,0 +1,527 @@
+#!/bin/sh
+# install - install a program, script, or datafile
+
+scriptversion=2011-11-20.07; # UTC
+
+# This originates from X11R5 (mit/util/scripts/install.sh), which was
+# later released in X11R6 (xc/config/util/install.sh) with the
+# following copyright and license.
+#
+# Copyright (C) 1994 X Consortium
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to
+# deal in the Software without restriction, including without limitation the
+# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+# sell copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
+# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+# Except as contained in this notice, the name of the X Consortium shall not
+# be used in advertising or otherwise to promote the sale, use or other deal-
+# ings in this Software without prior written authorization from the X Consor-
+# tium.
+#
+#
+# FSF changes to this file are in the public domain.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# 'make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch.
+
+nl='
+'
+IFS=" "" $nl"
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit=${DOITPROG-}
+if test -z "$doit"; then
+ doit_exec=exec
+else
+ doit_exec=$doit
+fi
+
+# Put in absolute file names if you don't have them in your path;
+# or use environment vars.
+
+chgrpprog=${CHGRPPROG-chgrp}
+chmodprog=${CHMODPROG-chmod}
+chownprog=${CHOWNPROG-chown}
+cmpprog=${CMPPROG-cmp}
+cpprog=${CPPROG-cp}
+mkdirprog=${MKDIRPROG-mkdir}
+mvprog=${MVPROG-mv}
+rmprog=${RMPROG-rm}
+stripprog=${STRIPPROG-strip}
+
+posix_glob='?'
+initialize_posix_glob='
+ test "$posix_glob" != "?" || {
+ if (set -f) 2>/dev/null; then
+ posix_glob=
+ else
+ posix_glob=:
+ fi
+ }
+'
+
+posix_mkdir=
+
+# Desired mode of installed file.
+mode=0755
+
+chgrpcmd=
+chmodcmd=$chmodprog
+chowncmd=
+mvcmd=$mvprog
+rmcmd="$rmprog -f"
+stripcmd=
+
+src=
+dst=
+dir_arg=
+dst_arg=
+
+copy_on_change=false
+no_target_directory=
+
+usage="\
+Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
+ or: $0 [OPTION]... SRCFILES... DIRECTORY
+ or: $0 [OPTION]... -t DIRECTORY SRCFILES...
+ or: $0 [OPTION]... -d DIRECTORIES...
+
+In the 1st form, copy SRCFILE to DSTFILE.
+In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
+In the 4th, create DIRECTORIES.
+
+Options:
+ --help display this help and exit.
+ --version display version info and exit.
+
+ -c (ignored)
+ -C install only if different (preserve the last data modification time)
+ -d create directories instead of installing files.
+ -g GROUP $chgrpprog installed files to GROUP.
+ -m MODE $chmodprog installed files to MODE.
+ -o USER $chownprog installed files to USER.
+ -s $stripprog installed files.
+ -t DIRECTORY install into DIRECTORY.
+ -T report an error if DSTFILE is a directory.
+
+Environment variables override the default commands:
+ CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
+ RMPROG STRIPPROG
+"
+
+while test $# -ne 0; do
+ case $1 in
+ -c) ;;
+
+ -C) copy_on_change=true;;
+
+ -d) dir_arg=true;;
+
+ -g) chgrpcmd="$chgrpprog $2"
+ shift;;
+
+ --help) echo "$usage"; exit $?;;
+
+ -m) mode=$2
+ case $mode in
+ *' '* | *' '* | *'
+'* | *'*'* | *'?'* | *'['*)
+ echo "$0: invalid mode: $mode" >&2
+ exit 1;;
+ esac
+ shift;;
+
+ -o) chowncmd="$chownprog $2"
+ shift;;
+
+ -s) stripcmd=$stripprog;;
+
+ -t) dst_arg=$2
+ # Protect names problematic for 'test' and other utilities.
+ case $dst_arg in
+ -* | [=\(\)!]) dst_arg=./$dst_arg;;
+ esac
+ shift;;
+
+ -T) no_target_directory=true;;
+
+ --version) echo "$0 $scriptversion"; exit $?;;
+
+ --) shift
+ break;;
+
+ -*) echo "$0: invalid option: $1" >&2
+ exit 1;;
+
+ *) break;;
+ esac
+ shift
+done
+
+if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
+ # When -d is used, all remaining arguments are directories to create.
+ # When -t is used, the destination is already specified.
+ # Otherwise, the last argument is the destination. Remove it from $@.
+ for arg
+ do
+ if test -n "$dst_arg"; then
+ # $@ is not empty: it contains at least $arg.
+ set fnord "$@" "$dst_arg"
+ shift # fnord
+ fi
+ shift # arg
+ dst_arg=$arg
+ # Protect names problematic for 'test' and other utilities.
+ case $dst_arg in
+ -* | [=\(\)!]) dst_arg=./$dst_arg;;
+ esac
+ done
+fi
+
+if test $# -eq 0; then
+ if test -z "$dir_arg"; then
+ echo "$0: no input file specified." >&2
+ exit 1
+ fi
+ # It's OK to call 'install-sh -d' without argument.
+ # This can happen when creating conditional directories.
+ exit 0
+fi
+
+if test -z "$dir_arg"; then
+ do_exit='(exit $ret); exit $ret'
+ trap "ret=129; $do_exit" 1
+ trap "ret=130; $do_exit" 2
+ trap "ret=141; $do_exit" 13
+ trap "ret=143; $do_exit" 15
+
+ # Set umask so as not to create temps with too-generous modes.
+ # However, 'strip' requires both read and write access to temps.
+ case $mode in
+ # Optimize common cases.
+ *644) cp_umask=133;;
+ *755) cp_umask=22;;
+
+ *[0-7])
+ if test -z "$stripcmd"; then
+ u_plus_rw=
+ else
+ u_plus_rw='% 200'
+ fi
+ cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
+ *)
+ if test -z "$stripcmd"; then
+ u_plus_rw=
+ else
+ u_plus_rw=,u+rw
+ fi
+ cp_umask=$mode$u_plus_rw;;
+ esac
+fi
+
+for src
+do
+ # Protect names problematic for 'test' and other utilities.
+ case $src in
+ -* | [=\(\)!]) src=./$src;;
+ esac
+
+ if test -n "$dir_arg"; then
+ dst=$src
+ dstdir=$dst
+ test -d "$dstdir"
+ dstdir_status=$?
+ else
+
+ # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
+ # might cause directories to be created, which would be especially bad
+ # if $src (and thus $dsttmp) contains '*'.
+ if test ! -f "$src" && test ! -d "$src"; then
+ echo "$0: $src does not exist." >&2
+ exit 1
+ fi
+
+ if test -z "$dst_arg"; then
+ echo "$0: no destination specified." >&2
+ exit 1
+ fi
+ dst=$dst_arg
+
+ # If destination is a directory, append the input filename; won't work
+ # if double slashes aren't ignored.
+ if test -d "$dst"; then
+ if test -n "$no_target_directory"; then
+ echo "$0: $dst_arg: Is a directory" >&2
+ exit 1
+ fi
+ dstdir=$dst
+ dst=$dstdir/`basename "$src"`
+ dstdir_status=0
+ else
+ # Prefer dirname, but fall back on a substitute if dirname fails.
+ dstdir=`
+ (dirname "$dst") 2>/dev/null ||
+ expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$dst" : 'X\(//\)[^/]' \| \
+ X"$dst" : 'X\(//\)$' \| \
+ X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
+ echo X"$dst" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'
+ `
+
+ test -d "$dstdir"
+ dstdir_status=$?
+ fi
+ fi
+
+ obsolete_mkdir_used=false
+
+ if test $dstdir_status != 0; then
+ case $posix_mkdir in
+ '')
+ # Create intermediate dirs using mode 755 as modified by the umask.
+ # This is like FreeBSD 'install' as of 1997-10-28.
+ umask=`umask`
+ case $stripcmd.$umask in
+ # Optimize common cases.
+ *[2367][2367]) mkdir_umask=$umask;;
+ .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
+
+ *[0-7])
+ mkdir_umask=`expr $umask + 22 \
+ - $umask % 100 % 40 + $umask % 20 \
+ - $umask % 10 % 4 + $umask % 2
+ `;;
+ *) mkdir_umask=$umask,go-w;;
+ esac
+
+ # With -d, create the new directory with the user-specified mode.
+ # Otherwise, rely on $mkdir_umask.
+ if test -n "$dir_arg"; then
+ mkdir_mode=-m$mode
+ else
+ mkdir_mode=
+ fi
+
+ posix_mkdir=false
+ case $umask in
+ *[123567][0-7][0-7])
+ # POSIX mkdir -p sets u+wx bits regardless of umask, which
+ # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
+ ;;
+ *)
+ tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
+ trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
+
+ if (umask $mkdir_umask &&
+ exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
+ then
+ if test -z "$dir_arg" || {
+ # Check for POSIX incompatibilities with -m.
+ # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
+ # other-writable bit of parent directory when it shouldn't.
+ # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
+ ls_ld_tmpdir=`ls -ld "$tmpdir"`
+ case $ls_ld_tmpdir in
+ d????-?r-*) different_mode=700;;
+ d????-?--*) different_mode=755;;
+ *) false;;
+ esac &&
+ $mkdirprog -m$different_mode -p -- "$tmpdir" && {
+ ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
+ test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
+ }
+ }
+ then posix_mkdir=:
+ fi
+ rmdir "$tmpdir/d" "$tmpdir"
+ else
+ # Remove any dirs left behind by ancient mkdir implementations.
+ rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
+ fi
+ trap '' 0;;
+ esac;;
+ esac
+
+ if
+ $posix_mkdir && (
+ umask $mkdir_umask &&
+ $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
+ )
+ then :
+ else
+
+ # The umask is ridiculous, or mkdir does not conform to POSIX,
+ # or it failed possibly due to a race condition. Create the
+ # directory the slow way, step by step, checking for races as we go.
+
+ case $dstdir in
+ /*) prefix='/';;
+ [-=\(\)!]*) prefix='./';;
+ *) prefix='';;
+ esac
+
+ eval "$initialize_posix_glob"
+
+ oIFS=$IFS
+ IFS=/
+ $posix_glob set -f
+ set fnord $dstdir
+ shift
+ $posix_glob set +f
+ IFS=$oIFS
+
+ prefixes=
+
+ for d
+ do
+ test X"$d" = X && continue
+
+ prefix=$prefix$d
+ if test -d "$prefix"; then
+ prefixes=
+ else
+ if $posix_mkdir; then
+ (umask=$mkdir_umask &&
+ $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
+ # Don't fail if two instances are running concurrently.
+ test -d "$prefix" || exit 1
+ else
+ case $prefix in
+ *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
+ *) qprefix=$prefix;;
+ esac
+ prefixes="$prefixes '$qprefix'"
+ fi
+ fi
+ prefix=$prefix/
+ done
+
+ if test -n "$prefixes"; then
+ # Don't fail if two instances are running concurrently.
+ (umask $mkdir_umask &&
+ eval "\$doit_exec \$mkdirprog $prefixes") ||
+ test -d "$dstdir" || exit 1
+ obsolete_mkdir_used=true
+ fi
+ fi
+ fi
+
+ if test -n "$dir_arg"; then
+ { test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
+ { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
+ { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
+ test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
+ else
+
+ # Make a couple of temp file names in the proper directory.
+ dsttmp=$dstdir/_inst.$$_
+ rmtmp=$dstdir/_rm.$$_
+
+ # Trap to clean up those temp files at exit.
+ trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
+
+ # Copy the file name to the temp name.
+ (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
+
+ # and set any options; do chmod last to preserve setuid bits.
+ #
+ # If any of these fail, we abort the whole thing. If we want to
+ # ignore errors from any of these, just make sure not to ignore
+ # errors from the above "$doit $cpprog $src $dsttmp" command.
+ #
+ { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
+ { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
+ { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
+ { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
+
+ # If -C, don't bother to copy if it wouldn't change the file.
+ if $copy_on_change &&
+ old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` &&
+ new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` &&
+
+ eval "$initialize_posix_glob" &&
+ $posix_glob set -f &&
+ set X $old && old=:$2:$4:$5:$6 &&
+ set X $new && new=:$2:$4:$5:$6 &&
+ $posix_glob set +f &&
+
+ test "$old" = "$new" &&
+ $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
+ then
+ rm -f "$dsttmp"
+ else
+ # Rename the file to the real destination.
+ $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
+
+ # The rename failed, perhaps because mv can't rename something else
+ # to itself, or perhaps because mv is so ancient that it does not
+ # support -f.
+ {
+ # Now remove or move aside any old file at destination location.
+ # We try this two ways since rm can't unlink itself on some
+ # systems and the destination file might be busy for other
+ # reasons. In this case, the final cleanup might fail but the new
+ # file should still install successfully.
+ {
+ test ! -f "$dst" ||
+ $doit $rmcmd -f "$dst" 2>/dev/null ||
+ { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
+ { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
+ } ||
+ { echo "$0: cannot unlink or rename $dst" >&2
+ (exit 1); exit 1
+ }
+ } &&
+
+ # Now rename the file to the real destination.
+ $doit $mvcmd "$dsttmp" "$dst"
+ }
+ fi || exit 1
+
+ trap '' 0
+ fi
+done
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
diff --git a/lib/Makefile.am b/lib/Makefile.am
new file mode 100644
index 0000000..002866a
--- /dev/null
+++ b/lib/Makefile.am
@@ -0,0 +1,66 @@
+#
+# Copyright (c) 2009-2020 Red Hat, Inc.
+#
+# Authors: Andrew Beekhof
+# Steven Dake (sdake@redhat.com)
+#
+# This software licensed under BSD license, the text of which follows:
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# - Redistributions of source code must retain the above copyright notice,
+# this list of conditions and the following disclaimer.
+# - Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+# - Neither the name of the MontaVista Software, Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from this
+# software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+# THE POSSIBILITY OF SUCH DAMAGE.
+
+# Functions to be used at link time (target.lo)
+get_libname=$(shell echo $1 | $(SED) -e "s/\.lo//")
+uc=$(shell echo $(call get_libname,$1) | tr a-z A-Z)
+get_soname=$(subst .,:,$(if $($(call uc,$1)_SONAME),$($(call uc,$1)_SONAME),$(SONAME)))
+get_major=$(firstword $(subst :, ,$(call get_soname,$1)))
+
+MAINTAINERCLEANFILES = Makefile.in
+
+EXTRA_DIST = libcfg.versions libcfg.verso \
+ libcmap.versions libcmap.verso \
+ libcpg.versions libcpg.verso \
+ libquorum.versions libquorum.verso \
+ libsam.versions libsam.verso \
+ libvotequorum.versions libvotequorum.verso
+
+noinst_HEADERS = util.h
+
+# override global LIBS that pulls in lots of craft we don't need here
+LIBS = -version-number $(call get_soname,$<) \
+ @VERSCRIPT_LDFLAGS@ \
+ -lpthread \
+ $(top_builddir)/common_lib/libcorosync_common.la \
+ $(LIBQB_LIBS)
+
+lib_LTLIBRARIES = libcpg.la libquorum.la libcfg.la \
+ libvotequorum.la libcmap.la libsam.la
+
+libcpg_la_SOURCES = cpg.c
+libcfg_la_SOURCES = cfg.c
+libquorum_la_SOURCES = quorum.c
+libvotequorum_la_SOURCES= votequorum.c
+libcmap_la_SOURCES = cmap.c
+libsam_la_SOURCES = sam.c
+libsam_la_LIBADD = libquorum.la libcmap.la
diff --git a/lib/Makefile.in b/lib/Makefile.in
new file mode 100644
index 0000000..2fa4309
--- /dev/null
+++ b/lib/Makefile.in
@@ -0,0 +1,786 @@
+# Makefile.in generated by automake 1.13.4 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+#
+# Copyright (c) 2009-2020 Red Hat, Inc.
+#
+# Authors: Andrew Beekhof
+# Steven Dake (sdake@redhat.com)
+#
+# This software licensed under BSD license, the text of which follows:
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# - Redistributions of source code must retain the above copyright notice,
+# this list of conditions and the following disclaimer.
+# - Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+# - Neither the name of the MontaVista Software, Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from this
+# software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+# THE POSSIBILITY OF SUCH DAMAGE.
+
+
+VPATH = @srcdir@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = lib
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+ $(top_srcdir)/depcomp $(noinst_HEADERS)
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/lib/libcfg.verso $(top_srcdir)/lib/libcpg.verso \
+ $(top_srcdir)/lib/libquorum.verso \
+ $(top_srcdir)/lib/libsam.verso \
+ $(top_srcdir)/lib/libvotequorum.verso \
+ $(top_srcdir)/lib/libcmap.verso $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/include/corosync/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+am__installdirs = "$(DESTDIR)$(libdir)"
+LTLIBRARIES = $(lib_LTLIBRARIES)
+libcfg_la_LIBADD =
+am_libcfg_la_OBJECTS = cfg.lo
+libcfg_la_OBJECTS = $(am_libcfg_la_OBJECTS)
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 =
+libcmap_la_LIBADD =
+am_libcmap_la_OBJECTS = cmap.lo
+libcmap_la_OBJECTS = $(am_libcmap_la_OBJECTS)
+libcpg_la_LIBADD =
+am_libcpg_la_OBJECTS = cpg.lo
+libcpg_la_OBJECTS = $(am_libcpg_la_OBJECTS)
+libquorum_la_LIBADD =
+am_libquorum_la_OBJECTS = quorum.lo
+libquorum_la_OBJECTS = $(am_libquorum_la_OBJECTS)
+libsam_la_DEPENDENCIES = libquorum.la libcmap.la
+am_libsam_la_OBJECTS = sam.lo
+libsam_la_OBJECTS = $(am_libsam_la_OBJECTS)
+libvotequorum_la_LIBADD =
+am_libvotequorum_la_OBJECTS = votequorum.lo
+libvotequorum_la_OBJECTS = $(am_libvotequorum_la_OBJECTS)
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/corosync
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo " CC " $@;
+am__v_CC_1 =
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo " CCLD " $@;
+am__v_CCLD_1 =
+SOURCES = $(libcfg_la_SOURCES) $(libcmap_la_SOURCES) \
+ $(libcpg_la_SOURCES) $(libquorum_la_SOURCES) \
+ $(libsam_la_SOURCES) $(libvotequorum_la_SOURCES)
+DIST_SOURCES = $(libcfg_la_SOURCES) $(libcmap_la_SOURCES) \
+ $(libcpg_la_SOURCES) $(libquorum_la_SOURCES) \
+ $(libsam_la_SOURCES) $(libvotequorum_la_SOURCES)
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+HEADERS = $(noinst_HEADERS)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALLOCA = @ALLOCA@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUGTOOL = @AUGTOOL@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BASHPATH = @BASHPATH@
+BINDGEN = @BINDGEN@
+CARGO = @CARGO@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFG_SONAME = @CFG_SONAME@
+CFLAGS = @CFLAGS@
+CLIPPY = @CLIPPY@
+CMAP_SONAME = @CMAP_SONAME@
+COROSYSCONFDIR = @COROSYSCONFDIR@
+CPG_SONAME = @CPG_SONAME@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DBUS_CFLAGS = @DBUS_CFLAGS@
+DBUS_LIBS = @DBUS_LIBS@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DOT = @DOT@
+DOXYGEN = @DOXYGEN@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GREP = @GREP@
+GROFF = @GROFF@
+INITCONFIGDIR = @INITCONFIGDIR@
+INITDDIR = @INITDDIR@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBQB_CFLAGS = @LIBQB_CFLAGS@
+LIBQB_LIBS = @LIBQB_LIBS@
+
+# override global LIBS that pulls in lots of craft we don't need here
+LIBS = -version-number $(call get_soname,$<) \
+ @VERSCRIPT_LDFLAGS@ \
+ -lpthread \
+ $(top_builddir)/common_lib/libcorosync_common.la \
+ $(LIBQB_LIBS)
+
+LIBTOOL = @LIBTOOL@
+LINT_FLAGS = @LINT_FLAGS@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LOGDIR = @LOGDIR@
+LOGROTATEDIR = @LOGROTATEDIR@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+QUORUM_SONAME = @QUORUM_SONAME@
+RANLIB = @RANLIB@
+RUSTC = @RUSTC@
+RUSTDOC = @RUSTDOC@
+RUSTFMT = @RUSTFMT@
+RUST_FLAGS = @RUST_FLAGS@
+RUST_TARGET_DIR = @RUST_TARGET_DIR@
+SAM_SONAME = @SAM_SONAME@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SNMPCONFIG = @SNMPCONFIG@
+SNMP_LIBS = @SNMP_LIBS@
+SOMAJOR = @SOMAJOR@
+SOMICRO = @SOMICRO@
+SOMINOR = @SOMINOR@
+SONAME = @SONAME@
+STRIP = @STRIP@
+SYSTEMDDIR = @SYSTEMDDIR@
+VERSCRIPT_LDFLAGS = @VERSCRIPT_LDFLAGS@
+VERSION = @VERSION@
+VOTEQUORUM_SONAME = @VOTEQUORUM_SONAME@
+WITH_LIST = @WITH_LIST@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+corosyncrustver = @corosyncrustver@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+knet_CFLAGS = @knet_CFLAGS@
+knet_LIBS = @knet_LIBS@
+libdir = @libdir@
+libexecdir = @libexecdir@
+libsystemd_CFLAGS = @libsystemd_CFLAGS@
+libsystemd_LIBS = @libsystemd_LIBS@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+nozzle_CFLAGS = @nozzle_CFLAGS@
+nozzle_LIBS = @nozzle_LIBS@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+statgrab_CFLAGS = @statgrab_CFLAGS@
+statgrab_LIBS = @statgrab_LIBS@
+statgrabge090_CFLAGS = @statgrabge090_CFLAGS@
+statgrabge090_LIBS = @statgrabge090_LIBS@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+
+# Functions to be used at link time (target.lo)
+get_libname = $(shell echo $1 | $(SED) -e "s/\.lo//")
+uc = $(shell echo $(call get_libname,$1) | tr a-z A-Z)
+get_soname = $(subst .,:,$(if $($(call uc,$1)_SONAME),$($(call uc,$1)_SONAME),$(SONAME)))
+get_major = $(firstword $(subst :, ,$(call get_soname,$1)))
+MAINTAINERCLEANFILES = Makefile.in
+EXTRA_DIST = libcfg.versions libcfg.verso \
+ libcmap.versions libcmap.verso \
+ libcpg.versions libcpg.verso \
+ libquorum.versions libquorum.verso \
+ libsam.versions libsam.verso \
+ libvotequorum.versions libvotequorum.verso
+
+noinst_HEADERS = util.h
+lib_LTLIBRARIES = libcpg.la libquorum.la libcfg.la \
+ libvotequorum.la libcmap.la libsam.la
+
+libcpg_la_SOURCES = cpg.c
+libcfg_la_SOURCES = cfg.c
+libquorum_la_SOURCES = quorum.c
+libvotequorum_la_SOURCES = votequorum.c
+libcmap_la_SOURCES = cmap.c
+libsam_la_SOURCES = sam.c
+libsam_la_LIBADD = libquorum.la libcmap.la
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign lib/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign lib/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+install-libLTLIBRARIES: $(lib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
+ list2=; for p in $$list; do \
+ if test -f $$p; then \
+ list2="$$list2 $$p"; \
+ else :; fi; \
+ done; \
+ test -z "$$list2" || { \
+ echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \
+ }
+
+uninstall-libLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \
+ done
+
+clean-libLTLIBRARIES:
+ -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
+ @list='$(lib_LTLIBRARIES)'; \
+ locs=`for p in $$list; do echo $$p; done | \
+ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+ sort -u`; \
+ test -z "$$locs" || { \
+ echo rm -f $${locs}; \
+ rm -f $${locs}; \
+ }
+
+libcfg.la: $(libcfg_la_OBJECTS) $(libcfg_la_DEPENDENCIES) $(EXTRA_libcfg_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(LINK) -rpath $(libdir) $(libcfg_la_OBJECTS) $(libcfg_la_LIBADD) $(LIBS)
+
+libcmap.la: $(libcmap_la_OBJECTS) $(libcmap_la_DEPENDENCIES) $(EXTRA_libcmap_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(LINK) -rpath $(libdir) $(libcmap_la_OBJECTS) $(libcmap_la_LIBADD) $(LIBS)
+
+libcpg.la: $(libcpg_la_OBJECTS) $(libcpg_la_DEPENDENCIES) $(EXTRA_libcpg_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(LINK) -rpath $(libdir) $(libcpg_la_OBJECTS) $(libcpg_la_LIBADD) $(LIBS)
+
+libquorum.la: $(libquorum_la_OBJECTS) $(libquorum_la_DEPENDENCIES) $(EXTRA_libquorum_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(LINK) -rpath $(libdir) $(libquorum_la_OBJECTS) $(libquorum_la_LIBADD) $(LIBS)
+
+libsam.la: $(libsam_la_OBJECTS) $(libsam_la_DEPENDENCIES) $(EXTRA_libsam_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(LINK) -rpath $(libdir) $(libsam_la_OBJECTS) $(libsam_la_LIBADD) $(LIBS)
+
+libvotequorum.la: $(libvotequorum_la_OBJECTS) $(libvotequorum_la_DEPENDENCIES) $(EXTRA_libvotequorum_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(LINK) -rpath $(libdir) $(libvotequorum_la_OBJECTS) $(libvotequorum_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cfg.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmap.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpg.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/quorum.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sam.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/votequorum.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LTLIBRARIES) $(HEADERS)
+installdirs:
+ for dir in "$(DESTDIR)$(libdir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+ -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+clean: clean-am
+
+clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am: install-libLTLIBRARIES
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-libLTLIBRARIES
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
+ clean-libLTLIBRARIES clean-libtool cscopelist-am ctags \
+ ctags-am distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-dvi install-dvi-am install-exec \
+ install-exec-am install-html install-html-am install-info \
+ install-info-am install-libLTLIBRARIES install-man install-pdf \
+ install-pdf-am install-ps install-ps-am install-strip \
+ installcheck installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags tags-am uninstall uninstall-am uninstall-libLTLIBRARIES
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/lib/cfg.c b/lib/cfg.c
new file mode 100644
index 0000000..f0a3e9a
--- /dev/null
+++ b/lib/cfg.c
@@ -0,0 +1,835 @@
+/*
+ * Copyright (c) 2002-2005 MontaVista Software, Inc.
+ * Copyright (c) 2006-2020 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Author: Steven Dake (sdake@redhat.com)
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of the MontaVista Software, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <pthread.h>
+#include <limits.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/select.h>
+#include <sys/un.h>
+#include <sys/uio.h>
+
+#include <qb/qbipcc.h>
+
+#include <corosync/corotypes.h>
+#include <corosync/corodefs.h>
+#include <corosync/hdb.h>
+
+#include <corosync/cfg.h>
+#include <corosync/ipc_cfg.h>
+
+#include "util.h"
+
+/*
+ * Data structure for instance data
+ */
+struct cfg_inst {
+ qb_ipcc_connection_t *c;
+ corosync_cfg_callbacks_t callbacks;
+ cs_name_t comp_name;
+ int comp_registered;
+ int finalize;
+};
+
+/*
+ * All instances in one database
+ */
+static void cfg_inst_free (void *inst);
+
+DECLARE_HDB_DATABASE (cfg_hdb, cfg_inst_free);
+
+/*
+ * Implementation
+ */
+
+cs_error_t
+corosync_cfg_initialize (
+ corosync_cfg_handle_t *cfg_handle,
+ const corosync_cfg_callbacks_t *cfg_callbacks)
+{
+ struct cfg_inst *cfg_inst;
+ cs_error_t error = CS_OK;
+
+ error = hdb_error_to_cs (hdb_handle_create (&cfg_hdb, sizeof (struct cfg_inst), cfg_handle));
+ if (error != CS_OK) {
+ goto error_no_destroy;
+ }
+
+ error = hdb_error_to_cs (hdb_handle_get (&cfg_hdb, *cfg_handle, (void *)&cfg_inst));
+ if (error != CS_OK) {
+ goto error_destroy;
+ }
+
+ cfg_inst->finalize = 0;
+ cfg_inst->c = qb_ipcc_connect ("cfg", IPC_REQUEST_SIZE);
+ if (cfg_inst->c == NULL) {
+ error = qb_to_cs_error(-errno);
+ goto error_put_destroy;
+ }
+
+ if (cfg_callbacks) {
+ memcpy (&cfg_inst->callbacks, cfg_callbacks, sizeof (corosync_cfg_callbacks_t));
+ }
+
+ (void)hdb_handle_put (&cfg_hdb, *cfg_handle);
+
+ return (CS_OK);
+
+error_put_destroy:
+ (void)hdb_handle_put (&cfg_hdb, *cfg_handle);
+error_destroy:
+ (void)hdb_handle_destroy (&cfg_hdb, *cfg_handle);
+error_no_destroy:
+ return (error);
+}
+
+cs_error_t
+corosync_cfg_fd_get (
+ corosync_cfg_handle_t cfg_handle,
+ int32_t *selection_fd)
+{
+ struct cfg_inst *cfg_inst;
+ cs_error_t error;
+
+ error = hdb_error_to_cs (hdb_handle_get (&cfg_hdb, cfg_handle, (void *)&cfg_inst));
+ if (error != CS_OK) {
+ return (error);
+ }
+
+ error = qb_to_cs_error (qb_ipcc_fd_get (cfg_inst->c, selection_fd));
+
+ (void)hdb_handle_put (&cfg_hdb, cfg_handle);
+ return (error);
+}
+
+cs_error_t
+corosync_cfg_dispatch (
+ corosync_cfg_handle_t cfg_handle,
+ cs_dispatch_flags_t dispatch_flags)
+{
+ int timeout = -1;
+ cs_error_t error;
+ int cont = 1; /* always continue do loop except when set to 0 */
+ struct cfg_inst *cfg_inst;
+ struct res_lib_cfg_testshutdown *res_lib_cfg_testshutdown;
+ corosync_cfg_callbacks_t callbacks;
+ struct qb_ipc_response_header *dispatch_data;
+ char dispatch_buf[IPC_DISPATCH_SIZE];
+
+ error = hdb_error_to_cs (hdb_handle_get (&cfg_hdb, cfg_handle,
+ (void *)&cfg_inst));
+ if (error != CS_OK) {
+ return (error);
+ }
+
+ /*
+ * Timeout instantly for CS_DISPATCH_ONE_NONBLOCKING or CS_DISPATCH_ALL and
+ * wait indefinately for CS_DISPATCH_ONE or CS_DISPATCH_BLOCKING
+ */
+ if (dispatch_flags == CS_DISPATCH_ALL || dispatch_flags == CS_DISPATCH_ONE_NONBLOCKING) {
+ timeout = 0;
+ }
+
+ dispatch_data = (struct qb_ipc_response_header *)dispatch_buf;
+ do {
+ error = qb_to_cs_error (qb_ipcc_event_recv (
+ cfg_inst->c,
+ dispatch_buf,
+ IPC_DISPATCH_SIZE,
+ timeout));
+ if (error == CS_ERR_BAD_HANDLE) {
+ error = CS_OK;
+ goto error_put;
+ }
+ if (error == CS_ERR_TRY_AGAIN) {
+ if (dispatch_flags == CS_DISPATCH_ONE_NONBLOCKING) {
+ /*
+ * Don't mask error
+ */
+ goto error_put;
+ }
+ error = CS_OK;
+ if (dispatch_flags == CS_DISPATCH_ALL) {
+ break; /* exit do while cont is 1 loop */
+ } else {
+ continue; /* next poll */
+ }
+ }
+ if (error != CS_OK) {
+ goto error_put;
+ }
+
+ /*
+ * Make copy of callbacks, message data, unlock instance, and call callback
+ * A risk of this dispatch method is that the callback routines may
+ * operate at the same time that cfgFinalize has been called in another thread.
+ */
+ memcpy (&callbacks, &cfg_inst->callbacks, sizeof (corosync_cfg_callbacks_t));
+
+ /*
+ * Dispatch incoming response
+ */
+ switch (dispatch_data->id) {
+ case MESSAGE_RES_CFG_TESTSHUTDOWN:
+ if (callbacks.corosync_cfg_shutdown_callback == NULL) {
+ break;
+ }
+
+ res_lib_cfg_testshutdown = (struct res_lib_cfg_testshutdown *)dispatch_data;
+ callbacks.corosync_cfg_shutdown_callback(cfg_handle, res_lib_cfg_testshutdown->flags);
+ break;
+ default:
+ error = CS_ERR_LIBRARY;
+ goto error_nounlock;
+ break;
+ }
+ if (cfg_inst->finalize) {
+ /*
+ * If the finalize has been called then get out of the dispatch.
+ */
+ error = CS_ERR_BAD_HANDLE;
+ goto error_put;
+ }
+
+ /*
+ * Determine if more messages should be processed
+ */
+ if (dispatch_flags == CS_DISPATCH_ONE || dispatch_flags == CS_DISPATCH_ONE_NONBLOCKING) {
+ cont = 0;
+ }
+ } while (cont);
+
+error_put:
+ (void)hdb_handle_put (&cfg_hdb, cfg_handle);
+error_nounlock:
+ return (error);
+}
+
+static void cfg_inst_free (void *inst)
+{
+ struct cfg_inst *cfg_inst = (struct cfg_inst *)inst;
+ qb_ipcc_disconnect(cfg_inst->c);
+}
+
+cs_error_t
+corosync_cfg_finalize (
+ corosync_cfg_handle_t cfg_handle)
+{
+ struct cfg_inst *cfg_inst;
+ cs_error_t error;
+
+ error = hdb_error_to_cs(hdb_handle_get (&cfg_hdb, cfg_handle, (void *)&cfg_inst));
+ if (error != CS_OK) {
+ return (error);
+ }
+
+ /*
+ * Another thread has already started finalizing
+ */
+ if (cfg_inst->finalize) {
+ (void)hdb_handle_put (&cfg_hdb, cfg_handle);
+ return (CS_ERR_BAD_HANDLE);
+ }
+
+ cfg_inst->finalize = 1;
+
+ (void)hdb_handle_destroy (&cfg_hdb, cfg_handle);
+
+ (void)hdb_handle_put (&cfg_hdb, cfg_handle);
+
+ return (error);
+}
+
+cs_error_t
+corosync_cfg_ring_status_get (
+ corosync_cfg_handle_t cfg_handle,
+ char ***interface_names,
+ char ***status,
+ unsigned int *interface_count)
+{
+ struct cfg_inst *cfg_inst;
+ struct req_lib_cfg_ringstatusget req_lib_cfg_ringstatusget;
+ struct res_lib_cfg_ringstatusget res_lib_cfg_ringstatusget;
+ unsigned int i, j;
+ cs_error_t error;
+ struct iovec iov;
+
+ error = hdb_error_to_cs(hdb_handle_get (&cfg_hdb, cfg_handle, (void *)&cfg_inst));
+ if (error != CS_OK) {
+ return (error);
+ }
+
+ req_lib_cfg_ringstatusget.header.size = sizeof (struct req_lib_cfg_ringstatusget);
+ req_lib_cfg_ringstatusget.header.id = MESSAGE_REQ_CFG_RINGSTATUSGET;
+
+ iov.iov_base = (void *)&req_lib_cfg_ringstatusget,
+ iov.iov_len = sizeof (struct req_lib_cfg_ringstatusget),
+
+ error = qb_to_cs_error (qb_ipcc_sendv_recv(cfg_inst->c,
+ &iov,
+ 1,
+ &res_lib_cfg_ringstatusget,
+ sizeof (struct res_lib_cfg_ringstatusget), CS_IPC_TIMEOUT_MS));
+
+ if (error != CS_OK) {
+ goto exit_handle_put;
+ }
+
+ *interface_count = res_lib_cfg_ringstatusget.interface_count;
+ *interface_names = malloc (sizeof (char *) * *interface_count);
+ if (*interface_names == NULL) {
+ return (CS_ERR_NO_MEMORY);
+ }
+ memset (*interface_names, 0, sizeof (char *) * *interface_count);
+
+ *status = malloc (sizeof (char *) * *interface_count);
+ if (*status == NULL) {
+ error = CS_ERR_NO_MEMORY;
+ goto error_free_interface_names_array;
+ }
+ memset (*status, 0, sizeof (char *) * *interface_count);
+
+ for (i = 0; i < res_lib_cfg_ringstatusget.interface_count; i++) {
+ (*(interface_names))[i] = strdup (res_lib_cfg_ringstatusget.interface_name[i]);
+ if ((*(interface_names))[i] == NULL) {
+ error = CS_ERR_NO_MEMORY;
+ goto error_free_interface_names;
+ }
+ }
+
+ for (i = 0; i < res_lib_cfg_ringstatusget.interface_count; i++) {
+ (*(status))[i] = strdup (res_lib_cfg_ringstatusget.interface_status[i]);
+ if ((*(status))[i] == NULL) {
+ error = CS_ERR_NO_MEMORY;
+ goto error_free_status;
+ }
+ }
+ goto exit_handle_put;
+
+error_free_status:
+ for (j = 0; j < i; j++) {
+ free ((*(status))[j]);
+ }
+ i = *interface_count;
+
+error_free_interface_names:
+ for (j = 0; j < i; j++) {
+ free ((*(interface_names))[j]);
+ }
+
+ free (*status);
+
+error_free_interface_names_array:
+ free (*interface_names);
+
+exit_handle_put:
+ (void)hdb_handle_put (&cfg_hdb, cfg_handle);
+
+ return (error);
+}
+
+cs_error_t
+corosync_cfg_node_status_get (
+ corosync_cfg_handle_t cfg_handle,
+ unsigned int nodeid,
+ corosync_cfg_node_status_version_t version,
+ void *node_status)
+{
+ struct cfg_inst *cfg_inst;
+ struct req_lib_cfg_nodestatusget req_lib_cfg_nodestatusget;
+ cs_error_t error;
+ struct iovec iov;
+ size_t cfg_node_status_size;
+ void *res_lib_cfg_nodestatuget_ptr;
+ struct res_lib_cfg_nodestatusget_v1 res_lib_cfg_nodestatusget_v1;
+ struct res_lib_cfg_nodestatusget_version *res_lib_cfg_nodestatusget_version;
+
+ if (!node_status) {
+ return (CS_ERR_INVALID_PARAM);
+ }
+
+ switch (version) {
+ case CFG_NODE_STATUS_V1:
+ cfg_node_status_size = sizeof(struct res_lib_cfg_nodestatusget_v1);
+ res_lib_cfg_nodestatuget_ptr = &res_lib_cfg_nodestatusget_v1;
+
+ break;
+ default:
+ return (CS_ERR_INVALID_PARAM);
+ break;
+ }
+
+ error = hdb_error_to_cs(hdb_handle_get (&cfg_hdb, cfg_handle, (void *)&cfg_inst));
+ if (error != CS_OK) {
+ return (error);
+ }
+
+ req_lib_cfg_nodestatusget.header.size = sizeof (struct req_lib_cfg_nodestatusget);
+ req_lib_cfg_nodestatusget.header.id = MESSAGE_REQ_CFG_NODESTATUSGET;
+ req_lib_cfg_nodestatusget.nodeid = nodeid;
+ req_lib_cfg_nodestatusget.version = version;
+
+ iov.iov_base = (void *)&req_lib_cfg_nodestatusget,
+ iov.iov_len = sizeof (struct req_lib_cfg_nodestatusget),
+
+ error = qb_to_cs_error (qb_ipcc_sendv_recv(cfg_inst->c,
+ &iov,
+ 1,
+ res_lib_cfg_nodestatuget_ptr,
+ cfg_node_status_size, CS_IPC_TIMEOUT_MS));
+ if (error != CS_OK) {
+ goto error_put;
+ }
+
+ res_lib_cfg_nodestatusget_version = res_lib_cfg_nodestatuget_ptr;
+ error = res_lib_cfg_nodestatusget_version->header.error;
+ if (error != CS_OK) {
+ goto error_put;
+ }
+
+ if (res_lib_cfg_nodestatusget_version->version != version) {
+ /*
+ * corosync sent us something we don't really understand.
+ */
+ error = CS_ERR_NOT_SUPPORTED;
+ goto error_put;
+ }
+
+ switch (version) {
+ case CFG_NODE_STATUS_V1:
+ memcpy(node_status, &res_lib_cfg_nodestatusget_v1.node_status,
+ sizeof(struct corosync_cfg_node_status_v1));
+ break;
+ }
+
+error_put:
+ (void)hdb_handle_put (&cfg_hdb, cfg_handle);
+
+ return (error);
+}
+
+
+cs_error_t
+corosync_cfg_trackstart (
+ corosync_cfg_handle_t cfg_handle,
+ uint8_t track_flags)
+{
+ struct cfg_inst *cfg_inst;
+ struct req_lib_cfg_trackstart req_lib_cfg_trackstart;
+ struct res_lib_cfg_trackstart res_lib_cfg_trackstart;
+ cs_error_t error;
+ struct iovec iov;
+
+ req_lib_cfg_trackstart.header.size = sizeof (struct req_lib_cfg_trackstart);
+ req_lib_cfg_trackstart.header.id = MESSAGE_REQ_CFG_TRACKSTART;
+ req_lib_cfg_trackstart.track_flags = track_flags;
+
+ error = hdb_error_to_cs(hdb_handle_get (&cfg_hdb, cfg_handle,
+ (void *)&cfg_inst));
+ if (error != CS_OK) {
+ return (error);
+ }
+
+ iov.iov_base = (void *)&req_lib_cfg_trackstart,
+ iov.iov_len = sizeof (struct req_lib_cfg_trackstart),
+
+ error = qb_to_cs_error (qb_ipcc_sendv_recv (cfg_inst->c,
+ &iov,
+ 1,
+ &res_lib_cfg_trackstart,
+ sizeof (struct res_lib_cfg_trackstart), CS_IPC_TIMEOUT_MS));
+
+ (void)hdb_handle_put (&cfg_hdb, cfg_handle);
+
+ return (error == CS_OK ? res_lib_cfg_trackstart.header.error : error);
+}
+
+cs_error_t
+corosync_cfg_trackstop (
+ corosync_cfg_handle_t cfg_handle)
+{
+ struct cfg_inst *cfg_inst;
+ struct req_lib_cfg_trackstop req_lib_cfg_trackstop;
+ struct res_lib_cfg_trackstop res_lib_cfg_trackstop;
+ cs_error_t error;
+ struct iovec iov;
+
+ error = hdb_error_to_cs (hdb_handle_get (&cfg_hdb, cfg_handle,
+ (void *)&cfg_inst));
+ if (error != CS_OK) {
+ return (error);
+ }
+
+ req_lib_cfg_trackstop.header.size = sizeof (struct req_lib_cfg_trackstop);
+ req_lib_cfg_trackstop.header.id = MESSAGE_REQ_CFG_TRACKSTOP;
+
+ iov.iov_base = (void *)&req_lib_cfg_trackstop,
+ iov.iov_len = sizeof (struct req_lib_cfg_trackstop),
+
+ error = qb_to_cs_error (qb_ipcc_sendv_recv (cfg_inst->c,
+ &iov,
+ 1,
+ &res_lib_cfg_trackstop,
+ sizeof (struct res_lib_cfg_trackstop), CS_IPC_TIMEOUT_MS));
+
+ (void)hdb_handle_put (&cfg_hdb, cfg_handle);
+
+ return (error == CS_OK ? res_lib_cfg_trackstop.header.error : error);
+}
+
+cs_error_t
+corosync_cfg_kill_node (
+ corosync_cfg_handle_t cfg_handle,
+ unsigned int nodeid,
+ const char *reason)
+{
+ struct cfg_inst *cfg_inst;
+ struct req_lib_cfg_killnode req_lib_cfg_killnode;
+ struct res_lib_cfg_killnode res_lib_cfg_killnode;
+ cs_error_t error;
+ struct iovec iov;
+
+ if (strlen(reason) >= CS_MAX_NAME_LENGTH)
+ return CS_ERR_NAME_TOO_LONG;
+
+ error = hdb_error_to_cs (hdb_handle_get (&cfg_hdb, cfg_handle,
+ (void *)&cfg_inst));
+ if (error != CS_OK) {
+ return (error);
+ }
+
+ req_lib_cfg_killnode.header.id = MESSAGE_REQ_CFG_KILLNODE;
+ req_lib_cfg_killnode.header.size = sizeof (struct req_lib_cfg_killnode);
+ req_lib_cfg_killnode.nodeid = nodeid;
+ strcpy((char *)req_lib_cfg_killnode.reason.value, reason);
+ req_lib_cfg_killnode.reason.length = strlen(reason)+1;
+
+ iov.iov_base = (void *)&req_lib_cfg_killnode;
+ iov.iov_len = sizeof (struct req_lib_cfg_killnode);
+
+ error = qb_to_cs_error (qb_ipcc_sendv_recv (cfg_inst->c,
+ &iov,
+ 1,
+ &res_lib_cfg_killnode,
+ sizeof (struct res_lib_cfg_killnode), CS_IPC_TIMEOUT_MS));
+
+ error = res_lib_cfg_killnode.header.error;
+
+ (void)hdb_handle_put (&cfg_hdb, cfg_handle);
+
+ return (error == CS_OK ? res_lib_cfg_killnode.header.error : error);
+}
+
+cs_error_t
+corosync_cfg_try_shutdown (
+ corosync_cfg_handle_t cfg_handle,
+ corosync_cfg_shutdown_flags_t flags)
+{
+ struct cfg_inst *cfg_inst;
+ struct req_lib_cfg_tryshutdown req_lib_cfg_tryshutdown;
+ struct res_lib_cfg_tryshutdown res_lib_cfg_tryshutdown;
+ cs_error_t error;
+ struct iovec iov;
+
+ error = hdb_error_to_cs(hdb_handle_get (&cfg_hdb, cfg_handle,
+ (void *)&cfg_inst));
+ if (error != CS_OK) {
+ return (error);
+ }
+
+ req_lib_cfg_tryshutdown.header.id = MESSAGE_REQ_CFG_TRYSHUTDOWN;
+ req_lib_cfg_tryshutdown.header.size = sizeof (struct req_lib_cfg_tryshutdown);
+ req_lib_cfg_tryshutdown.flags = flags;
+
+ iov.iov_base = (void *)&req_lib_cfg_tryshutdown;
+ iov.iov_len = sizeof (req_lib_cfg_tryshutdown);
+
+ error = qb_to_cs_error (qb_ipcc_sendv_recv (cfg_inst->c,
+ &iov,
+ 1,
+ &res_lib_cfg_tryshutdown,
+ sizeof (struct res_lib_cfg_tryshutdown), CS_IPC_TIMEOUT_MS));
+
+ (void)hdb_handle_put (&cfg_hdb, cfg_handle);
+
+ return (error == CS_OK ? res_lib_cfg_tryshutdown.header.error : error);
+}
+
+cs_error_t
+corosync_cfg_replyto_shutdown (
+ corosync_cfg_handle_t cfg_handle,
+ corosync_cfg_shutdown_reply_flags_t response)
+{
+ struct cfg_inst *cfg_inst;
+ struct req_lib_cfg_replytoshutdown req_lib_cfg_replytoshutdown;
+ struct res_lib_cfg_replytoshutdown res_lib_cfg_replytoshutdown;
+ struct iovec iov;
+ cs_error_t error;
+
+ error = hdb_error_to_cs(hdb_handle_get (&cfg_hdb, cfg_handle,
+ (void *)&cfg_inst));
+ if (error != CS_OK) {
+ return (error);
+ }
+
+ req_lib_cfg_replytoshutdown.header.id = MESSAGE_REQ_CFG_REPLYTOSHUTDOWN;
+ req_lib_cfg_replytoshutdown.header.size = sizeof (struct req_lib_cfg_replytoshutdown);
+ req_lib_cfg_replytoshutdown.response = response;
+
+ iov.iov_base = (void *)&req_lib_cfg_replytoshutdown;
+ iov.iov_len = sizeof (struct req_lib_cfg_replytoshutdown);
+
+ error = qb_to_cs_error (qb_ipcc_sendv_recv (cfg_inst->c,
+ &iov,
+ 1,
+ &res_lib_cfg_replytoshutdown,
+ sizeof (struct res_lib_cfg_replytoshutdown), CS_IPC_TIMEOUT_MS));
+
+ return (error);
+}
+
+cs_error_t corosync_cfg_get_node_addrs (
+ corosync_cfg_handle_t cfg_handle,
+ unsigned int nodeid,
+ size_t max_addrs,
+ int *num_addrs,
+ corosync_cfg_node_address_t *addrs)
+{
+ cs_error_t error;
+ struct req_lib_cfg_get_node_addrs req_lib_cfg_get_node_addrs;
+ struct res_lib_cfg_get_node_addrs *res_lib_cfg_get_node_addrs;
+ struct cfg_inst *cfg_inst;
+ int addrlen = 0;
+ int i;
+ struct iovec iov;
+ const char *addr_buf;
+ char response_buf[IPC_RESPONSE_SIZE];
+ char zeroes[sizeof(struct sockaddr_storage)];
+
+ error = hdb_error_to_cs(hdb_handle_get (&cfg_hdb, cfg_handle,
+ (void *)&cfg_inst));
+ if (error != CS_OK) {
+ return (error);
+ }
+ memset(zeroes, 0, sizeof(zeroes));
+
+ req_lib_cfg_get_node_addrs.header.size = sizeof (req_lib_cfg_get_node_addrs);
+ req_lib_cfg_get_node_addrs.header.id = MESSAGE_REQ_CFG_GET_NODE_ADDRS;
+ req_lib_cfg_get_node_addrs.nodeid = nodeid;
+
+ iov.iov_base = (char *)&req_lib_cfg_get_node_addrs;
+ iov.iov_len = sizeof (req_lib_cfg_get_node_addrs);
+
+ error = qb_to_cs_error (qb_ipcc_sendv_recv (
+ cfg_inst->c,
+ &iov, 1,
+ response_buf, IPC_RESPONSE_SIZE, CS_IPC_TIMEOUT_MS));
+ res_lib_cfg_get_node_addrs = (struct res_lib_cfg_get_node_addrs *)response_buf;
+
+ if (error != CS_OK) {
+ goto error_put;
+ }
+
+ if (res_lib_cfg_get_node_addrs->family == AF_INET)
+ addrlen = sizeof(struct sockaddr_in);
+ if (res_lib_cfg_get_node_addrs->family == AF_INET6)
+ addrlen = sizeof(struct sockaddr_in6);
+
+ for (i = 0, addr_buf = (char *)res_lib_cfg_get_node_addrs->addrs;
+ i < max_addrs && i<res_lib_cfg_get_node_addrs->num_addrs;
+ i++, addr_buf += TOTEMIP_ADDRLEN) {
+ struct sockaddr_in *in;
+ struct sockaddr_in6 *in6;
+
+ addrs[i].address_length = addrlen;
+
+ if (res_lib_cfg_get_node_addrs->family == AF_INET) {
+ in = (struct sockaddr_in *)addrs[i].address;
+ if (memcmp(addr_buf, zeroes, addrlen) == 0) {
+ in->sin_family = 0;
+ } else {
+ in->sin_family = AF_INET;
+ }
+ memcpy(&in->sin_addr, addr_buf, sizeof(struct in_addr));
+ }
+ if (res_lib_cfg_get_node_addrs->family == AF_INET6) {
+ in6 = (struct sockaddr_in6 *)addrs[i].address;
+
+ if (memcmp(addr_buf, zeroes, addrlen) == 0) {
+ in6->sin6_family = 0;
+ } else {
+ in6->sin6_family = AF_INET6;
+ }
+ memcpy(&in6->sin6_addr, addr_buf, sizeof(struct in6_addr));
+ }
+
+ /* Mark it as unused */
+
+ }
+ *num_addrs = res_lib_cfg_get_node_addrs->num_addrs;
+ errno = error = res_lib_cfg_get_node_addrs->header.error;
+
+error_put:
+ hdb_handle_put (&cfg_hdb, cfg_handle);
+
+ return (error);
+}
+
+cs_error_t corosync_cfg_local_get (
+ corosync_cfg_handle_t handle,
+ unsigned int *local_nodeid)
+{
+ cs_error_t error;
+ struct cfg_inst *cfg_inst;
+ struct iovec iov;
+ struct req_lib_cfg_local_get req_lib_cfg_local_get;
+ struct res_lib_cfg_local_get res_lib_cfg_local_get;
+
+ error = hdb_error_to_cs(hdb_handle_get (&cfg_hdb, handle, (void *)&cfg_inst));
+ if (error != CS_OK) {
+ return (error);
+ }
+
+ req_lib_cfg_local_get.header.size = sizeof (struct qb_ipc_request_header);
+ req_lib_cfg_local_get.header.id = MESSAGE_REQ_CFG_LOCAL_GET;
+
+ iov.iov_base = (void *)&req_lib_cfg_local_get;
+ iov.iov_len = sizeof (struct req_lib_cfg_local_get);
+
+ error = qb_to_cs_error (qb_ipcc_sendv_recv (
+ cfg_inst->c,
+ &iov,
+ 1,
+ &res_lib_cfg_local_get,
+ sizeof (struct res_lib_cfg_local_get), CS_IPC_TIMEOUT_MS));
+
+ if (error != CS_OK) {
+ goto error_exit;
+ }
+
+ error = res_lib_cfg_local_get.header.error;
+
+ *local_nodeid = res_lib_cfg_local_get.local_nodeid;
+
+error_exit:
+ (void)hdb_handle_put (&cfg_hdb, handle);
+
+ return (error);
+}
+
+cs_error_t corosync_cfg_reload_config (
+ corosync_cfg_handle_t handle)
+{
+ cs_error_t error;
+ struct cfg_inst *cfg_inst;
+ struct iovec iov;
+ struct req_lib_cfg_reload_config req_lib_cfg_reload_config;
+ struct res_lib_cfg_reload_config res_lib_cfg_reload_config;
+
+ error = hdb_error_to_cs(hdb_handle_get (&cfg_hdb, handle, (void *)&cfg_inst));
+ if (error != CS_OK) {
+ return (error);
+ }
+
+ req_lib_cfg_reload_config.header.size = sizeof (struct qb_ipc_request_header);
+ req_lib_cfg_reload_config.header.id = MESSAGE_REQ_CFG_RELOAD_CONFIG;
+
+ iov.iov_base = (void *)&req_lib_cfg_reload_config;
+ iov.iov_len = sizeof (struct req_lib_cfg_reload_config);
+
+ error = qb_to_cs_error (qb_ipcc_sendv_recv (
+ cfg_inst->c,
+ &iov,
+ 1,
+ &res_lib_cfg_reload_config,
+ sizeof (struct res_lib_cfg_reload_config), CS_IPC_TIMEOUT_MS));
+
+ if (error != CS_OK) {
+ goto error_exit;
+ }
+
+ error = res_lib_cfg_reload_config.header.error;
+
+error_exit:
+ (void)hdb_handle_put (&cfg_hdb, handle);
+
+ return (error);
+}
+
+cs_error_t corosync_cfg_reopen_log_files (
+ corosync_cfg_handle_t handle)
+{
+ cs_error_t error;
+ struct cfg_inst *cfg_inst;
+ struct iovec iov;
+ struct req_lib_cfg_reopen_log_files req_lib_cfg_reopen_log_files;
+ struct res_lib_cfg_reopen_log_files res_lib_cfg_reopen_log_files;
+
+ error = hdb_error_to_cs(hdb_handle_get (&cfg_hdb, handle, (void *)&cfg_inst));
+ if (error != CS_OK) {
+ return (error);
+ }
+
+ req_lib_cfg_reopen_log_files.header.size = sizeof (struct qb_ipc_request_header);
+ req_lib_cfg_reopen_log_files.header.id = MESSAGE_REQ_CFG_REOPEN_LOG_FILES;
+
+ iov.iov_base = (void *)&req_lib_cfg_reopen_log_files;
+ iov.iov_len = sizeof (struct req_lib_cfg_reopen_log_files);
+
+ error = qb_to_cs_error (qb_ipcc_sendv_recv (
+ cfg_inst->c,
+ &iov,
+ 1,
+ &res_lib_cfg_reopen_log_files,
+ sizeof (struct res_lib_cfg_reopen_log_files), CS_IPC_TIMEOUT_MS));
+
+ if (error != CS_OK) {
+ goto error_exit;
+ }
+
+ error = res_lib_cfg_reopen_log_files.header.error;
+
+error_exit:
+ (void)hdb_handle_put (&cfg_hdb, handle);
+
+ return (error);
+}
diff --git a/lib/cmap.c b/lib/cmap.c
new file mode 100644
index 0000000..ed9774a
--- /dev/null
+++ b/lib/cmap.c
@@ -0,0 +1,1119 @@
+/*
+ * Copyright (c) 2011-2017 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Author: Jan Friesse (jfriesse@redhat.com)
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of the Red Hat, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <pthread.h>
+#include <sys/types.h>
+#include <sys/uio.h>
+#include <errno.h>
+
+#include <corosync/corotypes.h>
+#include <corosync/corodefs.h>
+#include <corosync/hdb.h>
+#include <qb/qbipcc.h>
+
+#include <corosync/cmap.h>
+#include <corosync/ipc_cmap.h>
+
+#include "util.h"
+#include <stdio.h>
+
+struct cmap_inst {
+ int finalize;
+ qb_ipcc_connection_t *c;
+ const void *context;
+};
+
+struct cmap_track_inst {
+ void *user_data;
+ cmap_notify_fn_t notify_fn;
+ qb_ipcc_connection_t *c;
+ cmap_track_handle_t track_handle;
+};
+
+static void cmap_inst_free (void *inst);
+
+DECLARE_HDB_DATABASE(cmap_handle_t_db, cmap_inst_free);
+DECLARE_HDB_DATABASE(cmap_track_handle_t_db,NULL);
+
+/*
+ * Function prototypes
+ */
+static cs_error_t cmap_get_int(
+ cmap_handle_t handle,
+ const char *key_name,
+ void *value,
+ size_t value_size,
+ cmap_value_types_t type);
+
+static cs_error_t cmap_adjust_int(cmap_handle_t handle, const char *key_name, int32_t step);
+
+/*
+ * Function implementations
+ */
+cs_error_t cmap_initialize (cmap_handle_t *handle)
+{
+ cs_error_t error;
+ struct cmap_inst *cmap_inst;
+
+ error = hdb_error_to_cs(hdb_handle_create(&cmap_handle_t_db, sizeof(*cmap_inst), handle));
+ if (error != CS_OK) {
+ goto error_no_destroy;
+ }
+
+ error = hdb_error_to_cs(hdb_handle_get(&cmap_handle_t_db, *handle, (void *)&cmap_inst));
+ if (error != CS_OK) {
+ goto error_destroy;
+ }
+
+ error = CS_OK;
+ cmap_inst->finalize = 0;
+ cmap_inst->c = qb_ipcc_connect("cmap", IPC_REQUEST_SIZE);
+ if (cmap_inst->c == NULL) {
+ error = qb_to_cs_error(-errno);
+ goto error_put_destroy;
+ }
+
+ (void)hdb_handle_put(&cmap_handle_t_db, *handle);
+
+ return (CS_OK);
+
+error_put_destroy:
+ (void)hdb_handle_put(&cmap_handle_t_db, *handle);
+error_destroy:
+ (void)hdb_handle_destroy(&cmap_handle_t_db, *handle);
+error_no_destroy:
+ return (error);
+}
+
+cs_error_t cmap_initialize_map (cmap_handle_t *handle,
+ cmap_map_t map)
+{
+ cs_error_t error;
+ struct iovec iov[1];
+ struct cmap_inst *cmap_inst;
+ struct req_lib_cmap_set_current_map req_lib_cmap_set_current_map;
+ struct qb_ipc_response_header res_lib_cmap_set_current_map;
+
+ error = cmap_initialize(handle);
+
+ if (error == CS_OK) {
+ error = hdb_error_to_cs(hdb_handle_get (&cmap_handle_t_db, *handle, (void *)&cmap_inst));
+ if (error != CS_OK) {
+ return (error);
+ }
+
+ memset(&req_lib_cmap_set_current_map, 0, sizeof(req_lib_cmap_set_current_map));
+ req_lib_cmap_set_current_map.header.size = sizeof(req_lib_cmap_set_current_map);
+ req_lib_cmap_set_current_map.header.id = MESSAGE_REQ_CMAP_SET_CURRENT_MAP;
+ req_lib_cmap_set_current_map.map = map;
+
+ iov[0].iov_base = (char *)&req_lib_cmap_set_current_map;
+ iov[0].iov_len = sizeof(req_lib_cmap_set_current_map);
+
+ error = qb_to_cs_error(qb_ipcc_sendv_recv(
+ cmap_inst->c,
+ iov,
+ 1,
+ &res_lib_cmap_set_current_map,
+ sizeof (res_lib_cmap_set_current_map), CS_IPC_TIMEOUT_MS));
+
+ if (error == CS_OK) {
+ error = res_lib_cmap_set_current_map.error;
+ }
+
+ (void)hdb_handle_put (&cmap_handle_t_db, *handle);
+
+ return (error);
+ }
+ return (error);
+}
+
+static void cmap_inst_free (void *inst)
+{
+ struct cmap_inst *cmap_inst = (struct cmap_inst *)inst;
+ qb_ipcc_disconnect(cmap_inst->c);
+}
+
+cs_error_t cmap_finalize(cmap_handle_t handle)
+{
+ struct cmap_inst *cmap_inst;
+ cs_error_t error;
+ hdb_handle_t track_inst_handle = 0;
+ struct cmap_track_inst *cmap_track_inst;
+
+ error = hdb_error_to_cs(hdb_handle_get(&cmap_handle_t_db, handle, (void *)&cmap_inst));
+ if (error != CS_OK) {
+ return (error);
+ }
+
+ if (cmap_inst->finalize) {
+ (void)hdb_handle_put (&cmap_handle_t_db, handle);
+ return (CS_ERR_BAD_HANDLE);
+ }
+ cmap_inst->finalize = 1;
+
+ /*
+ * Destroy all track instances for given connection
+ */
+ hdb_iterator_reset(&cmap_track_handle_t_db);
+ while (hdb_iterator_next(&cmap_track_handle_t_db,
+ (void*)&cmap_track_inst, &track_inst_handle) == 0) {
+
+ if (cmap_track_inst->c == cmap_inst->c) {
+ (void)hdb_handle_destroy(&cmap_track_handle_t_db, track_inst_handle);
+ }
+
+ (void)hdb_handle_put (&cmap_track_handle_t_db, track_inst_handle);
+ }
+
+ (void)hdb_handle_destroy(&cmap_handle_t_db, handle);
+
+ (void)hdb_handle_put(&cmap_handle_t_db, handle);
+
+ return (CS_OK);
+}
+
+cs_error_t cmap_fd_get(cmap_handle_t handle, int *fd)
+{
+ cs_error_t error;
+ struct cmap_inst *cmap_inst;
+
+ error = hdb_error_to_cs(hdb_handle_get (&cmap_handle_t_db, handle, (void *)&cmap_inst));
+ if (error != CS_OK) {
+ return (error);
+ }
+
+ error = qb_to_cs_error (qb_ipcc_fd_get (cmap_inst->c, fd));
+
+ (void)hdb_handle_put (&cmap_handle_t_db, handle);
+
+ return (error);
+}
+
+cs_error_t cmap_dispatch (
+ cmap_handle_t handle,
+ cs_dispatch_flags_t dispatch_types)
+{
+ int timeout = -1;
+ cs_error_t error;
+ int cont = 1; /* always continue do loop except when set to 0 */
+ struct cmap_inst *cmap_inst;
+ struct qb_ipc_response_header *dispatch_data;
+ char dispatch_buf[IPC_DISPATCH_SIZE];
+ struct res_lib_cmap_notify_callback *res_lib_cmap_notify_callback;
+ struct cmap_track_inst *cmap_track_inst;
+ struct cmap_notify_value old_val;
+ struct cmap_notify_value new_val;
+
+ error = hdb_error_to_cs(hdb_handle_get (&cmap_handle_t_db, handle, (void *)&cmap_inst));
+ if (error != CS_OK) {
+ return (error);
+ }
+
+ /*
+ * Timeout instantly for CS_DISPATCH_ONE_NONBLOCKING or CS_DISPATCH_ALL and
+ * wait indefinately for CS_DISPATCH_ONE or CS_DISPATCH_BLOCKING
+ */
+ if (dispatch_types == CS_DISPATCH_ALL || dispatch_types == CS_DISPATCH_ONE_NONBLOCKING) {
+ timeout = 0;
+ }
+
+ dispatch_data = (struct qb_ipc_response_header *)dispatch_buf;
+ do {
+ error = qb_to_cs_error(qb_ipcc_event_recv (
+ cmap_inst->c,
+ dispatch_buf,
+ IPC_DISPATCH_SIZE,
+ timeout));
+
+ if (error == CS_ERR_BAD_HANDLE) {
+ error = CS_OK;
+ goto error_put;
+ }
+ if (error == CS_ERR_TRY_AGAIN) {
+ if (dispatch_types == CS_DISPATCH_ONE_NONBLOCKING) {
+ /*
+ * Don't mask error
+ */
+ goto error_put;
+ }
+ error = CS_OK;
+ if (dispatch_types == CS_DISPATCH_ALL) {
+ break; /* exit do while cont is 1 loop */
+ } else {
+ continue; /* next poll */
+ }
+ }
+
+ if (error != CS_OK) {
+ goto error_put;
+ }
+
+ /*
+ * Dispatch incoming message
+ */
+ switch (dispatch_data->id) {
+ case MESSAGE_RES_CMAP_NOTIFY_CALLBACK:
+ res_lib_cmap_notify_callback = (struct res_lib_cmap_notify_callback *)dispatch_data;
+
+ error = hdb_error_to_cs(hdb_handle_get(&cmap_track_handle_t_db,
+ res_lib_cmap_notify_callback->track_inst_handle,
+ (void *)&cmap_track_inst));
+ if (error == CS_ERR_BAD_HANDLE) {
+ /*
+ * User deleted tracker -> ignore error
+ */
+ break;
+ }
+ if (error != CS_OK) {
+ goto error_put;
+ }
+
+ new_val.type = res_lib_cmap_notify_callback->new_value_type;
+ old_val.type = res_lib_cmap_notify_callback->old_value_type;
+ new_val.len = res_lib_cmap_notify_callback->new_value_len;
+ old_val.len = res_lib_cmap_notify_callback->old_value_len;
+ new_val.data = res_lib_cmap_notify_callback->new_value;
+ old_val.data = (((const char *)res_lib_cmap_notify_callback->new_value) + new_val.len);
+
+ cmap_track_inst->notify_fn(handle,
+ cmap_track_inst->track_handle,
+ res_lib_cmap_notify_callback->event,
+ (char *)res_lib_cmap_notify_callback->key_name.value,
+ new_val,
+ old_val,
+ cmap_track_inst->user_data);
+
+ (void)hdb_handle_put(&cmap_track_handle_t_db, res_lib_cmap_notify_callback->track_inst_handle);
+ break;
+ default:
+ error = CS_ERR_LIBRARY;
+ goto error_put;
+ break;
+ }
+ if (cmap_inst->finalize) {
+ /*
+ * If the finalize has been called then get out of the dispatch.
+ */
+ error = CS_ERR_BAD_HANDLE;
+ goto error_put;
+ }
+
+ /*
+ * Determine if more messages should be processed
+ */
+ if (dispatch_types == CS_DISPATCH_ONE || dispatch_types == CS_DISPATCH_ONE_NONBLOCKING) {
+ cont = 0;
+ }
+ } while (cont);
+
+error_put:
+ (void)hdb_handle_put (&cmap_handle_t_db, handle);
+
+ return (error);
+}
+
+cs_error_t cmap_context_get (
+ cmap_handle_t handle,
+ const void **context)
+{
+ cs_error_t error;
+ struct cmap_inst *cmap_inst;
+
+ error = hdb_error_to_cs(hdb_handle_get(&cmap_handle_t_db, handle, (void *)&cmap_inst));
+ if (error != CS_OK) {
+ return (error);
+ }
+
+ *context = cmap_inst->context;
+
+ (void)hdb_handle_put (&cmap_handle_t_db, handle);
+
+ return (CS_OK);
+}
+
+cs_error_t cmap_context_set (
+ cmap_handle_t handle,
+ const void *context)
+{
+ cs_error_t error;
+ struct cmap_inst *cmap_inst;
+
+ error = hdb_error_to_cs(hdb_handle_get (&cmap_handle_t_db, handle, (void *)&cmap_inst));
+ if (error != CS_OK) {
+ return (error);
+ }
+
+ cmap_inst->context = context;
+
+ (void)hdb_handle_put (&cmap_handle_t_db, handle);
+
+ return (CS_OK);
+}
+
+cs_error_t cmap_set (
+ cmap_handle_t handle,
+ const char *key_name,
+ const void *value,
+ size_t value_len,
+ cmap_value_types_t type)
+{
+ cs_error_t error;
+ struct iovec iov[2];
+ struct cmap_inst *cmap_inst;
+ struct req_lib_cmap_set req_lib_cmap_set;
+ struct res_lib_cmap_set res_lib_cmap_set;
+
+ if (key_name == NULL || value == NULL) {
+ return (CS_ERR_INVALID_PARAM);
+ }
+
+ if (strlen(key_name) >= CS_MAX_NAME_LENGTH) {
+ return (CS_ERR_NAME_TOO_LONG);
+ }
+
+ error = hdb_error_to_cs(hdb_handle_get (&cmap_handle_t_db, handle, (void *)&cmap_inst));
+ if (error != CS_OK) {
+ return (error);
+ }
+
+ memset(&req_lib_cmap_set, 0, sizeof(req_lib_cmap_set));
+ req_lib_cmap_set.header.size = sizeof(req_lib_cmap_set) + value_len;
+ req_lib_cmap_set.header.id = MESSAGE_REQ_CMAP_SET;
+
+ memcpy(req_lib_cmap_set.key_name.value, key_name, strlen(key_name));
+ req_lib_cmap_set.key_name.length = strlen(key_name);
+
+ req_lib_cmap_set.value_len = value_len;
+ req_lib_cmap_set.type = type;
+
+ iov[0].iov_base = (char *)&req_lib_cmap_set;
+ iov[0].iov_len = sizeof(req_lib_cmap_set);
+ iov[1].iov_base = (void *)value;
+ iov[1].iov_len = value_len;
+
+ error = qb_to_cs_error(qb_ipcc_sendv_recv(
+ cmap_inst->c,
+ iov,
+ 2,
+ &res_lib_cmap_set,
+ sizeof (struct res_lib_cmap_set), CS_IPC_TIMEOUT_MS));
+
+ if (error == CS_OK) {
+ error = res_lib_cmap_set.header.error;
+ }
+
+ (void)hdb_handle_put (&cmap_handle_t_db, handle);
+
+ return (error);
+}
+
+cs_error_t cmap_set_int8(cmap_handle_t handle, const char *key_name, int8_t value)
+{
+ return (cmap_set(handle, key_name, &value, sizeof(value), CMAP_VALUETYPE_INT8));
+}
+
+cs_error_t cmap_set_uint8(cmap_handle_t handle, const char *key_name, uint8_t value)
+{
+ return (cmap_set(handle, key_name, &value, sizeof(value), CMAP_VALUETYPE_UINT8));
+}
+
+cs_error_t cmap_set_int16(cmap_handle_t handle, const char *key_name, int16_t value)
+{
+ return (cmap_set(handle, key_name, &value, sizeof(value), CMAP_VALUETYPE_INT16));
+}
+
+cs_error_t cmap_set_uint16(cmap_handle_t handle, const char *key_name, uint16_t value)
+{
+ return (cmap_set(handle, key_name, &value, sizeof(value), CMAP_VALUETYPE_UINT16));
+}
+
+cs_error_t cmap_set_int32(cmap_handle_t handle, const char *key_name, int32_t value)
+{
+ return (cmap_set(handle, key_name, &value, sizeof(value), CMAP_VALUETYPE_INT32));
+}
+
+cs_error_t cmap_set_uint32(cmap_handle_t handle, const char *key_name, uint32_t value)
+{
+ return (cmap_set(handle, key_name, &value, sizeof(value), CMAP_VALUETYPE_UINT32));
+}
+
+cs_error_t cmap_set_int64(cmap_handle_t handle, const char *key_name, int64_t value)
+{
+ return (cmap_set(handle, key_name, &value, sizeof(value), CMAP_VALUETYPE_INT64));
+}
+
+cs_error_t cmap_set_uint64(cmap_handle_t handle, const char *key_name, uint64_t value)
+{
+ return (cmap_set(handle, key_name, &value, sizeof(value), CMAP_VALUETYPE_UINT64));
+}
+
+cs_error_t cmap_set_float(cmap_handle_t handle, const char *key_name, float value)
+{
+ return (cmap_set(handle, key_name, &value, sizeof(value), CMAP_VALUETYPE_FLOAT));
+}
+
+cs_error_t cmap_set_double(cmap_handle_t handle, const char *key_name, double value)
+{
+ return (cmap_set(handle, key_name, &value, sizeof(value), CMAP_VALUETYPE_DOUBLE));
+}
+
+cs_error_t cmap_set_string(cmap_handle_t handle, const char *key_name, const char *value)
+{
+
+ if (value == NULL) {
+ return (CS_ERR_INVALID_PARAM);
+ }
+
+ return (cmap_set(handle, key_name, value, strlen(value), CMAP_VALUETYPE_STRING));
+}
+
+cs_error_t cmap_delete(cmap_handle_t handle, const char *key_name)
+{
+ cs_error_t error;
+ struct iovec iov;
+ struct cmap_inst *cmap_inst;
+ struct req_lib_cmap_delete req_lib_cmap_delete;
+ struct res_lib_cmap_delete res_lib_cmap_delete;
+
+ if (key_name == NULL) {
+ return (CS_ERR_INVALID_PARAM);
+ }
+ if (strlen(key_name) >= CS_MAX_NAME_LENGTH) {
+ return (CS_ERR_NAME_TOO_LONG);
+ }
+
+ error = hdb_error_to_cs(hdb_handle_get (&cmap_handle_t_db, handle, (void *)&cmap_inst));
+ if (error != CS_OK) {
+ return (error);
+ }
+
+ memset(&req_lib_cmap_delete, 0, sizeof(req_lib_cmap_delete));
+ req_lib_cmap_delete.header.size = sizeof(req_lib_cmap_delete);
+ req_lib_cmap_delete.header.id = MESSAGE_REQ_CMAP_DELETE;
+
+ memcpy(req_lib_cmap_delete.key_name.value, key_name, strlen(key_name));
+ req_lib_cmap_delete.key_name.length = strlen(key_name);
+
+ iov.iov_base = (char *)&req_lib_cmap_delete;
+ iov.iov_len = sizeof(req_lib_cmap_delete);
+
+ error = qb_to_cs_error(qb_ipcc_sendv_recv(
+ cmap_inst->c,
+ &iov,
+ 1,
+ &res_lib_cmap_delete,
+ sizeof (struct res_lib_cmap_delete), CS_IPC_TIMEOUT_MS));
+
+ if (error == CS_OK) {
+ error = res_lib_cmap_delete.header.error;
+ }
+
+ (void)hdb_handle_put (&cmap_handle_t_db, handle);
+
+ return (error);
+}
+
+cs_error_t cmap_get(
+ cmap_handle_t handle,
+ const char *key_name,
+ void *value,
+ size_t *value_len,
+ cmap_value_types_t *type)
+{
+ cs_error_t error;
+ struct cmap_inst *cmap_inst;
+ struct iovec iov;
+ struct req_lib_cmap_get req_lib_cmap_get;
+ struct res_lib_cmap_get *res_lib_cmap_get;
+ size_t res_size;
+
+ if (key_name == NULL) {
+ return (CS_ERR_INVALID_PARAM);
+ }
+ if (strlen(key_name) >= CS_MAX_NAME_LENGTH) {
+ return (CS_ERR_NAME_TOO_LONG);
+ }
+
+ if (value != NULL && value_len == NULL) {
+ return (CS_ERR_INVALID_PARAM);
+ }
+
+ error = hdb_error_to_cs(hdb_handle_get (&cmap_handle_t_db, handle, (void *)&cmap_inst));
+ if (error != CS_OK) {
+ return (error);
+ }
+
+ memset(&req_lib_cmap_get, 0, sizeof(req_lib_cmap_get));
+ req_lib_cmap_get.header.size = sizeof(req_lib_cmap_get);
+ req_lib_cmap_get.header.id = MESSAGE_REQ_CMAP_GET;
+
+ memcpy(req_lib_cmap_get.key_name.value, key_name, strlen(key_name));
+ req_lib_cmap_get.key_name.length = strlen(key_name);
+
+ if (value != NULL && value_len != NULL) {
+ req_lib_cmap_get.value_len = *value_len;
+ } else {
+ req_lib_cmap_get.value_len = 0;
+ }
+
+ iov.iov_base = (char *)&req_lib_cmap_get;
+ iov.iov_len = sizeof(req_lib_cmap_get);
+
+ res_size = sizeof(struct res_lib_cmap_get) + req_lib_cmap_get.value_len;
+
+ res_lib_cmap_get = malloc(res_size);
+ if (res_lib_cmap_get == NULL) {
+ return (CS_ERR_NO_MEMORY);
+ }
+
+ error = qb_to_cs_error(qb_ipcc_sendv_recv(
+ cmap_inst->c,
+ &iov,
+ 1,
+ res_lib_cmap_get,
+ res_size, CS_IPC_TIMEOUT_MS));
+
+ if (error == CS_OK) {
+ error = res_lib_cmap_get->header.error;
+ }
+
+ if (error == CS_OK) {
+ if (type != NULL) {
+ *type = res_lib_cmap_get->type;
+ }
+
+ if (value_len != NULL) {
+ *value_len = res_lib_cmap_get->value_len;
+ }
+
+ if (value != NULL && value_len != NULL) {
+ memcpy(value, res_lib_cmap_get->value, res_lib_cmap_get->value_len);
+ }
+ }
+
+ free(res_lib_cmap_get);
+
+ (void)hdb_handle_put (&cmap_handle_t_db, handle);
+
+ return (error);
+}
+
+static cs_error_t cmap_get_int(
+ cmap_handle_t handle,
+ const char *key_name,
+ void *value,
+ size_t value_size,
+ cmap_value_types_t type)
+{
+ char key_value[16];
+ size_t key_size;
+ cs_error_t err;
+
+ cmap_value_types_t key_type;
+
+ key_size = sizeof(key_value);
+ memset(key_value, 0, key_size);
+
+ err = cmap_get(handle, key_name, key_value, &key_size, &key_type);
+ if (err != CS_OK)
+ return (err);
+
+ if (key_type != type) {
+ return (CS_ERR_INVALID_PARAM);
+ }
+
+ memcpy(value, key_value, value_size);
+
+ return (CS_OK);
+}
+
+cs_error_t cmap_get_int8(cmap_handle_t handle, const char *key_name, int8_t *i8)
+{
+
+ return (cmap_get_int(handle, key_name, i8, sizeof(*i8), CMAP_VALUETYPE_INT8));
+}
+
+cs_error_t cmap_get_uint8(cmap_handle_t handle, const char *key_name, uint8_t *u8)
+{
+
+ return (cmap_get_int(handle, key_name, u8, sizeof(*u8), CMAP_VALUETYPE_UINT8));
+}
+
+cs_error_t cmap_get_int16(cmap_handle_t handle, const char *key_name, int16_t *i16)
+{
+
+ return (cmap_get_int(handle, key_name, i16, sizeof(*i16), CMAP_VALUETYPE_INT16));
+}
+
+cs_error_t cmap_get_uint16(cmap_handle_t handle, const char *key_name, uint16_t *u16)
+{
+
+ return (cmap_get_int(handle, key_name, u16, sizeof(*u16), CMAP_VALUETYPE_UINT16));
+}
+
+cs_error_t cmap_get_int32(cmap_handle_t handle, const char *key_name, int32_t *i32)
+{
+
+ return (cmap_get_int(handle, key_name, i32, sizeof(*i32), CMAP_VALUETYPE_INT32));
+}
+
+cs_error_t cmap_get_uint32(cmap_handle_t handle, const char *key_name, uint32_t *u32)
+{
+
+ return (cmap_get_int(handle, key_name, u32, sizeof(*u32), CMAP_VALUETYPE_UINT32));
+}
+
+cs_error_t cmap_get_int64(cmap_handle_t handle, const char *key_name, int64_t *i64)
+{
+
+ return (cmap_get_int(handle, key_name, i64, sizeof(*i64), CMAP_VALUETYPE_INT64));
+}
+
+cs_error_t cmap_get_uint64(cmap_handle_t handle, const char *key_name, uint64_t *u64)
+{
+
+ return (cmap_get_int(handle, key_name, u64, sizeof(*u64), CMAP_VALUETYPE_UINT64));
+}
+
+cs_error_t cmap_get_float(cmap_handle_t handle, const char *key_name, float *flt)
+{
+
+ return (cmap_get_int(handle, key_name, flt, sizeof(*flt), CMAP_VALUETYPE_FLOAT));
+}
+
+cs_error_t cmap_get_double(cmap_handle_t handle, const char *key_name, double *dbl)
+{
+
+ return (cmap_get_int(handle, key_name, dbl, sizeof(*dbl), CMAP_VALUETYPE_DOUBLE));
+}
+
+cs_error_t cmap_get_string(cmap_handle_t handle, const char *key_name, char **str)
+{
+ cs_error_t res;
+ size_t str_len;
+ cmap_value_types_t type;
+
+ res = cmap_get(handle, key_name, NULL, &str_len, &type);
+
+ if (res != CS_OK || type != CMAP_VALUETYPE_STRING) {
+ if (res == CS_OK) {
+ res = CS_ERR_INVALID_PARAM;
+ }
+
+ goto return_error;
+ }
+
+ *str = malloc(str_len);
+ if (*str == NULL) {
+ res = CS_ERR_NO_MEMORY;
+
+ goto return_error;
+ }
+
+ res = cmap_get(handle, key_name, *str, &str_len, &type);
+ if (res != CS_OK) {
+ free(*str);
+
+ goto return_error;
+ }
+
+ return (CS_OK);
+
+return_error:
+ return (res);
+}
+
+static cs_error_t cmap_adjust_int(cmap_handle_t handle, const char *key_name, int32_t step)
+{
+ cs_error_t error;
+ struct iovec iov;
+ struct cmap_inst *cmap_inst;
+ struct req_lib_cmap_adjust_int req_lib_cmap_adjust_int;
+ struct res_lib_cmap_adjust_int res_lib_cmap_adjust_int;
+
+ if (key_name == NULL) {
+ return (CS_ERR_INVALID_PARAM);
+ }
+ if (strlen(key_name) >= CS_MAX_NAME_LENGTH) {
+ return (CS_ERR_NAME_TOO_LONG);
+ }
+
+ error = hdb_error_to_cs(hdb_handle_get (&cmap_handle_t_db, handle, (void *)&cmap_inst));
+ if (error != CS_OK) {
+ return (error);
+ }
+
+ memset(&req_lib_cmap_adjust_int, 0, sizeof(req_lib_cmap_adjust_int));
+ req_lib_cmap_adjust_int.header.size = sizeof(req_lib_cmap_adjust_int);
+ req_lib_cmap_adjust_int.header.id = MESSAGE_REQ_CMAP_ADJUST_INT;
+
+ memcpy(req_lib_cmap_adjust_int.key_name.value, key_name, strlen(key_name));
+ req_lib_cmap_adjust_int.key_name.length = strlen(key_name);
+
+ req_lib_cmap_adjust_int.step = step;
+
+ iov.iov_base = (char *)&req_lib_cmap_adjust_int;
+ iov.iov_len = sizeof(req_lib_cmap_adjust_int);
+
+ error = qb_to_cs_error(qb_ipcc_sendv_recv(
+ cmap_inst->c,
+ &iov,
+ 1,
+ &res_lib_cmap_adjust_int,
+ sizeof (struct res_lib_cmap_adjust_int), CS_IPC_TIMEOUT_MS));
+
+ if (error == CS_OK) {
+ error = res_lib_cmap_adjust_int.header.error;
+ }
+
+ (void)hdb_handle_put (&cmap_handle_t_db, handle);
+
+ return (error);
+}
+
+cs_error_t cmap_inc(cmap_handle_t handle, const char *key_name)
+{
+
+ return (cmap_adjust_int(handle, key_name, 1));
+}
+
+cs_error_t cmap_dec(cmap_handle_t handle, const char *key_name)
+{
+
+ return (cmap_adjust_int(handle, key_name, -1));
+}
+
+cs_error_t cmap_iter_init(
+ cmap_handle_t handle,
+ const char *prefix,
+ cmap_iter_handle_t *cmap_iter_handle)
+{
+ cs_error_t error;
+ struct iovec iov;
+ struct cmap_inst *cmap_inst;
+ struct req_lib_cmap_iter_init req_lib_cmap_iter_init;
+ struct res_lib_cmap_iter_init res_lib_cmap_iter_init;
+
+ if (cmap_iter_handle == NULL) {
+ return (CS_ERR_INVALID_PARAM);
+ }
+
+ error = hdb_error_to_cs(hdb_handle_get (&cmap_handle_t_db, handle, (void *)&cmap_inst));
+ if (error != CS_OK) {
+ return (error);
+ }
+
+ memset(&req_lib_cmap_iter_init, 0, sizeof(req_lib_cmap_iter_init));
+ req_lib_cmap_iter_init.header.size = sizeof(req_lib_cmap_iter_init);
+ req_lib_cmap_iter_init.header.id = MESSAGE_REQ_CMAP_ITER_INIT;
+
+ if (prefix) {
+ if (strlen(prefix) >= CS_MAX_NAME_LENGTH) {
+ return (CS_ERR_NAME_TOO_LONG);
+ }
+ memcpy(req_lib_cmap_iter_init.prefix.value, prefix, strlen(prefix));
+ req_lib_cmap_iter_init.prefix.length = strlen(prefix);
+ }
+
+ iov.iov_base = (char *)&req_lib_cmap_iter_init;
+ iov.iov_len = sizeof(req_lib_cmap_iter_init);
+
+ error = qb_to_cs_error(qb_ipcc_sendv_recv(
+ cmap_inst->c,
+ &iov,
+ 1,
+ &res_lib_cmap_iter_init,
+ sizeof (struct res_lib_cmap_iter_init), CS_IPC_TIMEOUT_MS));
+
+ if (error == CS_OK) {
+ error = res_lib_cmap_iter_init.header.error;
+ }
+
+ if (error == CS_OK) {
+ *cmap_iter_handle = res_lib_cmap_iter_init.iter_handle;
+ }
+
+ (void)hdb_handle_put (&cmap_handle_t_db, handle);
+
+ return (error);
+}
+
+cs_error_t cmap_iter_next(
+ cmap_handle_t handle,
+ cmap_iter_handle_t iter_handle,
+ char key_name[],
+ size_t *value_len,
+ cmap_value_types_t *type)
+{
+ cs_error_t error;
+ struct iovec iov;
+ struct cmap_inst *cmap_inst;
+ struct req_lib_cmap_iter_next req_lib_cmap_iter_next;
+ struct res_lib_cmap_iter_next res_lib_cmap_iter_next;
+
+ if (key_name == NULL) {
+ return (CS_ERR_INVALID_PARAM);
+ }
+
+ error = hdb_error_to_cs(hdb_handle_get (&cmap_handle_t_db, handle, (void *)&cmap_inst));
+ if (error != CS_OK) {
+ return (error);
+ }
+
+ memset(&req_lib_cmap_iter_next, 0, sizeof(req_lib_cmap_iter_next));
+ req_lib_cmap_iter_next.header.size = sizeof(req_lib_cmap_iter_next);
+ req_lib_cmap_iter_next.header.id = MESSAGE_REQ_CMAP_ITER_NEXT;
+ req_lib_cmap_iter_next.iter_handle = iter_handle;
+
+ iov.iov_base = (char *)&req_lib_cmap_iter_next;
+ iov.iov_len = sizeof(req_lib_cmap_iter_next);
+
+ error = qb_to_cs_error(qb_ipcc_sendv_recv(
+ cmap_inst->c,
+ &iov,
+ 1,
+ &res_lib_cmap_iter_next,
+ sizeof (struct res_lib_cmap_iter_next), CS_IPC_TIMEOUT_MS));
+
+ if (error == CS_OK) {
+ error = res_lib_cmap_iter_next.header.error;
+ }
+
+ if (error == CS_OK) {
+ memcpy(key_name, (const char *)res_lib_cmap_iter_next.key_name.value,
+ res_lib_cmap_iter_next.key_name.length);
+ key_name[res_lib_cmap_iter_next.key_name.length] = '\0';
+
+ if (value_len != NULL) {
+ *value_len = res_lib_cmap_iter_next.value_len;
+ }
+
+ if (type != NULL) {
+ *type = res_lib_cmap_iter_next.type;
+ }
+ }
+
+ (void)hdb_handle_put (&cmap_handle_t_db, handle);
+
+ return (error);
+}
+
+cs_error_t cmap_iter_finalize(
+ cmap_handle_t handle,
+ cmap_iter_handle_t iter_handle)
+{
+ cs_error_t error;
+ struct iovec iov;
+ struct cmap_inst *cmap_inst;
+ struct req_lib_cmap_iter_finalize req_lib_cmap_iter_finalize;
+ struct res_lib_cmap_iter_finalize res_lib_cmap_iter_finalize;
+
+ error = hdb_error_to_cs(hdb_handle_get (&cmap_handle_t_db, handle, (void *)&cmap_inst));
+ if (error != CS_OK) {
+ return (error);
+ }
+
+ memset(&req_lib_cmap_iter_finalize, 0, sizeof(req_lib_cmap_iter_finalize));
+ req_lib_cmap_iter_finalize.header.size = sizeof(req_lib_cmap_iter_finalize);
+ req_lib_cmap_iter_finalize.header.id = MESSAGE_REQ_CMAP_ITER_FINALIZE;
+ req_lib_cmap_iter_finalize.iter_handle = iter_handle;
+
+ iov.iov_base = (char *)&req_lib_cmap_iter_finalize;
+ iov.iov_len = sizeof(req_lib_cmap_iter_finalize);
+
+ error = qb_to_cs_error(qb_ipcc_sendv_recv(
+ cmap_inst->c,
+ &iov,
+ 1,
+ &res_lib_cmap_iter_finalize,
+ sizeof (struct res_lib_cmap_iter_finalize), CS_IPC_TIMEOUT_MS));
+
+ if (error == CS_OK) {
+ error = res_lib_cmap_iter_finalize.header.error;
+ }
+
+ (void)hdb_handle_put (&cmap_handle_t_db, handle);
+
+ return (error);
+}
+
+cs_error_t cmap_track_add(
+ cmap_handle_t handle,
+ const char *key_name,
+ int32_t track_type,
+ cmap_notify_fn_t notify_fn,
+ void *user_data,
+ cmap_track_handle_t *cmap_track_handle)
+{
+ cs_error_t error;
+ struct iovec iov;
+ struct cmap_inst *cmap_inst;
+ struct req_lib_cmap_track_add req_lib_cmap_track_add;
+ struct res_lib_cmap_track_add res_lib_cmap_track_add;
+ struct cmap_track_inst *cmap_track_inst;
+ cmap_track_handle_t cmap_track_inst_handle;
+
+ if (cmap_track_handle == NULL || notify_fn == NULL) {
+ return (CS_ERR_INVALID_PARAM);
+ }
+
+ error = hdb_error_to_cs(hdb_handle_get (&cmap_handle_t_db, handle, (void *)&cmap_inst));
+ if (error != CS_OK) {
+ return (error);
+ }
+
+ error = hdb_error_to_cs(hdb_handle_create(&cmap_track_handle_t_db,
+ sizeof(*cmap_track_inst), &cmap_track_inst_handle));
+ if (error != CS_OK) {
+ goto error_put;
+ }
+
+ error = hdb_error_to_cs(hdb_handle_get(&cmap_track_handle_t_db,
+ cmap_track_inst_handle, (void *)&cmap_track_inst));
+ if (error != CS_OK) {
+ goto error_put_destroy;
+ }
+
+ cmap_track_inst->user_data = user_data;
+ cmap_track_inst->notify_fn = notify_fn;
+ cmap_track_inst->c = cmap_inst->c;
+
+ memset(&req_lib_cmap_track_add, 0, sizeof(req_lib_cmap_track_add));
+ req_lib_cmap_track_add.header.size = sizeof(req_lib_cmap_track_add);
+ req_lib_cmap_track_add.header.id = MESSAGE_REQ_CMAP_TRACK_ADD;
+
+ if (key_name) {
+ if (strlen(key_name) >= CS_MAX_NAME_LENGTH) {
+ return (CS_ERR_NAME_TOO_LONG);
+ }
+ memcpy(req_lib_cmap_track_add.key_name.value, key_name, strlen(key_name));
+ req_lib_cmap_track_add.key_name.length = strlen(key_name);
+ }
+
+ req_lib_cmap_track_add.track_type = track_type;
+ req_lib_cmap_track_add.track_inst_handle = cmap_track_inst_handle;
+
+ iov.iov_base = (char *)&req_lib_cmap_track_add;
+ iov.iov_len = sizeof(req_lib_cmap_track_add);
+
+ error = qb_to_cs_error(qb_ipcc_sendv_recv(
+ cmap_inst->c,
+ &iov,
+ 1,
+ &res_lib_cmap_track_add,
+ sizeof (struct res_lib_cmap_track_add), CS_IPC_TIMEOUT_MS));
+
+ if (error == CS_OK) {
+ error = res_lib_cmap_track_add.header.error;
+ }
+
+ if (error == CS_OK) {
+ *cmap_track_handle = res_lib_cmap_track_add.track_handle;
+ cmap_track_inst->track_handle = *cmap_track_handle;
+ }
+
+ (void)hdb_handle_put (&cmap_track_handle_t_db, cmap_track_inst_handle);
+
+ (void)hdb_handle_put (&cmap_handle_t_db, handle);
+
+ return (error);
+
+error_put_destroy:
+ (void)hdb_handle_put (&cmap_track_handle_t_db, cmap_track_inst_handle);
+ (void)hdb_handle_destroy (&cmap_track_handle_t_db, cmap_track_inst_handle);
+
+error_put:
+ (void)hdb_handle_put (&cmap_handle_t_db, handle);
+
+ return (error);
+}
+
+cs_error_t cmap_track_delete(
+ cmap_handle_t handle,
+ cmap_track_handle_t track_handle)
+{
+ cs_error_t error;
+ struct iovec iov;
+ struct cmap_inst *cmap_inst;
+ struct cmap_track_inst *cmap_track_inst;
+ struct req_lib_cmap_track_delete req_lib_cmap_track_delete;
+ struct res_lib_cmap_track_delete res_lib_cmap_track_delete;
+
+ error = hdb_error_to_cs(hdb_handle_get (&cmap_handle_t_db, handle, (void *)&cmap_inst));
+ if (error != CS_OK) {
+ return (error);
+ }
+
+ memset(&req_lib_cmap_track_delete, 0, sizeof(req_lib_cmap_track_delete));
+ req_lib_cmap_track_delete.header.size = sizeof(req_lib_cmap_track_delete);
+ req_lib_cmap_track_delete.header.id = MESSAGE_REQ_CMAP_TRACK_DELETE;
+ req_lib_cmap_track_delete.track_handle = track_handle;
+
+ iov.iov_base = (char *)&req_lib_cmap_track_delete;
+ iov.iov_len = sizeof(req_lib_cmap_track_delete);
+
+ error = qb_to_cs_error(qb_ipcc_sendv_recv(
+ cmap_inst->c,
+ &iov,
+ 1,
+ &res_lib_cmap_track_delete,
+ sizeof (struct res_lib_cmap_track_delete), CS_IPC_TIMEOUT_MS));
+
+ if (error == CS_OK) {
+ error = res_lib_cmap_track_delete.header.error;
+ }
+
+ if (error == CS_OK) {
+ error = hdb_error_to_cs(hdb_handle_get(&cmap_track_handle_t_db,
+ res_lib_cmap_track_delete.track_inst_handle,
+ (void *)&cmap_track_inst));
+ if (error != CS_OK) {
+ goto error_put;
+ }
+
+ (void)hdb_handle_put(&cmap_track_handle_t_db, res_lib_cmap_track_delete.track_inst_handle);
+ (void)hdb_handle_destroy(&cmap_track_handle_t_db, res_lib_cmap_track_delete.track_inst_handle);
+ }
+
+error_put:
+ (void)hdb_handle_put (&cmap_handle_t_db, handle);
+
+ return (error);
+}
diff --git a/lib/cpg.c b/lib/cpg.c
new file mode 100644
index 0000000..b41f31d
--- /dev/null
+++ b/lib/cpg.c
@@ -0,0 +1,1426 @@
+/*
+ * vi: set autoindent tabstop=4 shiftwidth=4 :
+ *
+ * Copyright (c) 2006-2015 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Author: Christine Caulfield (ccaulfi@redhat.com)
+ * Author: Jan Friesse (jfriesse@redhat.com)
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of the MontaVista Software, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+/*
+ * Provides a closed process group API using the coroipcc executive
+ */
+
+#include <config.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/mman.h>
+#include <sys/uio.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <limits.h>
+
+#include <qb/qblist.h>
+#include <qb/qbdefs.h>
+#include <qb/qbipcc.h>
+#include <qb/qblog.h>
+
+#include <corosync/hdb.h>
+#include <corosync/corotypes.h>
+#include <corosync/corodefs.h>
+#include <corosync/cpg.h>
+#include <corosync/ipc_cpg.h>
+
+#include "util.h"
+
+#ifndef MAP_ANONYMOUS
+#define MAP_ANONYMOUS MAP_ANON
+#endif
+
+/*
+ * Maximum number of times to retry a send when transmitting
+ * a large message fragment
+ */
+#define MAX_RETRIES 100
+
+/*
+ * ZCB files have following umask (umask is same as used in libqb)
+ */
+#define CPG_MEMORY_MAP_UMASK 077
+
+struct cpg_assembly_data
+{
+ struct qb_list_head list;
+ uint32_t nodeid;
+ uint32_t pid;
+ char *assembly_buf;
+ uint32_t assembly_buf_ptr;
+};
+
+struct cpg_inst {
+ qb_ipcc_connection_t *c;
+ int finalize;
+ void *context;
+ union {
+ cpg_model_data_t model_data;
+ cpg_model_v1_data_t model_v1_data;
+ };
+ struct qb_list_head iteration_list_head;
+ uint32_t max_msg_size;
+ struct qb_list_head assembly_list_head;
+};
+static void cpg_inst_free (void *inst);
+
+DECLARE_HDB_DATABASE(cpg_handle_t_db, cpg_inst_free);
+
+struct cpg_iteration_instance_t {
+ cpg_iteration_handle_t cpg_iteration_handle;
+ qb_ipcc_connection_t *conn;
+ hdb_handle_t executive_iteration_handle;
+ struct qb_list_head list;
+};
+
+DECLARE_HDB_DATABASE(cpg_iteration_handle_t_db,NULL);
+
+
+/*
+ * Internal (not visible by API) functions
+ */
+
+static cs_error_t
+coroipcc_msg_send_reply_receive (
+ qb_ipcc_connection_t *c,
+ const struct iovec *iov,
+ unsigned int iov_len,
+ void *res_msg,
+ size_t res_len)
+{
+ return qb_to_cs_error(qb_ipcc_sendv_recv(c, iov, iov_len, res_msg, res_len,
+ CS_IPC_TIMEOUT_MS));
+}
+
+static void cpg_iteration_instance_finalize (struct cpg_iteration_instance_t *cpg_iteration_instance)
+{
+ qb_list_del (&cpg_iteration_instance->list);
+ hdb_handle_destroy (&cpg_iteration_handle_t_db, cpg_iteration_instance->cpg_iteration_handle);
+}
+
+static void cpg_inst_free (void *inst)
+{
+ struct cpg_inst *cpg_inst = (struct cpg_inst *)inst;
+ qb_ipcc_disconnect(cpg_inst->c);
+}
+
+static void cpg_inst_finalize (struct cpg_inst *cpg_inst, hdb_handle_t handle)
+{
+ struct qb_list_head *iter, *tmp_iter;
+ struct cpg_iteration_instance_t *cpg_iteration_instance;
+
+ /*
+ * Traverse thru iteration instances and delete them
+ */
+ qb_list_for_each_safe(iter, tmp_iter, &(cpg_inst->iteration_list_head)) {
+ cpg_iteration_instance = qb_list_entry (iter, struct cpg_iteration_instance_t, list);
+
+ cpg_iteration_instance_finalize (cpg_iteration_instance);
+ }
+ hdb_handle_destroy (&cpg_handle_t_db, handle);
+}
+
+/**
+ * @defgroup cpg_coroipcc The closed process group API
+ * @ingroup coroipcc
+ *
+ * @{
+ */
+
+cs_error_t cpg_initialize (
+ cpg_handle_t *handle,
+ cpg_callbacks_t *callbacks)
+{
+ cpg_model_v1_data_t model_v1_data;
+
+ memset (&model_v1_data, 0, sizeof (cpg_model_v1_data_t));
+
+ if (callbacks) {
+ model_v1_data.cpg_deliver_fn = callbacks->cpg_deliver_fn;
+ model_v1_data.cpg_confchg_fn = callbacks->cpg_confchg_fn;
+ }
+
+ return (cpg_model_initialize (handle, CPG_MODEL_V1, (cpg_model_data_t *)&model_v1_data, NULL));
+}
+
+cs_error_t cpg_model_initialize (
+ cpg_handle_t *handle,
+ cpg_model_t model,
+ cpg_model_data_t *model_data,
+ void *context)
+{
+ cs_error_t error;
+ struct cpg_inst *cpg_inst;
+
+ if (model != CPG_MODEL_V1) {
+ error = CS_ERR_INVALID_PARAM;
+ goto error_no_destroy;
+ }
+
+ error = hdb_error_to_cs (hdb_handle_create (&cpg_handle_t_db, sizeof (struct cpg_inst), handle));
+ if (error != CS_OK) {
+ goto error_no_destroy;
+ }
+
+ error = hdb_error_to_cs (hdb_handle_get (&cpg_handle_t_db, *handle, (void *)&cpg_inst));
+ if (error != CS_OK) {
+ goto error_destroy;
+ }
+
+ cpg_inst->c = qb_ipcc_connect ("cpg", IPC_REQUEST_SIZE);
+ if (cpg_inst->c == NULL) {
+ error = qb_to_cs_error(-errno);
+ goto error_put_destroy;
+ }
+
+ if (model_data != NULL) {
+ switch (model) {
+ case CPG_MODEL_V1:
+ memcpy (&cpg_inst->model_v1_data, model_data, sizeof (cpg_model_v1_data_t));
+ if ((cpg_inst->model_v1_data.flags & ~(CPG_MODEL_V1_DELIVER_INITIAL_TOTEM_CONF)) != 0) {
+ error = CS_ERR_INVALID_PARAM;
+
+ goto error_destroy;
+ }
+ break;
+ }
+ }
+
+ /* Allow space for corosync internal headers */
+ cpg_inst->max_msg_size = IPC_REQUEST_SIZE - 1024;
+ cpg_inst->model_data.model = model;
+ cpg_inst->context = context;
+
+ qb_list_init(&cpg_inst->iteration_list_head);
+
+ qb_list_init(&cpg_inst->assembly_list_head);
+
+ hdb_handle_put (&cpg_handle_t_db, *handle);
+
+ return (CS_OK);
+
+error_put_destroy:
+ hdb_handle_put (&cpg_handle_t_db, *handle);
+error_destroy:
+ hdb_handle_destroy (&cpg_handle_t_db, *handle);
+error_no_destroy:
+ return (error);
+}
+
+cs_error_t cpg_finalize (
+ cpg_handle_t handle)
+{
+ struct cpg_inst *cpg_inst;
+ struct iovec iov;
+ struct req_lib_cpg_finalize req_lib_cpg_finalize;
+ struct res_lib_cpg_finalize res_lib_cpg_finalize;
+ cs_error_t error;
+
+ error = hdb_error_to_cs (hdb_handle_get (&cpg_handle_t_db, handle, (void *)&cpg_inst));
+ if (error != CS_OK) {
+ return (error);
+ }
+
+ /*
+ * Another thread has already started finalizing
+ */
+ if (cpg_inst->finalize) {
+ hdb_handle_put (&cpg_handle_t_db, handle);
+ return (CS_ERR_BAD_HANDLE);
+ }
+
+ cpg_inst->finalize = 1;
+
+ /*
+ * Send service request
+ */
+ req_lib_cpg_finalize.header.size = sizeof (struct req_lib_cpg_finalize);
+ req_lib_cpg_finalize.header.id = MESSAGE_REQ_CPG_FINALIZE;
+
+ iov.iov_base = (void *)&req_lib_cpg_finalize;
+ iov.iov_len = sizeof (struct req_lib_cpg_finalize);
+
+ error = coroipcc_msg_send_reply_receive (cpg_inst->c,
+ &iov,
+ 1,
+ &res_lib_cpg_finalize,
+ sizeof (struct res_lib_cpg_finalize));
+
+ cpg_inst_finalize (cpg_inst, handle);
+ hdb_handle_put (&cpg_handle_t_db, handle);
+
+ return (error);
+}
+
+cs_error_t cpg_fd_get (
+ cpg_handle_t handle,
+ int *fd)
+{
+ cs_error_t error;
+ struct cpg_inst *cpg_inst;
+
+ error = hdb_error_to_cs (hdb_handle_get (&cpg_handle_t_db, handle, (void *)&cpg_inst));
+ if (error != CS_OK) {
+ return (error);
+ }
+
+ error = qb_to_cs_error (qb_ipcc_fd_get (cpg_inst->c, fd));
+
+ hdb_handle_put (&cpg_handle_t_db, handle);
+
+ return (error);
+}
+
+cs_error_t cpg_max_atomic_msgsize_get (
+ cpg_handle_t handle,
+ uint32_t *size)
+{
+ cs_error_t error;
+ struct cpg_inst *cpg_inst;
+
+ error = hdb_error_to_cs (hdb_handle_get (&cpg_handle_t_db, handle, (void *)&cpg_inst));
+ if (error != CS_OK) {
+ return (error);
+ }
+
+ *size = cpg_inst->max_msg_size;
+
+ hdb_handle_put (&cpg_handle_t_db, handle);
+
+ return (error);
+}
+
+cs_error_t cpg_context_get (
+ cpg_handle_t handle,
+ void **context)
+{
+ cs_error_t error;
+ struct cpg_inst *cpg_inst;
+
+ error = hdb_error_to_cs (hdb_handle_get (&cpg_handle_t_db, handle, (void *)&cpg_inst));
+ if (error != CS_OK) {
+ return (error);
+ }
+
+ *context = cpg_inst->context;
+
+ hdb_handle_put (&cpg_handle_t_db, handle);
+
+ return (CS_OK);
+}
+
+cs_error_t cpg_context_set (
+ cpg_handle_t handle,
+ void *context)
+{
+ cs_error_t error;
+ struct cpg_inst *cpg_inst;
+
+ error = hdb_error_to_cs (hdb_handle_get (&cpg_handle_t_db, handle, (void *)&cpg_inst));
+ if (error != CS_OK) {
+ return (error);
+ }
+
+ cpg_inst->context = context;
+
+ hdb_handle_put (&cpg_handle_t_db, handle);
+
+ return (CS_OK);
+}
+
+cs_error_t cpg_dispatch (
+ cpg_handle_t handle,
+ cs_dispatch_flags_t dispatch_types)
+{
+ int timeout = -1;
+ cs_error_t error;
+ int cont = 1; /* always continue do loop except when set to 0 */
+ struct cpg_inst *cpg_inst;
+ struct res_lib_cpg_confchg_callback *res_cpg_confchg_callback;
+ struct res_lib_cpg_deliver_callback *res_cpg_deliver_callback;
+ struct res_lib_cpg_partial_deliver_callback *res_cpg_partial_deliver_callback;
+ struct res_lib_cpg_totem_confchg_callback *res_cpg_totem_confchg_callback;
+ struct cpg_inst cpg_inst_copy;
+ struct qb_ipc_response_header *dispatch_data;
+ struct cpg_address member_list[CPG_MEMBERS_MAX];
+ struct cpg_address left_list[CPG_MEMBERS_MAX];
+ struct cpg_address joined_list[CPG_MEMBERS_MAX];
+ struct cpg_name group_name;
+ struct cpg_assembly_data *assembly_data;
+ struct qb_list_head *iter, *tmp_iter;
+ mar_cpg_address_t *left_list_start;
+ mar_cpg_address_t *joined_list_start;
+ unsigned int i;
+ struct cpg_ring_id ring_id;
+ uint32_t totem_member_list[CPG_MEMBERS_MAX];
+ int32_t errno_res;
+ char dispatch_buf[IPC_DISPATCH_SIZE];
+
+ error = hdb_error_to_cs (hdb_handle_get (&cpg_handle_t_db, handle, (void *)&cpg_inst));
+ if (error != CS_OK) {
+ return (error);
+ }
+
+ /*
+ * Timeout instantly for CS_DISPATCH_ONE_NONBLOCKING or CS_DISPATCH_ALL and
+ * wait indefinitely for CS_DISPATCH_ONE or CS_DISPATCH_BLOCKING
+ */
+ if (dispatch_types == CS_DISPATCH_ALL || dispatch_types == CS_DISPATCH_ONE_NONBLOCKING) {
+ timeout = 0;
+ }
+
+ dispatch_data = (struct qb_ipc_response_header *)dispatch_buf;
+ do {
+ errno_res = qb_ipcc_event_recv (
+ cpg_inst->c,
+ dispatch_buf,
+ IPC_DISPATCH_SIZE,
+ timeout);
+ error = qb_to_cs_error (errno_res);
+ if (error == CS_ERR_BAD_HANDLE) {
+ error = CS_OK;
+ goto error_put;
+ }
+ if (error == CS_ERR_TRY_AGAIN) {
+ if (dispatch_types == CS_DISPATCH_ONE_NONBLOCKING) {
+ /*
+ * Don't mask error
+ */
+ goto error_put;
+ }
+ error = CS_OK;
+ if (dispatch_types == CS_DISPATCH_ALL) {
+ break; /* exit do while cont is 1 loop */
+ } else {
+ continue; /* next poll */
+ }
+ }
+ if (error != CS_OK) {
+ goto error_put;
+ }
+
+ /*
+ * Make copy of callbacks, message data, unlock instance, and call callback
+ * A risk of this dispatch method is that the callback routines may
+ * operate at the same time that cpgFinalize has been called.
+ */
+ memcpy (&cpg_inst_copy, cpg_inst, sizeof (struct cpg_inst));
+ switch (cpg_inst_copy.model_data.model) {
+ case CPG_MODEL_V1:
+ /*
+ * Dispatch incoming message
+ */
+ switch (dispatch_data->id) {
+ case MESSAGE_RES_CPG_DELIVER_CALLBACK:
+ if (cpg_inst_copy.model_v1_data.cpg_deliver_fn == NULL) {
+ break;
+ }
+
+ res_cpg_deliver_callback = (struct res_lib_cpg_deliver_callback *)dispatch_data;
+
+ marshall_from_mar_cpg_name_t (
+ &group_name,
+ &res_cpg_deliver_callback->group_name);
+
+ cpg_inst_copy.model_v1_data.cpg_deliver_fn (handle,
+ &group_name,
+ res_cpg_deliver_callback->nodeid,
+ res_cpg_deliver_callback->pid,
+ &res_cpg_deliver_callback->message,
+ res_cpg_deliver_callback->msglen);
+ break;
+
+ case MESSAGE_RES_CPG_PARTIAL_DELIVER_CALLBACK:
+ res_cpg_partial_deliver_callback = (struct res_lib_cpg_partial_deliver_callback *)dispatch_data;
+
+ marshall_from_mar_cpg_name_t (
+ &group_name,
+ &res_cpg_partial_deliver_callback->group_name);
+
+ /*
+ * Search for assembly data for current messages (nodeid, pid) pair in list of assemblies
+ */
+ assembly_data = NULL;
+ qb_list_for_each(iter, &(cpg_inst->assembly_list_head)) {
+ struct cpg_assembly_data *current_assembly_data = qb_list_entry (iter, struct cpg_assembly_data, list);
+ if (current_assembly_data->nodeid == res_cpg_partial_deliver_callback->nodeid && current_assembly_data->pid == res_cpg_partial_deliver_callback->pid) {
+ assembly_data = current_assembly_data;
+ break;
+ }
+ }
+
+ if (res_cpg_partial_deliver_callback->type == LIBCPG_PARTIAL_FIRST) {
+
+ /*
+ * As this is LIBCPG_PARTIAL_FIRST packet, check that there is no ongoing assembly.
+ * Otherwise the sending of packet must have been interrupted and error should have
+ * been reported to sending client. Therefore here last assembly will be dropped.
+ */
+ if (assembly_data) {
+ qb_list_del (&assembly_data->list);
+ free(assembly_data->assembly_buf);
+ free(assembly_data);
+ assembly_data = NULL;
+ }
+
+ assembly_data = malloc(sizeof(struct cpg_assembly_data));
+ if (!assembly_data) {
+ error = CS_ERR_NO_MEMORY;
+ goto error_put;
+ }
+
+ assembly_data->nodeid = res_cpg_partial_deliver_callback->nodeid;
+ assembly_data->pid = res_cpg_partial_deliver_callback->pid;
+ assembly_data->assembly_buf = malloc(res_cpg_partial_deliver_callback->msglen);
+ if (!assembly_data->assembly_buf) {
+ free(assembly_data);
+ error = CS_ERR_NO_MEMORY;
+ goto error_put;
+ }
+ assembly_data->assembly_buf_ptr = 0;
+ qb_list_init (&assembly_data->list);
+
+ qb_list_add (&assembly_data->list, &cpg_inst->assembly_list_head);
+ }
+ if (assembly_data) {
+ memcpy(assembly_data->assembly_buf + assembly_data->assembly_buf_ptr,
+ res_cpg_partial_deliver_callback->message, res_cpg_partial_deliver_callback->fraglen);
+ assembly_data->assembly_buf_ptr += res_cpg_partial_deliver_callback->fraglen;
+
+ if (res_cpg_partial_deliver_callback->type == LIBCPG_PARTIAL_LAST) {
+ cpg_inst_copy.model_v1_data.cpg_deliver_fn (handle,
+ &group_name,
+ res_cpg_partial_deliver_callback->nodeid,
+ res_cpg_partial_deliver_callback->pid,
+ assembly_data->assembly_buf,
+ res_cpg_partial_deliver_callback->msglen);
+
+ qb_list_del (&assembly_data->list);
+ free(assembly_data->assembly_buf);
+ free(assembly_data);
+ }
+ }
+ break;
+
+ case MESSAGE_RES_CPG_CONFCHG_CALLBACK:
+ if (cpg_inst_copy.model_v1_data.cpg_confchg_fn == NULL) {
+ break;
+ }
+
+ res_cpg_confchg_callback = (struct res_lib_cpg_confchg_callback *)dispatch_data;
+
+ for (i = 0; i < res_cpg_confchg_callback->member_list_entries; i++) {
+ marshall_from_mar_cpg_address_t (&member_list[i],
+ &res_cpg_confchg_callback->member_list[i]);
+ }
+ left_list_start = res_cpg_confchg_callback->member_list +
+ res_cpg_confchg_callback->member_list_entries;
+ for (i = 0; i < res_cpg_confchg_callback->left_list_entries; i++) {
+ marshall_from_mar_cpg_address_t (&left_list[i],
+ &left_list_start[i]);
+ }
+ joined_list_start = res_cpg_confchg_callback->member_list +
+ res_cpg_confchg_callback->member_list_entries +
+ res_cpg_confchg_callback->left_list_entries;
+ for (i = 0; i < res_cpg_confchg_callback->joined_list_entries; i++) {
+ marshall_from_mar_cpg_address_t (&joined_list[i],
+ &joined_list_start[i]);
+ }
+ marshall_from_mar_cpg_name_t (
+ &group_name,
+ &res_cpg_confchg_callback->group_name);
+
+ cpg_inst_copy.model_v1_data.cpg_confchg_fn (handle,
+ &group_name,
+ member_list,
+ res_cpg_confchg_callback->member_list_entries,
+ left_list,
+ res_cpg_confchg_callback->left_list_entries,
+ joined_list,
+ res_cpg_confchg_callback->joined_list_entries);
+
+ /*
+ * If member left while his partial packet was being assembled, assembly data must be removed from list
+ */
+ for (i = 0; i < res_cpg_confchg_callback->left_list_entries; i++) {
+ qb_list_for_each_safe(iter, tmp_iter, &(cpg_inst->assembly_list_head)) {
+ struct cpg_assembly_data *current_assembly_data = qb_list_entry (iter, struct cpg_assembly_data, list);
+ if (current_assembly_data->nodeid != left_list[i].nodeid || current_assembly_data->pid != left_list[i].pid)
+ continue;
+
+ qb_list_del (&current_assembly_data->list);
+ free(current_assembly_data->assembly_buf);
+ free(current_assembly_data);
+ }
+ }
+
+ break;
+ case MESSAGE_RES_CPG_TOTEM_CONFCHG_CALLBACK:
+ if (cpg_inst_copy.model_v1_data.cpg_totem_confchg_fn == NULL) {
+ break;
+ }
+
+ res_cpg_totem_confchg_callback = (struct res_lib_cpg_totem_confchg_callback *)dispatch_data;
+
+ marshall_from_mar_cpg_ring_id_t (&ring_id, &res_cpg_totem_confchg_callback->ring_id);
+ for (i = 0; i < res_cpg_totem_confchg_callback->member_list_entries; i++) {
+ totem_member_list[i] = res_cpg_totem_confchg_callback->member_list[i];
+ }
+
+ cpg_inst_copy.model_v1_data.cpg_totem_confchg_fn (handle,
+ ring_id,
+ res_cpg_totem_confchg_callback->member_list_entries,
+ totem_member_list);
+ break;
+ default:
+ error = CS_ERR_LIBRARY;
+ goto error_put;
+ break;
+ } /* - switch (dispatch_data->id) */
+ break; /* case CPG_MODEL_V1 */
+ } /* - switch (cpg_inst_copy.model_data.model) */
+
+ if (cpg_inst_copy.finalize || cpg_inst->finalize) {
+ /*
+ * If the finalize has been called then get out of the dispatch.
+ */
+ cpg_inst->finalize = 1;
+ error = CS_ERR_BAD_HANDLE;
+ goto error_put;
+ }
+
+ /*
+ * Determine if more messages should be processed
+ */
+ if (dispatch_types == CS_DISPATCH_ONE || dispatch_types == CS_DISPATCH_ONE_NONBLOCKING) {
+ cont = 0;
+ }
+ } while (cont);
+
+error_put:
+ hdb_handle_put (&cpg_handle_t_db, handle);
+ return (error);
+}
+
+cs_error_t cpg_join (
+ cpg_handle_t handle,
+ const struct cpg_name *group)
+{
+ cs_error_t error;
+ struct cpg_inst *cpg_inst;
+ struct iovec iov[2];
+ struct req_lib_cpg_join req_lib_cpg_join;
+ struct res_lib_cpg_join response;
+
+ if (group->length > CPG_MAX_NAME_LENGTH) {
+ return (CS_ERR_NAME_TOO_LONG);
+ }
+
+ error = hdb_error_to_cs (hdb_handle_get (&cpg_handle_t_db, handle, (void *)&cpg_inst));
+ if (error != CS_OK) {
+ return (error);
+ }
+
+ /* Now join */
+ req_lib_cpg_join.header.size = sizeof (struct req_lib_cpg_join);
+ req_lib_cpg_join.header.id = MESSAGE_REQ_CPG_JOIN;
+ req_lib_cpg_join.pid = getpid();
+ req_lib_cpg_join.flags = 0;
+
+ switch (cpg_inst->model_data.model) {
+ case CPG_MODEL_V1:
+ req_lib_cpg_join.flags = cpg_inst->model_v1_data.flags;
+ break;
+ }
+
+ marshall_to_mar_cpg_name_t (&req_lib_cpg_join.group_name,
+ group);
+
+ iov[0].iov_base = (void *)&req_lib_cpg_join;
+ iov[0].iov_len = sizeof (struct req_lib_cpg_join);
+
+ do {
+ error = coroipcc_msg_send_reply_receive (cpg_inst->c, iov, 1,
+ &response, sizeof (struct res_lib_cpg_join));
+
+ if (error != CS_OK) {
+ goto error_exit;
+ }
+ } while (response.header.error == CS_ERR_BUSY);
+
+ error = response.header.error;
+
+error_exit:
+ hdb_handle_put (&cpg_handle_t_db, handle);
+
+ return (error);
+}
+
+cs_error_t cpg_leave (
+ cpg_handle_t handle,
+ const struct cpg_name *group)
+{
+ cs_error_t error;
+ struct cpg_inst *cpg_inst;
+ struct iovec iov[2];
+ struct req_lib_cpg_leave req_lib_cpg_leave;
+ struct res_lib_cpg_leave res_lib_cpg_leave;
+
+ if (group->length > CPG_MAX_NAME_LENGTH) {
+ return (CS_ERR_NAME_TOO_LONG);
+ }
+
+ error = hdb_error_to_cs (hdb_handle_get (&cpg_handle_t_db, handle, (void *)&cpg_inst));
+ if (error != CS_OK) {
+ return (error);
+ }
+
+ req_lib_cpg_leave.header.size = sizeof (struct req_lib_cpg_leave);
+ req_lib_cpg_leave.header.id = MESSAGE_REQ_CPG_LEAVE;
+ req_lib_cpg_leave.pid = getpid();
+ marshall_to_mar_cpg_name_t (&req_lib_cpg_leave.group_name,
+ group);
+
+ iov[0].iov_base = (void *)&req_lib_cpg_leave;
+ iov[0].iov_len = sizeof (struct req_lib_cpg_leave);
+
+ do {
+ error = coroipcc_msg_send_reply_receive (cpg_inst->c, iov, 1,
+ &res_lib_cpg_leave, sizeof (struct res_lib_cpg_leave));
+
+ if (error != CS_OK) {
+ goto error_exit;
+ }
+ } while (res_lib_cpg_leave.header.error == CS_ERR_BUSY);
+
+ error = res_lib_cpg_leave.header.error;
+
+error_exit:
+ hdb_handle_put (&cpg_handle_t_db, handle);
+
+ return (error);
+}
+
+cs_error_t cpg_membership_get (
+ cpg_handle_t handle,
+ struct cpg_name *group_name,
+ struct cpg_address *member_list,
+ int *member_list_entries)
+{
+ cs_error_t error;
+ struct cpg_inst *cpg_inst;
+ struct iovec iov;
+ struct req_lib_cpg_membership_get req_lib_cpg_membership_get;
+ struct res_lib_cpg_membership_get res_lib_cpg_membership_get;
+ unsigned int i;
+
+ if (group_name->length > CPG_MAX_NAME_LENGTH) {
+ return (CS_ERR_NAME_TOO_LONG);
+ }
+ if (member_list == NULL) {
+ return (CS_ERR_INVALID_PARAM);
+ }
+ if (member_list_entries == NULL) {
+ return (CS_ERR_INVALID_PARAM);
+ }
+
+ error = hdb_error_to_cs (hdb_handle_get (&cpg_handle_t_db, handle, (void *)&cpg_inst));
+ if (error != CS_OK) {
+ return (error);
+ }
+
+ req_lib_cpg_membership_get.header.size = sizeof (struct req_lib_cpg_membership_get);
+ req_lib_cpg_membership_get.header.id = MESSAGE_REQ_CPG_MEMBERSHIP;
+
+ marshall_to_mar_cpg_name_t (&req_lib_cpg_membership_get.group_name,
+ group_name);
+
+ iov.iov_base = (void *)&req_lib_cpg_membership_get;
+ iov.iov_len = sizeof (struct req_lib_cpg_membership_get);
+
+ error = coroipcc_msg_send_reply_receive (cpg_inst->c, &iov, 1,
+ &res_lib_cpg_membership_get, sizeof (res_lib_cpg_membership_get));
+
+ if (error != CS_OK) {
+ goto error_exit;
+ }
+
+ error = res_lib_cpg_membership_get.header.error;
+
+ /*
+ * Copy results to caller
+ */
+ *member_list_entries = res_lib_cpg_membership_get.member_count;
+ if (member_list) {
+ for (i = 0; i < res_lib_cpg_membership_get.member_count; i++) {
+ marshall_from_mar_cpg_address_t (&member_list[i],
+ &res_lib_cpg_membership_get.member_list[i]);
+ }
+ }
+
+error_exit:
+ hdb_handle_put (&cpg_handle_t_db, handle);
+
+ return (error);
+}
+
+cs_error_t cpg_local_get (
+ cpg_handle_t handle,
+ unsigned int *local_nodeid)
+{
+ cs_error_t error;
+ struct cpg_inst *cpg_inst;
+ struct iovec iov;
+ struct req_lib_cpg_local_get req_lib_cpg_local_get;
+ struct res_lib_cpg_local_get res_lib_cpg_local_get;
+
+ error = hdb_error_to_cs (hdb_handle_get (&cpg_handle_t_db, handle, (void *)&cpg_inst));
+ if (error != CS_OK) {
+ return (error);
+ }
+
+ req_lib_cpg_local_get.header.size = sizeof (struct qb_ipc_request_header);
+ req_lib_cpg_local_get.header.id = MESSAGE_REQ_CPG_LOCAL_GET;
+
+ iov.iov_base = (void *)&req_lib_cpg_local_get;
+ iov.iov_len = sizeof (struct req_lib_cpg_local_get);
+
+ error = coroipcc_msg_send_reply_receive (cpg_inst->c, &iov, 1,
+ &res_lib_cpg_local_get, sizeof (res_lib_cpg_local_get));
+
+ if (error != CS_OK) {
+ goto error_exit;
+ }
+
+ error = res_lib_cpg_local_get.header.error;
+
+ *local_nodeid = res_lib_cpg_local_get.local_nodeid;
+
+error_exit:
+ hdb_handle_put (&cpg_handle_t_db, handle);
+
+ return (error);
+}
+
+cs_error_t cpg_flow_control_state_get (
+ cpg_handle_t handle,
+ cpg_flow_control_state_t *flow_control_state)
+{
+ cs_error_t error;
+ struct cpg_inst *cpg_inst;
+
+ error = hdb_error_to_cs (hdb_handle_get (&cpg_handle_t_db, handle, (void *)&cpg_inst));
+ if (error != CS_OK) {
+ return (error);
+ }
+ *flow_control_state = CPG_FLOW_CONTROL_DISABLED;
+ error = CS_OK;
+
+ hdb_handle_put (&cpg_handle_t_db, handle);
+
+ return (error);
+}
+
+static int
+memory_map (char *path, const char *file, void **buf, size_t bytes)
+{
+ int32_t fd;
+ void *addr;
+ int32_t res;
+ char *buffer;
+ int32_t i;
+ size_t written;
+ size_t page_size;
+ long int sysconf_page_size;
+ mode_t old_umask;
+
+ snprintf (path, PATH_MAX, "/dev/shm/%s", file);
+
+ old_umask = umask(CPG_MEMORY_MAP_UMASK);
+ fd = mkstemp (path);
+ (void)umask(old_umask);
+ if (fd == -1) {
+ snprintf (path, PATH_MAX, LOCALSTATEDIR "/run/%s", file);
+ old_umask = umask(CPG_MEMORY_MAP_UMASK);
+ fd = mkstemp (path);
+ (void)umask(old_umask);
+ if (fd == -1) {
+ return (-1);
+ }
+ }
+
+ res = ftruncate (fd, bytes);
+ if (res == -1) {
+ goto error_close_unlink;
+ }
+ sysconf_page_size = sysconf(_SC_PAGESIZE);
+ if (sysconf_page_size <= 0) {
+ goto error_close_unlink;
+ }
+ page_size = sysconf_page_size;
+ buffer = malloc (page_size);
+ if (buffer == NULL) {
+ goto error_close_unlink;
+ }
+ memset (buffer, 0, page_size);
+ for (i = 0; i < (bytes / page_size); i++) {
+retry_write:
+ written = write (fd, buffer, page_size);
+ if (written == -1 && errno == EINTR) {
+ goto retry_write;
+ }
+ if (written != page_size) {
+ free (buffer);
+ goto error_close_unlink;
+ }
+ }
+ free (buffer);
+
+ addr = mmap (NULL, bytes, PROT_READ | PROT_WRITE,
+ MAP_SHARED, fd, 0);
+
+ if (addr == MAP_FAILED) {
+ goto error_close_unlink;
+ }
+#ifdef MADV_NOSYNC
+ madvise(addr, bytes, MADV_NOSYNC);
+#endif
+
+ res = close (fd);
+ if (res) {
+ munmap(addr, bytes);
+
+ return (-1);
+ }
+ *buf = addr;
+
+ return 0;
+
+error_close_unlink:
+ close (fd);
+ unlink(path);
+ return -1;
+}
+
+cs_error_t cpg_zcb_alloc (
+ cpg_handle_t handle,
+ size_t size,
+ void **buffer)
+{
+ void *buf = NULL;
+ char path[PATH_MAX];
+ mar_req_coroipcc_zc_alloc_t req_coroipcc_zc_alloc;
+ struct qb_ipc_response_header res_coroipcs_zc_alloc;
+ size_t map_size;
+ struct iovec iovec;
+ struct coroipcs_zc_header *hdr;
+ cs_error_t error;
+ struct cpg_inst *cpg_inst;
+
+ error = hdb_error_to_cs (hdb_handle_get (&cpg_handle_t_db, handle, (void *)&cpg_inst));
+ if (error != CS_OK) {
+ return (error);
+ }
+
+ map_size = size + sizeof (struct req_lib_cpg_mcast) + sizeof (struct coroipcs_zc_header);
+ assert(memory_map (path, "corosync_zerocopy-XXXXXX", &buf, map_size) != -1);
+
+ if (strlen(path) >= CPG_ZC_PATH_LEN) {
+ unlink(path);
+ munmap (buf, map_size);
+ return (CS_ERR_NAME_TOO_LONG);
+ }
+
+ req_coroipcc_zc_alloc.header.size = sizeof (mar_req_coroipcc_zc_alloc_t);
+ req_coroipcc_zc_alloc.header.id = MESSAGE_REQ_CPG_ZC_ALLOC;
+ req_coroipcc_zc_alloc.map_size = map_size;
+ strcpy (req_coroipcc_zc_alloc.path_to_file, path);
+
+ iovec.iov_base = (void *)&req_coroipcc_zc_alloc;
+ iovec.iov_len = sizeof (mar_req_coroipcc_zc_alloc_t);
+
+ error = coroipcc_msg_send_reply_receive (
+ cpg_inst->c,
+ &iovec,
+ 1,
+ &res_coroipcs_zc_alloc,
+ sizeof (struct qb_ipc_response_header));
+
+ if (error != CS_OK) {
+ goto error_exit;
+ }
+
+ hdr = (struct coroipcs_zc_header *)buf;
+ hdr->map_size = map_size;
+ *buffer = ((char *)buf) + sizeof (struct coroipcs_zc_header) + sizeof (struct req_lib_cpg_mcast);
+
+error_exit:
+ hdb_handle_put (&cpg_handle_t_db, handle);
+ return (error);
+}
+
+cs_error_t cpg_zcb_free (
+ cpg_handle_t handle,
+ void *buffer)
+{
+ cs_error_t error;
+ unsigned int res;
+ struct cpg_inst *cpg_inst;
+ mar_req_coroipcc_zc_free_t req_coroipcc_zc_free;
+ struct qb_ipc_response_header res_coroipcs_zc_free;
+ struct iovec iovec;
+ struct coroipcs_zc_header *header = (struct coroipcs_zc_header *)((char *)buffer - sizeof (struct coroipcs_zc_header) - sizeof (struct req_lib_cpg_mcast));
+
+ error = hdb_error_to_cs (hdb_handle_get (&cpg_handle_t_db, handle, (void *)&cpg_inst));
+ if (error != CS_OK) {
+ return (error);
+ }
+
+ req_coroipcc_zc_free.header.size = sizeof (mar_req_coroipcc_zc_free_t);
+ req_coroipcc_zc_free.header.id = MESSAGE_REQ_CPG_ZC_FREE;
+ req_coroipcc_zc_free.map_size = header->map_size;
+ req_coroipcc_zc_free.server_address = header->server_address;
+
+ iovec.iov_base = (void *)&req_coroipcc_zc_free;
+ iovec.iov_len = sizeof (mar_req_coroipcc_zc_free_t);
+
+ error = coroipcc_msg_send_reply_receive (
+ cpg_inst->c,
+ &iovec,
+ 1,
+ &res_coroipcs_zc_free,
+ sizeof (struct qb_ipc_response_header));
+
+ if (error != CS_OK) {
+ goto error_exit;
+ }
+
+ res = munmap ((void *)header, header->map_size);
+ if (res == -1) {
+ error = qb_to_cs_error(-errno);
+
+ goto error_exit;
+ }
+
+error_exit:
+ hdb_handle_put (&cpg_handle_t_db, handle);
+
+ return (error);
+}
+
+cs_error_t cpg_zcb_mcast_joined (
+ cpg_handle_t handle,
+ cpg_guarantee_t guarantee,
+ void *msg,
+ size_t msg_len)
+{
+ cs_error_t error;
+ struct cpg_inst *cpg_inst;
+ struct req_lib_cpg_mcast *req_lib_cpg_mcast;
+ struct res_lib_cpg_mcast res_lib_cpg_mcast;
+ mar_req_coroipcc_zc_execute_t req_coroipcc_zc_execute;
+ struct coroipcs_zc_header *hdr;
+ struct iovec iovec;
+
+ error = hdb_error_to_cs (hdb_handle_get (&cpg_handle_t_db, handle, (void *)&cpg_inst));
+ if (error != CS_OK) {
+ return (error);
+ }
+
+ if (msg_len > IPC_REQUEST_SIZE) {
+ error = CS_ERR_TOO_BIG;
+ goto error_exit;
+ }
+
+ req_lib_cpg_mcast = (struct req_lib_cpg_mcast *)(((char *)msg) - sizeof (struct req_lib_cpg_mcast));
+ req_lib_cpg_mcast->header.size = sizeof (struct req_lib_cpg_mcast) +
+ msg_len;
+
+ req_lib_cpg_mcast->header.id = MESSAGE_REQ_CPG_MCAST;
+ req_lib_cpg_mcast->guarantee = guarantee;
+ req_lib_cpg_mcast->msglen = msg_len;
+
+ hdr = (struct coroipcs_zc_header *)(((char *)req_lib_cpg_mcast) - sizeof (struct coroipcs_zc_header));
+
+ req_coroipcc_zc_execute.header.size = sizeof (mar_req_coroipcc_zc_execute_t);
+ req_coroipcc_zc_execute.header.id = MESSAGE_REQ_CPG_ZC_EXECUTE;
+ req_coroipcc_zc_execute.server_address = hdr->server_address;
+
+ iovec.iov_base = (void *)&req_coroipcc_zc_execute;
+ iovec.iov_len = sizeof (mar_req_coroipcc_zc_execute_t);
+
+ error = coroipcc_msg_send_reply_receive (
+ cpg_inst->c,
+ &iovec,
+ 1,
+ &res_lib_cpg_mcast,
+ sizeof(res_lib_cpg_mcast));
+
+ if (error != CS_OK) {
+ goto error_exit;
+ }
+
+ error = res_lib_cpg_mcast.header.error;
+
+error_exit:
+ hdb_handle_put (&cpg_handle_t_db, handle);
+
+ return (error);
+}
+
+static cs_error_t send_fragments (
+ struct cpg_inst *cpg_inst,
+ cpg_guarantee_t guarantee,
+ size_t msg_len,
+ const struct iovec *iovec,
+ unsigned int iov_len)
+{
+ int i;
+ cs_error_t error = CS_OK;
+ struct iovec iov[2];
+ struct req_lib_cpg_partial_mcast req_lib_cpg_mcast;
+ struct res_lib_cpg_partial_send res_lib_cpg_partial_send;
+ size_t sent = 0;
+ size_t iov_sent = 0;
+ int retry_count;
+
+ req_lib_cpg_mcast.header.id = MESSAGE_REQ_CPG_PARTIAL_MCAST;
+ req_lib_cpg_mcast.guarantee = guarantee;
+ req_lib_cpg_mcast.msglen = msg_len;
+
+ iov[0].iov_base = (void *)&req_lib_cpg_mcast;
+ iov[0].iov_len = sizeof (struct req_lib_cpg_partial_mcast);
+
+ i=0;
+ iov_sent = 0 ;
+ qb_ipcc_fc_enable_max_set(cpg_inst->c, 2);
+
+ while (error == CS_OK && sent < msg_len) {
+
+ retry_count = 0;
+ if ( (iovec[i].iov_len - iov_sent) > cpg_inst->max_msg_size) {
+ iov[1].iov_len = cpg_inst->max_msg_size;
+ }
+ else {
+ iov[1].iov_len = iovec[i].iov_len - iov_sent;
+ }
+
+ if (sent == 0) {
+ req_lib_cpg_mcast.type = LIBCPG_PARTIAL_FIRST;
+ }
+ else if ((sent + iov[1].iov_len) == msg_len) {
+ req_lib_cpg_mcast.type = LIBCPG_PARTIAL_LAST;
+ }
+ else {
+ req_lib_cpg_mcast.type = LIBCPG_PARTIAL_CONTINUED;
+ }
+
+ req_lib_cpg_mcast.fraglen = iov[1].iov_len;
+ req_lib_cpg_mcast.header.size = sizeof (struct req_lib_cpg_partial_mcast) + iov[1].iov_len;
+ iov[1].iov_base = (char *)iovec[i].iov_base + iov_sent;
+
+ resend:
+ error = coroipcc_msg_send_reply_receive (cpg_inst->c, iov, 2,
+ &res_lib_cpg_partial_send,
+ sizeof (res_lib_cpg_partial_send));
+
+ if (error == CS_ERR_TRY_AGAIN) {
+ fprintf(stderr, "sleep. counter=%d\n", retry_count);
+ if (++retry_count > MAX_RETRIES) {
+ goto error_exit;
+ }
+ usleep(10000);
+ goto resend;
+ }
+
+ iov_sent += iov[1].iov_len;
+ sent += iov[1].iov_len;
+
+ /* Next iovec */
+ if (iov_sent >= iovec[i].iov_len) {
+ i++;
+ iov_sent = 0;
+ }
+ error = res_lib_cpg_partial_send.header.error;
+ }
+error_exit:
+ qb_ipcc_fc_enable_max_set(cpg_inst->c, 1);
+
+ return error;
+}
+
+
+cs_error_t cpg_mcast_joined (
+ cpg_handle_t handle,
+ cpg_guarantee_t guarantee,
+ const struct iovec *iovec,
+ unsigned int iov_len)
+{
+ int i;
+ cs_error_t error;
+ struct cpg_inst *cpg_inst;
+ struct iovec iov[64];
+ struct req_lib_cpg_mcast req_lib_cpg_mcast;
+ size_t msg_len = 0;
+
+ error = hdb_error_to_cs (hdb_handle_get (&cpg_handle_t_db, handle, (void *)&cpg_inst));
+ if (error != CS_OK) {
+ return (error);
+ }
+
+ for (i = 0; i < iov_len; i++ ) {
+ msg_len += iovec[i].iov_len;
+ }
+
+ if (msg_len > cpg_inst->max_msg_size) {
+ error = send_fragments(cpg_inst, guarantee, msg_len, iovec, iov_len);
+ goto error_exit;
+ }
+
+ req_lib_cpg_mcast.header.size = sizeof (struct req_lib_cpg_mcast) +
+ msg_len;
+
+ req_lib_cpg_mcast.header.id = MESSAGE_REQ_CPG_MCAST;
+ req_lib_cpg_mcast.guarantee = guarantee;
+ req_lib_cpg_mcast.msglen = msg_len;
+
+ iov[0].iov_base = (void *)&req_lib_cpg_mcast;
+ iov[0].iov_len = sizeof (struct req_lib_cpg_mcast);
+ memcpy (&iov[1], iovec, iov_len * sizeof (struct iovec));
+
+ qb_ipcc_fc_enable_max_set(cpg_inst->c, 2);
+ error = qb_to_cs_error(qb_ipcc_sendv(cpg_inst->c, iov, iov_len + 1));
+ qb_ipcc_fc_enable_max_set(cpg_inst->c, 1);
+
+error_exit:
+ hdb_handle_put (&cpg_handle_t_db, handle);
+
+ return (error);
+}
+
+cs_error_t cpg_iteration_initialize(
+ cpg_handle_t handle,
+ cpg_iteration_type_t iteration_type,
+ const struct cpg_name *group,
+ cpg_iteration_handle_t *cpg_iteration_handle)
+{
+ cs_error_t error;
+ struct iovec iov;
+ struct cpg_inst *cpg_inst;
+ struct cpg_iteration_instance_t *cpg_iteration_instance;
+ struct req_lib_cpg_iterationinitialize req_lib_cpg_iterationinitialize;
+ struct res_lib_cpg_iterationinitialize res_lib_cpg_iterationinitialize;
+
+ if (group && group->length > CPG_MAX_NAME_LENGTH) {
+ return (CS_ERR_NAME_TOO_LONG);
+ }
+ if (cpg_iteration_handle == NULL) {
+ return (CS_ERR_INVALID_PARAM);
+ }
+
+ if ((iteration_type == CPG_ITERATION_ONE_GROUP && group == NULL) ||
+ (iteration_type != CPG_ITERATION_ONE_GROUP && group != NULL)) {
+ return (CS_ERR_INVALID_PARAM);
+ }
+
+ if (iteration_type != CPG_ITERATION_NAME_ONLY && iteration_type != CPG_ITERATION_ONE_GROUP &&
+ iteration_type != CPG_ITERATION_ALL) {
+
+ return (CS_ERR_INVALID_PARAM);
+ }
+
+ error = hdb_error_to_cs (hdb_handle_get (&cpg_handle_t_db, handle, (void *)&cpg_inst));
+ if (error != CS_OK) {
+ return (error);
+ }
+
+ error = hdb_error_to_cs (hdb_handle_create (&cpg_iteration_handle_t_db,
+ sizeof (struct cpg_iteration_instance_t), cpg_iteration_handle));
+ if (error != CS_OK) {
+ goto error_put_cpg_db;
+ }
+
+ error = hdb_error_to_cs (hdb_handle_get (&cpg_iteration_handle_t_db, *cpg_iteration_handle,
+ (void *)&cpg_iteration_instance));
+ if (error != CS_OK) {
+ goto error_destroy;
+ }
+
+ cpg_iteration_instance->conn = cpg_inst->c;
+
+ qb_list_init (&cpg_iteration_instance->list);
+
+ req_lib_cpg_iterationinitialize.header.size = sizeof (struct req_lib_cpg_iterationinitialize);
+ req_lib_cpg_iterationinitialize.header.id = MESSAGE_REQ_CPG_ITERATIONINITIALIZE;
+ req_lib_cpg_iterationinitialize.iteration_type = iteration_type;
+ if (group) {
+ marshall_to_mar_cpg_name_t (&req_lib_cpg_iterationinitialize.group_name, group);
+ }
+
+ iov.iov_base = (void *)&req_lib_cpg_iterationinitialize;
+ iov.iov_len = sizeof (struct req_lib_cpg_iterationinitialize);
+
+ error = coroipcc_msg_send_reply_receive (cpg_inst->c,
+ &iov,
+ 1,
+ &res_lib_cpg_iterationinitialize,
+ sizeof (struct res_lib_cpg_iterationinitialize));
+
+ if (error != CS_OK) {
+ goto error_put_destroy;
+ }
+
+ cpg_iteration_instance->executive_iteration_handle =
+ res_lib_cpg_iterationinitialize.iteration_handle;
+ cpg_iteration_instance->cpg_iteration_handle = *cpg_iteration_handle;
+
+ qb_list_add (&cpg_iteration_instance->list, &cpg_inst->iteration_list_head);
+
+ hdb_handle_put (&cpg_iteration_handle_t_db, *cpg_iteration_handle);
+ hdb_handle_put (&cpg_handle_t_db, handle);
+
+ return (res_lib_cpg_iterationinitialize.header.error);
+
+error_put_destroy:
+ hdb_handle_put (&cpg_iteration_handle_t_db, *cpg_iteration_handle);
+error_destroy:
+ hdb_handle_destroy (&cpg_iteration_handle_t_db, *cpg_iteration_handle);
+error_put_cpg_db:
+ hdb_handle_put (&cpg_handle_t_db, handle);
+
+ return (error);
+}
+
+cs_error_t cpg_iteration_next(
+ cpg_iteration_handle_t handle,
+ struct cpg_iteration_description_t *description)
+{
+ cs_error_t error;
+ struct cpg_iteration_instance_t *cpg_iteration_instance;
+ struct req_lib_cpg_iterationnext req_lib_cpg_iterationnext;
+ struct res_lib_cpg_iterationnext res_lib_cpg_iterationnext;
+
+ if (description == NULL) {
+ return CS_ERR_INVALID_PARAM;
+ }
+
+ error = hdb_error_to_cs (hdb_handle_get (&cpg_iteration_handle_t_db, handle,
+ (void *)&cpg_iteration_instance));
+ if (error != CS_OK) {
+ goto error_exit;
+ }
+
+ req_lib_cpg_iterationnext.header.size = sizeof (struct req_lib_cpg_iterationnext);
+ req_lib_cpg_iterationnext.header.id = MESSAGE_REQ_CPG_ITERATIONNEXT;
+ req_lib_cpg_iterationnext.iteration_handle = cpg_iteration_instance->executive_iteration_handle;
+
+ error = qb_to_cs_error (qb_ipcc_send (cpg_iteration_instance->conn,
+ &req_lib_cpg_iterationnext,
+ req_lib_cpg_iterationnext.header.size));
+ if (error != CS_OK) {
+ goto error_put;
+ }
+
+ error = qb_to_cs_error (qb_ipcc_recv (cpg_iteration_instance->conn,
+ &res_lib_cpg_iterationnext,
+ sizeof(struct res_lib_cpg_iterationnext), -1));
+ if (error != CS_OK) {
+ goto error_put;
+ }
+
+ marshall_from_mar_cpg_iteration_description_t(
+ description,
+ &res_lib_cpg_iterationnext.description);
+
+ error = res_lib_cpg_iterationnext.header.error;
+
+error_put:
+ hdb_handle_put (&cpg_iteration_handle_t_db, handle);
+
+error_exit:
+ return (error);
+}
+
+cs_error_t cpg_iteration_finalize (
+ cpg_iteration_handle_t handle)
+{
+ cs_error_t error;
+ struct iovec iov;
+ struct cpg_iteration_instance_t *cpg_iteration_instance;
+ struct req_lib_cpg_iterationfinalize req_lib_cpg_iterationfinalize;
+ struct res_lib_cpg_iterationfinalize res_lib_cpg_iterationfinalize;
+
+ error = hdb_error_to_cs (hdb_handle_get (&cpg_iteration_handle_t_db, handle,
+ (void *)&cpg_iteration_instance));
+ if (error != CS_OK) {
+ goto error_exit;
+ }
+
+ req_lib_cpg_iterationfinalize.header.size = sizeof (struct req_lib_cpg_iterationfinalize);
+ req_lib_cpg_iterationfinalize.header.id = MESSAGE_REQ_CPG_ITERATIONFINALIZE;
+ req_lib_cpg_iterationfinalize.iteration_handle = cpg_iteration_instance->executive_iteration_handle;
+
+ iov.iov_base = (void *)&req_lib_cpg_iterationfinalize;
+ iov.iov_len = sizeof (struct req_lib_cpg_iterationfinalize);
+
+ error = coroipcc_msg_send_reply_receive (cpg_iteration_instance->conn,
+ &iov,
+ 1,
+ &res_lib_cpg_iterationfinalize,
+ sizeof (struct req_lib_cpg_iterationfinalize));
+
+ if (error != CS_OK) {
+ goto error_put;
+ }
+
+ cpg_iteration_instance_finalize (cpg_iteration_instance);
+ hdb_handle_put (&cpg_iteration_handle_t_db, cpg_iteration_instance->cpg_iteration_handle);
+
+ return (res_lib_cpg_iterationfinalize.header.error);
+
+error_put:
+ hdb_handle_put (&cpg_iteration_handle_t_db, handle);
+error_exit:
+ return (error);
+}
+
+/** @} */
diff --git a/lib/libcfg.versions b/lib/libcfg.versions
new file mode 100644
index 0000000..18d18f7
--- /dev/null
+++ b/lib/libcfg.versions
@@ -0,0 +1,18 @@
+# Version and symbol export for libcfg.so
+
+COROSYNC_CFG_0.82 {
+ global:
+ corosync_cfg_initialize;
+ corosync_cfg_fd_get;
+ corosync_cfg_dispatch;
+ corosync_cfg_finalize;
+ corosync_cfg_administrative_state_get;
+ corosync_cfg_administrative_state_set;
+ corosync_cfg_track;
+ corosync_cfg_track_stop;
+ corosync_cfg_ring_status_get;
+ corosync_cfg_node_status_get;
+ corosync_cfg_ring_reenable;
+ corosync_cfg_trackstart;
+ corosync_cfg_trackstop;
+};
diff --git a/lib/libcfg.verso b/lib/libcfg.verso
new file mode 100644
index 0000000..1502020
--- /dev/null
+++ b/lib/libcfg.verso
@@ -0,0 +1 @@
+7.3.0
diff --git a/lib/libcmap.versions b/lib/libcmap.versions
new file mode 100644
index 0000000..59c8778
--- /dev/null
+++ b/lib/libcmap.versions
@@ -0,0 +1,6 @@
+# Version and symbol export for libsam.so
+
+COROSYNC_CMAP_1.0 {
+ global:
+ cmap_initialize;
+};
diff --git a/lib/libcmap.verso b/lib/libcmap.verso
new file mode 100644
index 0000000..ee74734
--- /dev/null
+++ b/lib/libcmap.verso
@@ -0,0 +1 @@
+4.1.0
diff --git a/lib/libcpg.versions b/lib/libcpg.versions
new file mode 100644
index 0000000..93eeb52
--- /dev/null
+++ b/lib/libcpg.versions
@@ -0,0 +1,17 @@
+# Version and symbol export for libcpg.so
+
+COROSYNC_CPG_1.0 {
+ global:
+ cpg_initialize;
+ cpg_finalize;
+ cpg_fd_get;
+ cpg_dispatch;
+ cpg_join;
+ cpg_leave;
+ cpg_mcast_joined;
+ cpg_membership_get;
+ cpg_context_get;
+ cpg_context_set;
+ cpg_zcb_alloc;
+ cpg_zcb_free;
+};
diff --git a/lib/libcpg.verso b/lib/libcpg.verso
new file mode 100644
index 0000000..ee74734
--- /dev/null
+++ b/lib/libcpg.verso
@@ -0,0 +1 @@
+4.1.0
diff --git a/lib/libquorum.versions b/lib/libquorum.versions
new file mode 100644
index 0000000..b1f0a88
--- /dev/null
+++ b/lib/libquorum.versions
@@ -0,0 +1,11 @@
+# Version and symbol export for libquorum.so
+
+COROSYNC_QUORUM_1.0 {
+ global:
+ quorum_initialize;
+ quorum_finalize;
+ quorum_getquorate;
+ quorum_initialize;
+ quorum_finalize;
+ quorum_dispatch;
+};
diff --git a/lib/libquorum.verso b/lib/libquorum.verso
new file mode 100644
index 0000000..831446c
--- /dev/null
+++ b/lib/libquorum.verso
@@ -0,0 +1 @@
+5.1.0
diff --git a/lib/libsam.versions b/lib/libsam.versions
new file mode 100644
index 0000000..48fba2c
--- /dev/null
+++ b/lib/libsam.versions
@@ -0,0 +1,12 @@
+# Version and symbol export for libsam.so
+
+COROSYNC_SAM_1.0 {
+ global:
+ sam_initialized;
+ sam_finalize;
+ sam_start;
+ sam_stop;
+ sam_register;
+ sam_hc_send;
+ sam_hc_callback_register;
+};
diff --git a/lib/libsam.verso b/lib/libsam.verso
new file mode 100644
index 0000000..fdc6698
--- /dev/null
+++ b/lib/libsam.verso
@@ -0,0 +1 @@
+4.4.0
diff --git a/lib/libvotequorum.versions b/lib/libvotequorum.versions
new file mode 100644
index 0000000..7a37030
--- /dev/null
+++ b/lib/libvotequorum.versions
@@ -0,0 +1,17 @@
+# Version and symbol export for libvotequorum.so
+
+COROSYNC_VOTEQUORUM_1.0 {
+ global:
+ votequorum_initialize;
+ votequorum_finalize;
+ votequorum_getinfo;
+ votequorum_setexpected;
+ votequorum_setvotes;
+ votequorum_qdevice_register;
+ votequorum_qdevice_unregister;
+ votequorum_qdevice_poll;
+ votequorum_trackstart;
+ votequorum_trackstop;
+ votequorum_context_get;
+ votequorum_context_set;
+};
diff --git a/lib/libvotequorum.verso b/lib/libvotequorum.verso
new file mode 100644
index 0000000..ae9a76b
--- /dev/null
+++ b/lib/libvotequorum.verso
@@ -0,0 +1 @@
+8.0.0
diff --git a/lib/quorum.c b/lib/quorum.c
new file mode 100644
index 0000000..c1139c0
--- /dev/null
+++ b/lib/quorum.c
@@ -0,0 +1,588 @@
+/*
+ * Copyright (c) 2008-2020 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Author: Christine Caulfield (ccaulfie@redhat.com)
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of the MontaVista Software, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+/*
+ * Provides a quorum API using the corosync executive
+ */
+
+#include <config.h>
+
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/uio.h>
+#include <errno.h>
+
+#include <qb/qbipcc.h>
+#include <corosync/corotypes.h>
+#include <corosync/corodefs.h>
+#include <corosync/hdb.h>
+
+#include <corosync/quorum.h>
+#include <corosync/ipc_quorum.h>
+
+#include "util.h"
+
+struct quorum_inst {
+ qb_ipcc_connection_t *c;
+ int finalize;
+ const void *context;
+ union {
+ quorum_model_data_t model_data;
+ quorum_model_v0_data_t model_v0_data;
+ quorum_model_v1_data_t model_v1_data;
+ };
+};
+
+static void quorum_inst_free (void *inst);
+
+DECLARE_HDB_DATABASE(quorum_handle_t_db, quorum_inst_free);
+
+cs_error_t quorum_initialize (
+ quorum_handle_t *handle,
+ quorum_callbacks_t *callbacks,
+ uint32_t *quorum_type)
+{
+ quorum_model_v0_data_t model_v0_data;
+
+ memset (&model_v0_data, 0, sizeof(quorum_model_v0_data_t));
+
+ if (callbacks) {
+ model_v0_data.quorum_notify_fn = callbacks->quorum_notify_fn;
+ }
+
+ return (quorum_model_initialize(handle, QUORUM_MODEL_V0,
+ (quorum_model_data_t *)&model_v0_data, quorum_type, NULL));
+}
+
+cs_error_t quorum_model_initialize (
+ quorum_handle_t *handle,
+ quorum_model_t model,
+ quorum_model_data_t *model_data,
+ uint32_t *quorum_type,
+ void *context)
+{
+ cs_error_t error;
+ struct quorum_inst *quorum_inst;
+ struct iovec iov;
+ struct qb_ipc_request_header quorum_gettype_req;
+ struct req_lib_quorum_model_gettype quorum_model_gettype_req;
+ struct res_lib_quorum_gettype res_lib_quorum_gettype;
+ struct res_lib_quorum_model_gettype res_lib_quorum_model_gettype;
+ uint32_t local_quorum_type;
+
+ if (model != QUORUM_MODEL_V0 && model != QUORUM_MODEL_V1) {
+ error = CS_ERR_INVALID_PARAM;
+ goto error_no_destroy;
+ }
+
+ error = hdb_error_to_cs(hdb_handle_create (&quorum_handle_t_db, sizeof (struct quorum_inst), handle));
+ if (error != CS_OK) {
+ goto error_no_destroy;
+ }
+
+ error = hdb_error_to_cs(hdb_handle_get (&quorum_handle_t_db, *handle, (void *)&quorum_inst));
+ if (error != CS_OK) {
+ goto error_destroy;
+ }
+
+ error = CS_OK;
+ quorum_inst->finalize = 0;
+ quorum_inst->c = qb_ipcc_connect ("quorum", IPC_REQUEST_SIZE);
+ if (quorum_inst->c == NULL) {
+ error = qb_to_cs_error(-errno);
+ goto error_put_destroy;
+ }
+
+ switch (model) {
+ case QUORUM_MODEL_V0:
+ quorum_gettype_req.size = sizeof (quorum_gettype_req);
+ quorum_gettype_req.id = MESSAGE_REQ_QUORUM_GETTYPE;
+
+ iov.iov_base = (char *)&quorum_gettype_req;
+ iov.iov_len = sizeof (quorum_gettype_req);
+
+ error = qb_to_cs_error(qb_ipcc_sendv_recv (
+ quorum_inst->c,
+ &iov,
+ 1,
+ &res_lib_quorum_gettype,
+ sizeof(res_lib_quorum_gettype), -1));
+
+ if (error != CS_OK) {
+ goto error_put_destroy;
+ }
+ error = res_lib_quorum_gettype.header.error;
+ local_quorum_type = res_lib_quorum_gettype.quorum_type;
+ break;
+ case QUORUM_MODEL_V1:
+ quorum_model_gettype_req.header.size = sizeof (quorum_model_gettype_req);
+ quorum_model_gettype_req.header.id = MESSAGE_REQ_QUORUM_MODEL_GETTYPE;
+ quorum_model_gettype_req.model = model;
+
+ iov.iov_base = (char *)&quorum_model_gettype_req;
+ iov.iov_len = sizeof (quorum_model_gettype_req);
+
+ error = qb_to_cs_error(qb_ipcc_sendv_recv (
+ quorum_inst->c,
+ &iov,
+ 1,
+ &res_lib_quorum_model_gettype,
+ sizeof(res_lib_quorum_model_gettype), -1));
+
+ if (error != CS_OK) {
+ goto error_put_destroy;
+ }
+ error = res_lib_quorum_model_gettype.header.error;
+ local_quorum_type = res_lib_quorum_model_gettype.quorum_type;
+ break;
+ }
+
+ if (quorum_type != NULL) {
+ *quorum_type = local_quorum_type;
+ }
+
+ if (model_data != NULL) {
+ switch (model) {
+ case QUORUM_MODEL_V0:
+ memcpy(&quorum_inst->model_v0_data, model_data, sizeof(quorum_model_v0_data_t));
+ break;
+ case QUORUM_MODEL_V1:
+ memcpy(&quorum_inst->model_v1_data, model_data, sizeof(quorum_model_v1_data_t));
+ break;
+ }
+ }
+
+ quorum_inst->model_data.model = model;
+ quorum_inst->context = context;
+
+ (void)hdb_handle_put (&quorum_handle_t_db, *handle);
+
+ return (error);
+
+error_put_destroy:
+ (void)hdb_handle_put (&quorum_handle_t_db, *handle);
+error_destroy:
+ (void)hdb_handle_destroy (&quorum_handle_t_db, *handle);
+error_no_destroy:
+ return (error);
+}
+
+static void quorum_inst_free (void *inst)
+{
+ struct quorum_inst *quorum_inst = (struct quorum_inst *)inst;
+ qb_ipcc_disconnect(quorum_inst->c);
+}
+
+cs_error_t quorum_finalize (
+ quorum_handle_t handle)
+{
+ struct quorum_inst *quorum_inst;
+ cs_error_t error;
+
+ error = hdb_error_to_cs(hdb_handle_get (&quorum_handle_t_db, handle, (void *)&quorum_inst));
+ if (error != CS_OK) {
+ return (error);
+ }
+
+ /*
+ * Another thread has already started finalizing
+ */
+ if (quorum_inst->finalize) {
+ (void)hdb_handle_put (&quorum_handle_t_db, handle);
+ return (CS_ERR_BAD_HANDLE);
+ }
+
+ quorum_inst->finalize = 1;
+
+ (void)hdb_handle_destroy (&quorum_handle_t_db, handle);
+
+ (void)hdb_handle_put (&quorum_handle_t_db, handle);
+
+ return (CS_OK);
+}
+
+cs_error_t quorum_getquorate (
+ quorum_handle_t handle,
+ int *quorate)
+{
+ cs_error_t error;
+ struct quorum_inst *quorum_inst;
+ struct iovec iov;
+ struct qb_ipc_request_header req;
+ struct res_lib_quorum_getquorate res_lib_quorum_getquorate;
+
+ error = hdb_error_to_cs(hdb_handle_get (&quorum_handle_t_db, handle, (void *)&quorum_inst));
+ if (error != CS_OK) {
+ return (error);
+ }
+
+ req.size = sizeof (req);
+ req.id = MESSAGE_REQ_QUORUM_GETQUORATE;
+
+ iov.iov_base = (char *)&req;
+ iov.iov_len = sizeof (req);
+
+ error = qb_to_cs_error(qb_ipcc_sendv_recv (
+ quorum_inst->c,
+ &iov,
+ 1,
+ &res_lib_quorum_getquorate,
+ sizeof (struct res_lib_quorum_getquorate), CS_IPC_TIMEOUT_MS));
+
+ if (error != CS_OK) {
+ goto error_exit;
+ }
+
+ error = res_lib_quorum_getquorate.header.error;
+
+ *quorate = res_lib_quorum_getquorate.quorate;
+
+error_exit:
+ (void)hdb_handle_put (&quorum_handle_t_db, handle);
+
+ return (error);
+}
+
+cs_error_t quorum_fd_get (
+ quorum_handle_t handle,
+ int *fd)
+{
+ cs_error_t error;
+ struct quorum_inst *quorum_inst;
+
+ error = hdb_error_to_cs(hdb_handle_get (&quorum_handle_t_db, handle, (void *)&quorum_inst));
+ if (error != CS_OK) {
+ return (error);
+ }
+
+ error = qb_to_cs_error(qb_ipcc_fd_get (quorum_inst->c, fd));
+
+ (void)hdb_handle_put (&quorum_handle_t_db, handle);
+
+ return (error);
+}
+
+
+cs_error_t quorum_context_get (
+ quorum_handle_t handle,
+ const void **context)
+{
+ cs_error_t error;
+ struct quorum_inst *quorum_inst;
+
+ error = hdb_error_to_cs(hdb_handle_get (&quorum_handle_t_db, handle, (void *)&quorum_inst));
+ if (error != CS_OK) {
+ return (error);
+ }
+
+ *context = quorum_inst->context;
+
+ (void)hdb_handle_put (&quorum_handle_t_db, handle);
+
+ return (CS_OK);
+}
+
+cs_error_t quorum_context_set (
+ quorum_handle_t handle,
+ const void *context)
+{
+ cs_error_t error;
+ struct quorum_inst *quorum_inst;
+
+ error = hdb_error_to_cs(hdb_handle_get (&quorum_handle_t_db, handle, (void *)&quorum_inst));
+ if (error != CS_OK) {
+ return (error);
+ }
+
+ quorum_inst->context = context;
+
+ (void)hdb_handle_put (&quorum_handle_t_db, handle);
+
+ return (CS_OK);
+}
+
+
+cs_error_t quorum_trackstart (
+ quorum_handle_t handle,
+ unsigned int flags )
+{
+ cs_error_t error;
+ struct quorum_inst *quorum_inst;
+ struct iovec iov;
+ struct req_lib_quorum_trackstart req_lib_quorum_trackstart;
+ struct qb_ipc_response_header res;
+
+ error = hdb_error_to_cs(hdb_handle_get (&quorum_handle_t_db, handle, (void *)&quorum_inst));
+ if (error != CS_OK) {
+ return (error);
+ }
+
+ req_lib_quorum_trackstart.header.size = sizeof (struct req_lib_quorum_trackstart);
+ req_lib_quorum_trackstart.header.id = MESSAGE_REQ_QUORUM_TRACKSTART;
+ req_lib_quorum_trackstart.track_flags = flags;
+
+ iov.iov_base = (char *)&req_lib_quorum_trackstart;
+ iov.iov_len = sizeof (struct req_lib_quorum_trackstart);
+
+ error = qb_to_cs_error(qb_ipcc_sendv_recv (
+ quorum_inst->c,
+ &iov,
+ 1,
+ &res,
+ sizeof (res), CS_IPC_TIMEOUT_MS));
+
+ if (error != CS_OK) {
+ goto error_exit;
+ }
+
+ error = res.error;
+
+error_exit:
+ (void)hdb_handle_put (&quorum_handle_t_db, handle);
+
+ return (error);
+}
+
+cs_error_t quorum_trackstop (
+ quorum_handle_t handle)
+{
+ cs_error_t error;
+ struct quorum_inst *quorum_inst;
+ struct iovec iov;
+ struct qb_ipc_request_header req;
+ struct qb_ipc_response_header res;
+
+ error = hdb_error_to_cs(hdb_handle_get (&quorum_handle_t_db, handle, (void *)&quorum_inst));
+ if (error != CS_OK) {
+ return (error);
+ }
+
+ req.size = sizeof (req);
+ req.id = MESSAGE_REQ_QUORUM_TRACKSTOP;
+
+ iov.iov_base = (char *)&req;
+ iov.iov_len = sizeof (req);
+
+ error = qb_to_cs_error(qb_ipcc_sendv_recv (
+ quorum_inst->c,
+ &iov,
+ 1,
+ &res,
+ sizeof (res), CS_IPC_TIMEOUT_MS));
+
+ if (error != CS_OK) {
+ goto error_exit;
+ }
+
+ error = res.error;
+
+error_exit:
+ (void)hdb_handle_put (&quorum_handle_t_db, handle);
+
+ return (error);
+}
+
+cs_error_t quorum_dispatch (
+ quorum_handle_t handle,
+ cs_dispatch_flags_t dispatch_types)
+{
+ int timeout = -1;
+ cs_error_t error;
+ int cont = 1; /* always continue do loop except when set to 0 */
+ struct quorum_inst *quorum_inst;
+ struct quorum_inst quorum_inst_copy;
+ struct qb_ipc_response_header *dispatch_data;
+ char dispatch_buf[IPC_DISPATCH_SIZE];
+ struct res_lib_quorum_notification *res_lib_quorum_notification;
+ struct res_lib_quorum_v1_quorum_notification *res_lib_quorum_v1_quorum_notification;
+ struct res_lib_quorum_v1_nodelist_notification *res_lib_quorum_v1_nodelist_notification;
+ struct quorum_ring_id ring_id;
+ mar_uint32_t *joined_list;
+ mar_uint32_t *left_list;
+
+ if (dispatch_types != CS_DISPATCH_ONE &&
+ dispatch_types != CS_DISPATCH_ALL &&
+ dispatch_types != CS_DISPATCH_BLOCKING &&
+ dispatch_types != CS_DISPATCH_ONE_NONBLOCKING) {
+
+ return (CS_ERR_INVALID_PARAM);
+ }
+
+ error = hdb_error_to_cs(hdb_handle_get (&quorum_handle_t_db, handle,
+ (void *)&quorum_inst));
+ if (error != CS_OK) {
+ return (error);
+ }
+
+ /*
+ * Timeout instantly for CS_DISPATCH_ONE_NONBLOCKING or CS_DISPATCH_ALL and
+ * wait indefinately for CS_DISPATCH_ONE or CS_DISPATCH_BLOCKING
+ */
+ if (dispatch_types == CS_DISPATCH_ALL || dispatch_types == CS_DISPATCH_ONE_NONBLOCKING) {
+ timeout = 0;
+ }
+
+ dispatch_data = (struct qb_ipc_response_header *)dispatch_buf;
+ do {
+ error = qb_to_cs_error (qb_ipcc_event_recv (
+ quorum_inst->c,
+ dispatch_buf,
+ IPC_DISPATCH_SIZE,
+ timeout));
+ if (error == CS_ERR_BAD_HANDLE) {
+ error = CS_OK;
+ goto error_put;
+ }
+ if (error == CS_ERR_TRY_AGAIN) {
+ if (dispatch_types == CS_DISPATCH_ONE_NONBLOCKING) {
+ /*
+ * Don't mask error
+ */
+ goto error_put;
+ }
+ error = CS_OK;
+ if (dispatch_types == CS_DISPATCH_ALL) {
+ break; /* exit do while cont is 1 loop */
+ } else {
+ continue; /* next poll */
+ }
+ }
+ if (error != CS_OK) {
+ goto error_put;
+ }
+
+ /*
+ * Make copy of callbacks, message data, unlock instance, and call callback
+ * A risk of this dispatch method is that the callback routines may
+ * operate at the same time that quorum_finalize has been called in another thread.
+ */
+ memcpy (&quorum_inst_copy, quorum_inst, sizeof(quorum_inst_copy));
+ switch (quorum_inst_copy.model_data.model) {
+ case QUORUM_MODEL_V0:
+ /*
+ * Dispatch incoming message
+ */
+ switch (dispatch_data->id) {
+ case MESSAGE_RES_QUORUM_NOTIFICATION:
+ if (quorum_inst_copy.model_v0_data.quorum_notify_fn == NULL) {
+ break;
+ }
+ res_lib_quorum_notification = (struct res_lib_quorum_notification *)dispatch_data;
+
+ quorum_inst_copy.model_v0_data.quorum_notify_fn ( handle,
+ res_lib_quorum_notification->quorate,
+ res_lib_quorum_notification->ring_seq,
+ res_lib_quorum_notification->view_list_entries,
+ res_lib_quorum_notification->view_list);
+ break;
+ default:
+ error = CS_ERR_LIBRARY;
+ goto error_put;
+ break;
+ } /* switch (dispatch_data->id) */
+ break; /* case QUORUM_MODEL_V0 */
+ case QUORUM_MODEL_V1:
+ /*
+ * Dispatch incoming message
+ */
+ switch (dispatch_data->id) {
+ case MESSAGE_RES_QUORUM_V1_QUORUM_NOTIFICATION:
+ if (quorum_inst_copy.model_v1_data.quorum_notify_fn == NULL) {
+ break;
+ }
+ res_lib_quorum_v1_quorum_notification =
+ (struct res_lib_quorum_v1_quorum_notification *)dispatch_data;
+
+ ring_id.nodeid = res_lib_quorum_v1_quorum_notification->ring_id.nodeid;
+ ring_id.seq = res_lib_quorum_v1_quorum_notification->ring_id.seq;
+
+ quorum_inst_copy.model_v1_data.quorum_notify_fn ( handle,
+ res_lib_quorum_v1_quorum_notification->quorate,
+ ring_id,
+ res_lib_quorum_v1_quorum_notification->view_list_entries,
+ res_lib_quorum_v1_quorum_notification->view_list);
+ break;
+ case MESSAGE_RES_QUORUM_V1_NODELIST_NOTIFICATION:
+ if (quorum_inst_copy.model_v1_data.nodelist_notify_fn == NULL) {
+ break;
+ }
+ res_lib_quorum_v1_nodelist_notification =
+ (struct res_lib_quorum_v1_nodelist_notification *)dispatch_data;
+
+ ring_id.nodeid = res_lib_quorum_v1_nodelist_notification->ring_id.nodeid;
+ ring_id.seq = res_lib_quorum_v1_nodelist_notification->ring_id.seq;
+
+ joined_list = res_lib_quorum_v1_nodelist_notification->member_list +
+ res_lib_quorum_v1_nodelist_notification->member_list_entries;
+ left_list = joined_list +
+ res_lib_quorum_v1_nodelist_notification->joined_list_entries;
+
+ quorum_inst_copy.model_v1_data.nodelist_notify_fn ( handle,
+ ring_id,
+ res_lib_quorum_v1_nodelist_notification->member_list_entries,
+ res_lib_quorum_v1_nodelist_notification->member_list,
+ res_lib_quorum_v1_nodelist_notification->joined_list_entries,
+ joined_list,
+ res_lib_quorum_v1_nodelist_notification->left_list_entries,
+ left_list);
+ break;
+ default:
+ error = CS_ERR_LIBRARY;
+ goto error_put;
+ break;
+ } /* switch (dispatch_data->id) */
+ break; /* case QUORUM_MODEL_V1 */
+ }
+ if (quorum_inst->finalize) {
+ /*
+ * If the finalize has been called then get out of the dispatch.
+ */
+ error = CS_ERR_BAD_HANDLE;
+ goto error_put;
+ }
+
+ /*
+ * Determine if more messages should be processed
+ */
+ if (dispatch_types == CS_DISPATCH_ONE || dispatch_types == CS_DISPATCH_ONE_NONBLOCKING) {
+ cont = 0;
+ }
+ } while (cont);
+
+error_put:
+ (void)hdb_handle_put (&quorum_handle_t_db, handle);
+ return (error);
+}
diff --git a/lib/sam.c b/lib/sam.c
new file mode 100644
index 0000000..94dbf2a
--- /dev/null
+++ b/lib/sam.c
@@ -0,0 +1,1489 @@
+/*
+ * Copyright (c) 2009-2011 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Author: Jan Friesse (jfriesse@redhat.com)
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of the Red Hat, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Provides a SAM API
+ */
+
+#include <config.h>
+
+#include <limits.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <errno.h>
+#include <poll.h>
+
+#include <corosync/corotypes.h>
+#include <qb/qbipcc.h>
+#include <corosync/corodefs.h>
+#include <corosync/cmap.h>
+#include <corosync/hdb.h>
+#include <corosync/quorum.h>
+
+#include <corosync/sam.h>
+
+#include "util.h"
+
+#include <stdio.h>
+#include <sys/wait.h>
+#include <signal.h>
+
+#define SAM_CMAP_S_FAILED "failed"
+#define SAM_CMAP_S_REGISTERED "stopped"
+#define SAM_CMAP_S_STARTED "running"
+#define SAM_CMAP_S_Q_WAIT "waiting for quorum"
+
+#define SAM_RP_MASK_Q(pol) (pol & (~SAM_RECOVERY_POLICY_QUORUM))
+#define SAM_RP_MASK_C(pol) (pol & (~SAM_RECOVERY_POLICY_CMAP))
+#define SAM_RP_MASK(pol) (pol & (~(SAM_RECOVERY_POLICY_QUORUM | SAM_RECOVERY_POLICY_CMAP)))
+
+enum sam_internal_status_t {
+ SAM_INTERNAL_STATUS_NOT_INITIALIZED = 0,
+ SAM_INTERNAL_STATUS_INITIALIZED,
+ SAM_INTERNAL_STATUS_REGISTERED,
+ SAM_INTERNAL_STATUS_STARTED,
+ SAM_INTERNAL_STATUS_FINALIZED
+};
+
+enum sam_command_t {
+ SAM_COMMAND_START,
+ SAM_COMMAND_STOP,
+ SAM_COMMAND_HB,
+ SAM_COMMAND_DATA_STORE,
+ SAM_COMMAND_WARN_SIGNAL_SET,
+ SAM_COMMAND_MARK_FAILED,
+};
+
+enum sam_reply_t {
+ SAM_REPLY_OK,
+ SAM_REPLY_ERROR,
+};
+
+enum sam_parent_action_t {
+ SAM_PARENT_ACTION_ERROR,
+ SAM_PARENT_ACTION_RECOVERY,
+ SAM_PARENT_ACTION_QUIT,
+ SAM_PARENT_ACTION_CONTINUE
+};
+
+enum sam_cmap_key_t {
+ SAM_CMAP_KEY_RECOVERY,
+ SAM_CMAP_KEY_HC_PERIOD,
+ SAM_CMAP_KEY_LAST_HC,
+ SAM_CMAP_KEY_STATE,
+};
+
+static struct {
+ int time_interval;
+ sam_recovery_policy_t recovery_policy;
+ enum sam_internal_status_t internal_status;
+ unsigned int instance_id;
+ int child_fd_out;
+ int child_fd_in;
+ int term_send;
+ int warn_signal;
+ int am_i_child;
+
+ sam_hc_callback_t hc_callback;
+ pthread_t cb_thread;
+ int cb_rpipe_fd, cb_wpipe_fd;
+ int cb_registered;
+
+ void *user_data;
+ size_t user_data_size;
+ size_t user_data_allocated;
+
+ pthread_mutex_t lock;
+
+ quorum_handle_t quorum_handle;
+ uint32_t quorate;
+ int quorum_fd;
+
+ cmap_handle_t cmap_handle;
+ char cmap_pid_path[CMAP_KEYNAME_MAXLEN];
+} sam_internal_data;
+
+extern const char *__progname;
+
+static cs_error_t sam_cmap_update_key (enum sam_cmap_key_t key, const char *value)
+{
+ cs_error_t err;
+ const char *svalue;
+ uint64_t hc_period, last_hc;
+
+ const char *ssvalue[] = { [SAM_RECOVERY_POLICY_QUIT] = "quit", [SAM_RECOVERY_POLICY_RESTART] = "restart" };
+ char key_name[CMAP_KEYNAME_MAXLEN];
+
+ switch (key) {
+ case SAM_CMAP_KEY_RECOVERY:
+ svalue = ssvalue[SAM_RP_MASK (sam_internal_data.recovery_policy)];
+
+ if (snprintf(key_name, CMAP_KEYNAME_MAXLEN, "%s%s", sam_internal_data.cmap_pid_path,
+ "recovery") >= CMAP_KEYNAME_MAXLEN) {
+
+ err = CS_ERR_NAME_TOO_LONG;
+ goto exit_error;
+ }
+
+ if ((err = cmap_set_string(sam_internal_data.cmap_handle, key_name, svalue)) != CS_OK) {
+ goto exit_error;
+ }
+ break;
+ case SAM_CMAP_KEY_HC_PERIOD:
+ hc_period = sam_internal_data.time_interval;
+
+ if (snprintf(key_name, CMAP_KEYNAME_MAXLEN, "%s%s", sam_internal_data.cmap_pid_path,
+ "poll_period") >= CMAP_KEYNAME_MAXLEN) {
+
+ err = CS_ERR_NAME_TOO_LONG;
+ goto exit_error;
+ }
+
+ if ((err = cmap_set_uint64(sam_internal_data.cmap_handle, key_name, hc_period)) != CS_OK) {
+ goto exit_error;
+ }
+ break;
+ case SAM_CMAP_KEY_LAST_HC:
+ last_hc = cs_timestamp_get();
+
+ if (snprintf(key_name, CMAP_KEYNAME_MAXLEN, "%s%s", sam_internal_data.cmap_pid_path,
+ "last_updated") >= CMAP_KEYNAME_MAXLEN) {
+
+ err = CS_ERR_NAME_TOO_LONG;
+ goto exit_error;
+ }
+ if ((err = cmap_set_uint64(sam_internal_data.cmap_handle, key_name, last_hc)) != CS_OK) {
+ goto exit_error;
+ }
+ break;
+ case SAM_CMAP_KEY_STATE:
+ svalue = value;
+ if (snprintf(key_name, CMAP_KEYNAME_MAXLEN, "%s%s", sam_internal_data.cmap_pid_path,
+ "state") >= CMAP_KEYNAME_MAXLEN) {
+
+ err = CS_ERR_NAME_TOO_LONG;
+ goto exit_error;
+ }
+
+ if ((err = cmap_set_string(sam_internal_data.cmap_handle, key_name, svalue)) != CS_OK) {
+ goto exit_error;
+ }
+ break;
+ }
+
+ return (CS_OK);
+
+exit_error:
+ return (err);
+}
+
+static cs_error_t sam_cmap_destroy_pid_path (void)
+{
+ cmap_iter_handle_t iter;
+ cs_error_t err;
+ char key_name[CMAP_KEYNAME_MAXLEN + 1];
+
+ err = cmap_iter_init(sam_internal_data.cmap_handle, sam_internal_data.cmap_pid_path, &iter);
+ if (err != CS_OK) {
+ goto error_exit;
+ }
+
+ while ((err = cmap_iter_next(sam_internal_data.cmap_handle, iter, key_name, NULL, NULL)) == CS_OK) {
+ cmap_delete(sam_internal_data.cmap_handle, key_name);
+ }
+
+ err = cmap_iter_finalize(sam_internal_data.cmap_handle, iter);
+
+error_exit:
+ return (err);
+}
+
+static cs_error_t sam_cmap_register (void)
+{
+ cs_error_t err;
+ cmap_handle_t cmap_handle;
+
+ if ((err = cmap_initialize (&cmap_handle)) != CS_OK) {
+ return (err);
+ }
+
+ snprintf(sam_internal_data.cmap_pid_path, CMAP_KEYNAME_MAXLEN, "resources.process.%d.", getpid());
+
+ sam_internal_data.cmap_handle = cmap_handle;
+
+ if ((err = sam_cmap_update_key (SAM_CMAP_KEY_RECOVERY, NULL)) != CS_OK) {
+ goto destroy_finalize_error;
+ }
+
+ if ((err = sam_cmap_update_key (SAM_CMAP_KEY_HC_PERIOD, NULL)) != CS_OK) {
+ goto destroy_finalize_error;
+ }
+
+ return (CS_OK);
+
+destroy_finalize_error:
+ sam_cmap_destroy_pid_path ();
+ cmap_finalize (cmap_handle);
+ return (err);
+}
+
+static void quorum_notification_fn (
+ quorum_handle_t handle,
+ uint32_t quorate,
+ uint64_t ring_id,
+ uint32_t view_list_entries,
+ uint32_t *view_list)
+{
+ sam_internal_data.quorate = quorate;
+}
+
+cs_error_t sam_initialize (
+ int time_interval,
+ sam_recovery_policy_t recovery_policy)
+{
+ quorum_callbacks_t quorum_callbacks;
+ uint32_t quorum_type;
+ cs_error_t err;
+
+ if (sam_internal_data.internal_status != SAM_INTERNAL_STATUS_NOT_INITIALIZED) {
+ return (CS_ERR_BAD_HANDLE);
+ }
+
+ if (SAM_RP_MASK (recovery_policy) != SAM_RECOVERY_POLICY_QUIT &&
+ SAM_RP_MASK (recovery_policy) != SAM_RECOVERY_POLICY_RESTART) {
+ return (CS_ERR_INVALID_PARAM);
+ }
+
+ if (recovery_policy & SAM_RECOVERY_POLICY_QUORUM) {
+ /*
+ * Initialize quorum
+ */
+ quorum_callbacks.quorum_notify_fn = quorum_notification_fn;
+ if ((err = quorum_initialize (&sam_internal_data.quorum_handle, &quorum_callbacks, &quorum_type)) != CS_OK) {
+ goto exit_error;
+ }
+
+ if ((err = quorum_trackstart (sam_internal_data.quorum_handle, CS_TRACK_CHANGES)) != CS_OK) {
+ goto exit_error_quorum;
+ }
+
+ if ((err = quorum_fd_get (sam_internal_data.quorum_handle, &sam_internal_data.quorum_fd)) != CS_OK) {
+ goto exit_error_quorum;
+ }
+
+ /*
+ * Dispatch initial quorate state
+ */
+ if ((err = quorum_dispatch (sam_internal_data.quorum_handle, CS_DISPATCH_ONE)) != CS_OK) {
+ goto exit_error_quorum;
+ }
+ }
+ sam_internal_data.recovery_policy = recovery_policy;
+
+ sam_internal_data.time_interval = time_interval;
+
+ sam_internal_data.internal_status = SAM_INTERNAL_STATUS_INITIALIZED;
+
+ sam_internal_data.warn_signal = SIGTERM;
+
+ sam_internal_data.am_i_child = 0;
+
+ sam_internal_data.user_data = NULL;
+ sam_internal_data.user_data_size = 0;
+ sam_internal_data.user_data_allocated = 0;
+
+ pthread_mutex_init (&sam_internal_data.lock, NULL);
+
+ return (CS_OK);
+
+exit_error_quorum:
+ quorum_finalize (sam_internal_data.quorum_handle);
+exit_error:
+ return (err);
+}
+
+/*
+ * Wrapper on top of write(2) function. It handles EAGAIN and EINTR states and sends whole buffer if possible.
+ */
+static size_t sam_safe_write (
+ int d,
+ const void *buf,
+ size_t nbyte)
+{
+ ssize_t bytes_write;
+ ssize_t tmp_bytes_write;
+
+ bytes_write = 0;
+
+ do {
+ tmp_bytes_write = write (d, (const char *)buf + bytes_write,
+ (nbyte - bytes_write > SSIZE_MAX) ? SSIZE_MAX : nbyte - bytes_write);
+
+ if (tmp_bytes_write == -1) {
+ if (!(errno == EAGAIN || errno == EINTR))
+ return -1;
+ } else {
+ bytes_write += tmp_bytes_write;
+ }
+ } while (bytes_write != nbyte);
+
+ return (bytes_write);
+}
+
+/*
+ * Wrapper on top of read(2) function. It handles EAGAIN and EINTR states and reads whole buffer if possible.
+ */
+static size_t sam_safe_read (
+ int d,
+ void *buf,
+ size_t nbyte)
+{
+ ssize_t bytes_read;
+ ssize_t tmp_bytes_read;
+
+ bytes_read = 0;
+
+ do {
+ tmp_bytes_read = read (d, (char *)buf + bytes_read,
+ (nbyte - bytes_read > SSIZE_MAX) ? SSIZE_MAX : nbyte - bytes_read);
+
+ if (tmp_bytes_read == -1) {
+ if (!(errno == EAGAIN || errno == EINTR))
+ return -1;
+ } else {
+ bytes_read += tmp_bytes_read;
+ }
+
+ } while (bytes_read != nbyte && tmp_bytes_read != 0);
+
+ return (bytes_read);
+}
+
+static cs_error_t sam_read_reply (
+ int child_fd_in)
+{
+ char reply;
+ cs_error_t err;
+
+ if (sam_safe_read (sam_internal_data.child_fd_in, &reply, sizeof (reply)) != sizeof (reply)) {
+ return (CS_ERR_LIBRARY);
+ }
+
+ switch (reply) {
+ case SAM_REPLY_ERROR:
+ /*
+ * Read error and return that
+ */
+ if (sam_safe_read (sam_internal_data.child_fd_in, &err, sizeof (err)) != sizeof (err)) {
+ return (CS_ERR_LIBRARY);
+ }
+
+ return (err);
+ break;
+ case SAM_REPLY_OK:
+ /*
+ * Everything correct
+ */
+ break;
+ default:
+ return (CS_ERR_LIBRARY);
+ break;
+ }
+
+ return (CS_OK);
+}
+
+cs_error_t sam_data_getsize (size_t *size)
+{
+ if (size == NULL) {
+ return (CS_ERR_INVALID_PARAM);
+ }
+
+ if (sam_internal_data.internal_status != SAM_INTERNAL_STATUS_INITIALIZED &&
+ sam_internal_data.internal_status != SAM_INTERNAL_STATUS_REGISTERED &&
+ sam_internal_data.internal_status != SAM_INTERNAL_STATUS_STARTED) {
+
+ return (CS_ERR_BAD_HANDLE);
+ }
+
+ pthread_mutex_lock (&sam_internal_data.lock);
+
+ *size = sam_internal_data.user_data_size;
+
+ pthread_mutex_unlock (&sam_internal_data.lock);
+
+ return (CS_OK);
+}
+
+cs_error_t sam_data_restore (
+ void *data,
+ size_t size)
+{
+ cs_error_t err;
+
+ err = CS_OK;
+
+ if (data == NULL) {
+ return (CS_ERR_INVALID_PARAM);
+ }
+
+ if (sam_internal_data.internal_status != SAM_INTERNAL_STATUS_INITIALIZED &&
+ sam_internal_data.internal_status != SAM_INTERNAL_STATUS_REGISTERED &&
+ sam_internal_data.internal_status != SAM_INTERNAL_STATUS_STARTED) {
+
+ return (CS_ERR_BAD_HANDLE);
+ }
+
+ pthread_mutex_lock (&sam_internal_data.lock);
+
+ if (sam_internal_data.user_data_size == 0) {
+ err = CS_OK;
+
+ goto error_unlock;
+ }
+
+ if (size < sam_internal_data.user_data_size) {
+ err = CS_ERR_INVALID_PARAM;
+
+ goto error_unlock;
+ }
+
+ memcpy (data, sam_internal_data.user_data, sam_internal_data.user_data_size);
+
+ pthread_mutex_unlock (&sam_internal_data.lock);
+
+ return (CS_OK);
+
+error_unlock:
+ pthread_mutex_unlock (&sam_internal_data.lock);
+
+ return (err);
+}
+
+cs_error_t sam_data_store (
+ const void *data,
+ size_t size)
+{
+ cs_error_t err;
+ char command;
+ char *new_data;
+
+ if (sam_internal_data.internal_status != SAM_INTERNAL_STATUS_INITIALIZED &&
+ sam_internal_data.internal_status != SAM_INTERNAL_STATUS_REGISTERED &&
+ sam_internal_data.internal_status != SAM_INTERNAL_STATUS_STARTED) {
+
+ return (CS_ERR_BAD_HANDLE);
+ }
+
+
+ if (data == NULL) {
+ size = 0;
+ }
+
+ pthread_mutex_lock (&sam_internal_data.lock);
+
+ if (sam_internal_data.am_i_child) {
+ /*
+ * We are child so we must send data to parent
+ */
+ command = SAM_COMMAND_DATA_STORE;
+ if (sam_safe_write (sam_internal_data.child_fd_out, &command, sizeof (command)) != sizeof (command)) {
+ err = CS_ERR_LIBRARY;
+
+ goto error_unlock;
+ }
+
+ if (sam_safe_write (sam_internal_data.child_fd_out, &size, sizeof (size)) != sizeof (size)) {
+ err = CS_ERR_LIBRARY;
+
+ goto error_unlock;
+ }
+
+ if (data != NULL && sam_safe_write (sam_internal_data.child_fd_out, data, size) != size) {
+ err = CS_ERR_LIBRARY;
+
+ goto error_unlock;
+ }
+
+ /*
+ * And wait for reply
+ */
+ if ((err = sam_read_reply (sam_internal_data.child_fd_in)) != CS_OK) {
+ goto error_unlock;
+ }
+ }
+
+ /*
+ * We are parent or we received OK reply from parent -> do required action
+ */
+ if (data == NULL) {
+ free (sam_internal_data.user_data);
+ sam_internal_data.user_data = NULL;
+ sam_internal_data.user_data_allocated = 0;
+ sam_internal_data.user_data_size = 0;
+ } else {
+ if (sam_internal_data.user_data_allocated < size) {
+ if ((new_data = realloc (sam_internal_data.user_data, size)) == NULL) {
+ err = CS_ERR_NO_MEMORY;
+
+ goto error_unlock;
+ }
+
+ sam_internal_data.user_data_allocated = size;
+ } else {
+ new_data = sam_internal_data.user_data;
+ }
+ sam_internal_data.user_data = new_data;
+ sam_internal_data.user_data_size = size;
+
+ memcpy (sam_internal_data.user_data, data, size);
+ }
+
+ pthread_mutex_unlock (&sam_internal_data.lock);
+
+ return (CS_OK);
+
+error_unlock:
+ pthread_mutex_unlock (&sam_internal_data.lock);
+
+ return (err);
+}
+
+cs_error_t sam_start (void)
+{
+ char command;
+ cs_error_t err;
+ sam_recovery_policy_t recpol;
+
+ if (sam_internal_data.internal_status != SAM_INTERNAL_STATUS_REGISTERED) {
+ return (CS_ERR_BAD_HANDLE);
+ }
+
+ recpol = sam_internal_data.recovery_policy;
+
+ if (recpol & SAM_RECOVERY_POLICY_QUORUM || recpol & SAM_RECOVERY_POLICY_CMAP) {
+ pthread_mutex_lock (&sam_internal_data.lock);
+ }
+
+ command = SAM_COMMAND_START;
+
+ if (sam_safe_write (sam_internal_data.child_fd_out, &command, sizeof (command)) != sizeof (command)) {
+ if (recpol & SAM_RECOVERY_POLICY_QUORUM || recpol & SAM_RECOVERY_POLICY_CMAP) {
+ pthread_mutex_unlock (&sam_internal_data.lock);
+ }
+
+ return (CS_ERR_LIBRARY);
+ }
+
+ if (recpol & SAM_RECOVERY_POLICY_QUORUM || recpol & SAM_RECOVERY_POLICY_CMAP) {
+ /*
+ * Wait for parent reply
+ */
+ if ((err = sam_read_reply (sam_internal_data.child_fd_in)) != CS_OK) {
+ pthread_mutex_unlock (&sam_internal_data.lock);
+
+ return (err);
+ }
+
+ pthread_mutex_unlock (&sam_internal_data.lock);
+ }
+
+ if (sam_internal_data.hc_callback)
+ if (sam_safe_write (sam_internal_data.cb_wpipe_fd, &command, sizeof (command)) != sizeof (command))
+ return (CS_ERR_LIBRARY);
+
+ sam_internal_data.internal_status = SAM_INTERNAL_STATUS_STARTED;
+
+ return (CS_OK);
+}
+
+cs_error_t sam_stop (void)
+{
+ char command;
+ cs_error_t err;
+
+ if (sam_internal_data.internal_status != SAM_INTERNAL_STATUS_STARTED) {
+ return (CS_ERR_BAD_HANDLE);
+ }
+
+ command = SAM_COMMAND_STOP;
+
+ if (sam_internal_data.recovery_policy & SAM_RECOVERY_POLICY_CMAP) {
+ pthread_mutex_lock (&sam_internal_data.lock);
+ }
+
+ if (sam_safe_write (sam_internal_data.child_fd_out, &command, sizeof (command)) != sizeof (command)) {
+ if (sam_internal_data.recovery_policy & SAM_RECOVERY_POLICY_CMAP) {
+ pthread_mutex_unlock (&sam_internal_data.lock);
+ }
+
+ return (CS_ERR_LIBRARY);
+ }
+
+ if (sam_internal_data.recovery_policy & SAM_RECOVERY_POLICY_CMAP) {
+ /*
+ * Wait for parent reply
+ */
+ if ((err = sam_read_reply (sam_internal_data.child_fd_in)) != CS_OK) {
+ pthread_mutex_unlock (&sam_internal_data.lock);
+
+ return (err);
+ }
+
+ pthread_mutex_unlock (&sam_internal_data.lock);
+ }
+
+ if (sam_internal_data.hc_callback)
+ if (sam_safe_write (sam_internal_data.cb_wpipe_fd, &command, sizeof (command)) != sizeof (command))
+ return (CS_ERR_LIBRARY);
+
+ sam_internal_data.internal_status = SAM_INTERNAL_STATUS_REGISTERED;
+
+ return (CS_OK);
+}
+
+cs_error_t sam_hc_send (void)
+{
+ char command;
+
+ if (sam_internal_data.internal_status != SAM_INTERNAL_STATUS_STARTED) {
+ return (CS_ERR_BAD_HANDLE);
+ }
+
+ command = SAM_COMMAND_HB;
+
+ if (sam_safe_write (sam_internal_data.child_fd_out, &command, sizeof (command)) != sizeof (command))
+ return (CS_ERR_LIBRARY);
+
+ return (CS_OK);
+}
+
+cs_error_t sam_finalize (void)
+{
+ cs_error_t error;
+
+ if (sam_internal_data.internal_status != SAM_INTERNAL_STATUS_INITIALIZED &&
+ sam_internal_data.internal_status != SAM_INTERNAL_STATUS_REGISTERED &&
+ sam_internal_data.internal_status != SAM_INTERNAL_STATUS_STARTED) {
+ return (CS_ERR_BAD_HANDLE);
+ }
+
+ if (sam_internal_data.internal_status == SAM_INTERNAL_STATUS_STARTED) {
+ error = sam_stop ();
+ if (error != CS_OK)
+ goto exit_error;
+ }
+
+ sam_internal_data.internal_status = SAM_INTERNAL_STATUS_FINALIZED;
+
+ free (sam_internal_data.user_data);
+
+exit_error:
+ return (CS_OK);
+}
+
+cs_error_t sam_mark_failed (void)
+{
+ char command;
+
+ if (sam_internal_data.internal_status != SAM_INTERNAL_STATUS_STARTED &&
+ sam_internal_data.internal_status != SAM_INTERNAL_STATUS_REGISTERED) {
+ return (CS_ERR_BAD_HANDLE);
+ }
+
+ if (!(sam_internal_data.recovery_policy & SAM_RECOVERY_POLICY_CMAP)) {
+ return (CS_ERR_INVALID_PARAM);
+ }
+
+ command = SAM_COMMAND_MARK_FAILED;
+
+ if (sam_safe_write (sam_internal_data.child_fd_out, &command, sizeof (command)) != sizeof (command))
+ return (CS_ERR_LIBRARY);
+
+ return (CS_OK);
+}
+
+cs_error_t sam_warn_signal_set (int warn_signal)
+{
+ char command;
+ cs_error_t err;
+
+ if (sam_internal_data.internal_status != SAM_INTERNAL_STATUS_INITIALIZED &&
+ sam_internal_data.internal_status != SAM_INTERNAL_STATUS_REGISTERED &&
+ sam_internal_data.internal_status != SAM_INTERNAL_STATUS_STARTED) {
+ return (CS_ERR_BAD_HANDLE);
+ }
+
+ pthread_mutex_lock (&sam_internal_data.lock);
+
+ if (sam_internal_data.am_i_child) {
+ /*
+ * We are child so we must send data to parent
+ */
+ command = SAM_COMMAND_WARN_SIGNAL_SET;
+ if (sam_safe_write (sam_internal_data.child_fd_out, &command, sizeof (command)) != sizeof (command)) {
+ err = CS_ERR_LIBRARY;
+
+ goto error_unlock;
+ }
+
+ if (sam_safe_write (sam_internal_data.child_fd_out, &warn_signal, sizeof (warn_signal)) !=
+ sizeof (warn_signal)) {
+ err = CS_ERR_LIBRARY;
+
+ goto error_unlock;
+ }
+
+ /*
+ * And wait for reply
+ */
+ if ((err = sam_read_reply (sam_internal_data.child_fd_in)) != CS_OK) {
+ goto error_unlock;
+ }
+ }
+
+ /*
+ * We are parent or we received OK reply from parent -> do required action
+ */
+ sam_internal_data.warn_signal = warn_signal;
+
+ pthread_mutex_unlock (&sam_internal_data.lock);
+
+ return (CS_OK);
+
+error_unlock:
+ pthread_mutex_unlock (&sam_internal_data.lock);
+
+ return (err);
+}
+
+static cs_error_t sam_parent_reply_send (
+ cs_error_t err,
+ int parent_fd_in,
+ int parent_fd_out)
+{
+ char reply;
+
+ if (err == CS_OK) {
+ reply = SAM_REPLY_OK;
+
+ if (sam_safe_write (parent_fd_out, &reply, sizeof (reply)) != sizeof (reply)) {
+ err = CS_ERR_LIBRARY;
+ goto error_reply;
+ }
+
+ return (CS_OK);
+ }
+
+error_reply:
+ reply = SAM_REPLY_ERROR;
+ if (sam_safe_write (parent_fd_out, &reply, sizeof (reply)) != sizeof (reply)) {
+ return (CS_ERR_LIBRARY);
+ }
+ if (sam_safe_write (parent_fd_out, &err, sizeof (err)) != sizeof (err)) {
+ return (CS_ERR_LIBRARY);
+ }
+
+ return (err);
+}
+
+
+static cs_error_t sam_parent_warn_signal_set (
+ int parent_fd_in,
+ int parent_fd_out)
+{
+ int warn_signal;
+ cs_error_t err;
+
+ err = CS_OK;
+
+ if (sam_safe_read (parent_fd_in, &warn_signal, sizeof (warn_signal)) != sizeof (warn_signal)) {
+ err = CS_ERR_LIBRARY;
+ goto error_reply;
+ }
+
+ err = sam_warn_signal_set (warn_signal);
+ if (err != CS_OK) {
+ goto error_reply;
+ }
+
+
+ return (sam_parent_reply_send (CS_OK, parent_fd_in, parent_fd_out));
+
+error_reply:
+ return (sam_parent_reply_send (err, parent_fd_in, parent_fd_out));
+}
+
+static cs_error_t sam_parent_wait_for_quorum (
+ int parent_fd_in,
+ int parent_fd_out)
+{
+ cs_error_t err;
+ struct pollfd pfds[2];
+ int poll_err;
+
+ if (sam_internal_data.recovery_policy & SAM_RECOVERY_POLICY_CMAP) {
+ if ((err = sam_cmap_update_key (SAM_CMAP_KEY_STATE, SAM_CMAP_S_Q_WAIT)) != CS_OK) {
+ goto error_reply;
+ }
+ }
+
+ /*
+ * Update current quorum
+ */
+ if ((err = quorum_dispatch (sam_internal_data.quorum_handle, CS_DISPATCH_ALL)) != CS_OK) {
+ goto error_reply;
+ }
+
+ /*
+ * Wait for quorum
+ */
+ while (!sam_internal_data.quorate) {
+ pfds[0].fd = parent_fd_in;
+ pfds[0].events = 0;
+ pfds[0].revents = 0;
+
+ pfds[1].fd = sam_internal_data.quorum_fd;
+ pfds[1].events = POLLIN;
+ pfds[1].revents = 0;
+
+ poll_err = poll (pfds, 2, -1);
+
+ if (poll_err == -1) {
+ /*
+ * Error in poll
+ * If it is EINTR, continue, otherwise QUIT
+ */
+ if (errno != EINTR) {
+ err = CS_ERR_LIBRARY;
+ goto error_reply;
+ }
+ }
+
+ if (pfds[0].revents != 0) {
+ if (pfds[0].revents == POLLERR || pfds[0].revents == POLLHUP ||pfds[0].revents == POLLNVAL) {
+ /*
+ * Child has exited
+ */
+ return (CS_OK);
+ }
+ }
+
+ if (pfds[1].revents != 0) {
+ if ((err = quorum_dispatch (sam_internal_data.quorum_handle, CS_DISPATCH_ONE)) != CS_OK) {
+ goto error_reply;
+ }
+ }
+ }
+
+ if (sam_internal_data.recovery_policy & SAM_RECOVERY_POLICY_CMAP) {
+ if ((err = sam_cmap_update_key (SAM_CMAP_KEY_STATE, SAM_CMAP_S_STARTED)) != CS_OK) {
+ goto error_reply;
+ }
+ }
+
+ return (sam_parent_reply_send (CS_OK, parent_fd_in, parent_fd_out));
+
+error_reply:
+ if (sam_internal_data.recovery_policy & SAM_RECOVERY_POLICY_CMAP) {
+ sam_cmap_update_key (SAM_CMAP_KEY_STATE, SAM_CMAP_S_REGISTERED);
+ }
+
+ return (sam_parent_reply_send (err, parent_fd_in, parent_fd_out));
+}
+
+static cs_error_t sam_parent_cmap_state_set (
+ int parent_fd_in,
+ int parent_fd_out,
+ int state)
+{
+ cs_error_t err;
+ const char *state_s;
+
+ if (state == 1) {
+ state_s = SAM_CMAP_S_STARTED;
+ } else {
+ state_s = SAM_CMAP_S_REGISTERED;
+ }
+
+ if ((err = sam_cmap_update_key (SAM_CMAP_KEY_STATE, state_s)) != CS_OK) {
+ goto error_reply;
+ }
+
+ return (sam_parent_reply_send (CS_OK, parent_fd_in, parent_fd_out));
+
+error_reply:
+ return (sam_parent_reply_send (err, parent_fd_in, parent_fd_out));
+}
+
+static cs_error_t sam_parent_kill_child (
+ int *action,
+ pid_t child_pid)
+{
+ /*
+ * Kill child process
+ */
+ if (!sam_internal_data.term_send) {
+ /*
+ * We didn't send warn_signal yet.
+ */
+ kill (child_pid, sam_internal_data.warn_signal);
+
+ sam_internal_data.term_send = 1;
+ } else {
+ /*
+ * We sent child warning. Now, we will not be so nice
+ */
+ kill (child_pid, SIGKILL);
+ *action = SAM_PARENT_ACTION_RECOVERY;
+ }
+
+ return (CS_OK);
+}
+
+static cs_error_t sam_parent_mark_child_failed (
+ int *action,
+ pid_t child_pid)
+{
+ sam_recovery_policy_t recpol;
+
+ recpol = sam_internal_data.recovery_policy;
+
+ sam_internal_data.term_send = 1;
+ sam_internal_data.recovery_policy = SAM_RECOVERY_POLICY_QUIT |
+ (SAM_RP_MASK_C (recpol) ? SAM_RECOVERY_POLICY_CMAP : 0) |
+ (SAM_RP_MASK_Q (recpol) ? SAM_RECOVERY_POLICY_QUORUM : 0);
+
+ return (sam_parent_kill_child (action, child_pid));
+}
+
+static cs_error_t sam_parent_data_store (
+ int parent_fd_in,
+ int parent_fd_out)
+{
+ char *user_data;
+ ssize_t size;
+ cs_error_t err;
+
+ err = CS_OK;
+ user_data = NULL;
+
+ if (sam_safe_read (parent_fd_in, &size, sizeof (size)) != sizeof (size)) {
+ err = CS_ERR_LIBRARY;
+ goto error_reply;
+ }
+
+ if (size > 0) {
+ user_data = malloc (size);
+ if (user_data == NULL) {
+ err = CS_ERR_NO_MEMORY;
+ goto error_reply;
+ }
+
+ if (sam_safe_read (parent_fd_in, user_data, size) != size) {
+ err = CS_ERR_LIBRARY;
+ goto free_error_reply;
+ }
+ }
+
+ err = sam_data_store (user_data, size);
+ if (err != CS_OK) {
+ goto free_error_reply;
+ }
+
+ free (user_data);
+
+ return (sam_parent_reply_send (CS_OK, parent_fd_in, parent_fd_out));
+
+free_error_reply:
+ free (user_data);
+error_reply:
+ return (sam_parent_reply_send (err, parent_fd_in, parent_fd_out));
+}
+
+static enum sam_parent_action_t sam_parent_handler (
+ int parent_fd_in,
+ int parent_fd_out,
+ pid_t child_pid)
+{
+ int poll_error;
+ int action;
+ int status;
+ ssize_t bytes_read;
+ char command;
+ int time_interval;
+ struct pollfd pfds[2];
+ nfds_t nfds;
+ cs_error_t err;
+ sam_recovery_policy_t recpol;
+
+ status = 0;
+
+ action = SAM_PARENT_ACTION_CONTINUE;
+ recpol = sam_internal_data.recovery_policy;
+
+ while (action == SAM_PARENT_ACTION_CONTINUE) {
+ pfds[0].fd = parent_fd_in;
+ pfds[0].events = POLLIN;
+ pfds[0].revents = 0;
+ nfds = 1;
+
+ if (status == 1 && sam_internal_data.time_interval != 0) {
+ time_interval = sam_internal_data.time_interval;
+ } else {
+ time_interval = -1;
+ }
+
+ if (recpol & SAM_RECOVERY_POLICY_QUORUM) {
+ pfds[nfds].fd = sam_internal_data.quorum_fd;
+ pfds[nfds].events = POLLIN;
+ pfds[nfds].revents = 0;
+ nfds++;
+ }
+
+ poll_error = poll (pfds, nfds, time_interval);
+
+ if (poll_error == -1) {
+ /*
+ * Error in poll
+ * If it is EINTR, continue, otherwise QUIT
+ */
+ if (errno != EINTR) {
+ action = SAM_PARENT_ACTION_ERROR;
+ }
+ }
+
+ if (poll_error == 0) {
+ /*
+ * Time limit expires
+ */
+ if (status == 0) {
+ action = SAM_PARENT_ACTION_QUIT;
+ } else {
+ sam_parent_kill_child (&action, child_pid);
+ }
+ }
+
+ if (poll_error > 0) {
+ if (pfds[0].revents != 0) {
+ /*
+ * We have EOF or command in pipe
+ */
+ bytes_read = sam_safe_read (parent_fd_in, &command, 1);
+
+ if (bytes_read == 0) {
+ /*
+ * Handle EOF -> Take recovery action or quit if sam_start wasn't called
+ */
+ if (status == 0)
+ action = SAM_PARENT_ACTION_QUIT;
+ else
+ action = SAM_PARENT_ACTION_RECOVERY;
+
+ continue;
+ }
+
+ if (bytes_read == -1) {
+ action = SAM_PARENT_ACTION_ERROR;
+ goto action_exit;
+ }
+
+ if (recpol & SAM_RECOVERY_POLICY_CMAP) {
+ sam_cmap_update_key (SAM_CMAP_KEY_LAST_HC, NULL);
+ }
+
+ /*
+ * We have read command
+ */
+ switch (command) {
+ case SAM_COMMAND_START:
+ if (status == 0) {
+ /*
+ * Not started yet
+ */
+ if (recpol & SAM_RECOVERY_POLICY_QUORUM) {
+ if (sam_parent_wait_for_quorum (parent_fd_in,
+ parent_fd_out) != CS_OK) {
+ continue;
+ }
+ }
+
+ if (recpol & SAM_RECOVERY_POLICY_CMAP) {
+ if (sam_parent_cmap_state_set (parent_fd_in,
+ parent_fd_out, 1) != CS_OK) {
+ continue;
+ }
+ }
+
+ status = 1;
+ }
+ break;
+ case SAM_COMMAND_STOP:
+ if (status == 1) {
+ /*
+ * Started
+ */
+ if (recpol & SAM_RECOVERY_POLICY_CMAP) {
+ if (sam_parent_cmap_state_set (parent_fd_in,
+ parent_fd_out, 0) != CS_OK) {
+ continue;
+ }
+ }
+
+ status = 0;
+ }
+ break;
+ case SAM_COMMAND_DATA_STORE:
+ sam_parent_data_store (parent_fd_in, parent_fd_out);
+ break;
+ case SAM_COMMAND_WARN_SIGNAL_SET:
+ sam_parent_warn_signal_set (parent_fd_in, parent_fd_out);
+ break;
+ case SAM_COMMAND_MARK_FAILED:
+ status = 1;
+ sam_parent_mark_child_failed (&action, child_pid);
+ break;
+ }
+ } /* if (pfds[0].revents != 0) */
+
+ if ((sam_internal_data.recovery_policy & SAM_RECOVERY_POLICY_QUORUM) &&
+ pfds[1].revents != 0) {
+ /*
+ * Handle quorum change
+ */
+ err = quorum_dispatch (sam_internal_data.quorum_handle, CS_DISPATCH_ALL);
+
+ if (status == 1 &&
+ (!sam_internal_data.quorate || (err != CS_ERR_TRY_AGAIN && err != CS_OK))) {
+ sam_parent_kill_child (&action, child_pid);
+ }
+ }
+ } /* select_error > 0 */
+ } /* action == SAM_PARENT_ACTION_CONTINUE */
+
+action_exit:
+ return action;
+}
+
+cs_error_t sam_register (
+ unsigned int *instance_id)
+{
+ cs_error_t error;
+ pid_t pid;
+ int pipe_error;
+ int pipe_fd_out[2], pipe_fd_in[2];
+ enum sam_parent_action_t action, old_action;
+ int child_status;
+ sam_recovery_policy_t recpol;
+
+ if (sam_internal_data.internal_status != SAM_INTERNAL_STATUS_INITIALIZED) {
+ return (CS_ERR_BAD_HANDLE);
+ }
+
+ recpol = sam_internal_data.recovery_policy;
+
+ if (recpol & SAM_RECOVERY_POLICY_CMAP) {
+ /*
+ * Register to cmap
+ */
+ if ((error = sam_cmap_register ()) != CS_OK) {
+ goto error_exit;
+ }
+ }
+
+ error = CS_OK;
+
+ while (1) {
+ if ((pipe_error = pipe (pipe_fd_out)) != 0) {
+ error = CS_ERR_LIBRARY;
+ goto error_exit;
+ }
+
+ if ((pipe_error = pipe (pipe_fd_in)) != 0) {
+ close (pipe_fd_out[0]);
+ close (pipe_fd_out[1]);
+
+ error = CS_ERR_LIBRARY;
+ goto error_exit;
+ }
+
+ if (recpol & SAM_RECOVERY_POLICY_CMAP) {
+ if ((error = sam_cmap_update_key (SAM_CMAP_KEY_STATE, SAM_CMAP_S_REGISTERED)) != CS_OK) {
+ goto error_exit;
+ }
+ }
+
+ sam_internal_data.instance_id++;
+
+ sam_internal_data.term_send = 0;
+
+ pid = fork ();
+
+ if (pid == -1) {
+ /*
+ * Fork error
+ */
+ sam_internal_data.instance_id--;
+
+ error = CS_ERR_LIBRARY;
+ goto error_exit;
+ }
+
+ if (pid == 0) {
+ /*
+ * Child process
+ */
+ close (pipe_fd_out[0]);
+ close (pipe_fd_in[1]);
+
+ sam_internal_data.child_fd_out = pipe_fd_out[1];
+ sam_internal_data.child_fd_in = pipe_fd_in[0];
+
+ if (instance_id)
+ *instance_id = sam_internal_data.instance_id;
+
+ sam_internal_data.am_i_child = 1;
+ sam_internal_data.internal_status = SAM_INTERNAL_STATUS_REGISTERED;
+
+ pthread_mutex_init (&sam_internal_data.lock, NULL);
+
+ goto error_exit;
+ } else {
+ /*
+ * Parent process
+ */
+ close (pipe_fd_out[1]);
+ close (pipe_fd_in[0]);
+
+ action = sam_parent_handler (pipe_fd_out[0], pipe_fd_in[1], pid);
+
+ close (pipe_fd_out[0]);
+ close (pipe_fd_in[1]);
+
+ if (action == SAM_PARENT_ACTION_ERROR) {
+ error = CS_ERR_LIBRARY;
+ goto error_exit;
+ }
+
+ /*
+ * We really don't like zombies
+ */
+ while (waitpid (pid, &child_status, 0) == -1 && errno == EINTR)
+ ;
+
+ old_action = action;
+
+ if (action == SAM_PARENT_ACTION_RECOVERY) {
+ if (SAM_RP_MASK (sam_internal_data.recovery_policy) == SAM_RECOVERY_POLICY_QUIT)
+ action = SAM_PARENT_ACTION_QUIT;
+ }
+
+
+ if (action == SAM_PARENT_ACTION_QUIT) {
+ if (recpol & SAM_RECOVERY_POLICY_QUORUM) {
+ quorum_finalize (sam_internal_data.quorum_handle);
+ }
+
+ if (recpol & SAM_RECOVERY_POLICY_CMAP) {
+ if (old_action == SAM_PARENT_ACTION_RECOVERY) {
+ /*
+ * Mark as failed
+ */
+ sam_cmap_update_key (SAM_CMAP_KEY_STATE, SAM_CMAP_S_FAILED);
+ } else {
+ sam_cmap_destroy_pid_path ();
+ }
+ }
+
+ exit (WEXITSTATUS (child_status));
+ }
+
+
+ }
+ }
+
+error_exit:
+ return (error);
+}
+
+static void *hc_callback_thread (void *unused_param)
+{
+ int poll_error;
+ int status;
+ ssize_t bytes_readed;
+ char command;
+ int time_interval, tmp_time_interval;
+ int counter;
+ struct pollfd pfds;
+
+ status = 0;
+ counter = 0;
+
+ time_interval = sam_internal_data.time_interval >> 2;
+
+ while (1) {
+ pfds.fd = sam_internal_data.cb_rpipe_fd;
+ pfds.events = POLLIN;
+ pfds.revents = 0;
+
+ if (status == 1) {
+ tmp_time_interval = time_interval;
+ } else {
+ tmp_time_interval = -1;
+ }
+
+ poll_error = poll (&pfds, 1, tmp_time_interval);
+
+ if (poll_error == 0) {
+ if (sam_hc_send () == CS_OK) {
+ counter++;
+ }
+
+ if (counter >= 4) {
+ if (sam_internal_data.hc_callback () != 0) {
+ status = 3;
+ }
+
+ counter = 0;
+ }
+ }
+
+ if (poll_error > 0) {
+ bytes_readed = sam_safe_read (sam_internal_data.cb_rpipe_fd, &command, 1);
+
+ if (bytes_readed > 0) {
+ if (status == 0 && command == SAM_COMMAND_START)
+ status = 1;
+
+ if (status == 1 && command == SAM_COMMAND_STOP)
+ status = 0;
+
+ }
+ }
+ }
+
+ /*
+ * This makes compiler happy, it's same as return (NULL);
+ */
+ return (unused_param);
+}
+
+cs_error_t sam_hc_callback_register (sam_hc_callback_t cb)
+{
+ cs_error_t error = CS_OK;
+ pthread_attr_t thread_attr;
+ int pipe_error;
+ int pipe_fd[2];
+
+ if (sam_internal_data.internal_status != SAM_INTERNAL_STATUS_REGISTERED) {
+ return (CS_ERR_BAD_HANDLE);
+ }
+
+ if (sam_internal_data.time_interval == 0) {
+ return (CS_ERR_INVALID_PARAM);
+ }
+
+ if (sam_internal_data.cb_registered) {
+ sam_internal_data.hc_callback = cb;
+
+ return (CS_OK);
+ }
+
+ /*
+ * We know, this is first registration
+ */
+
+ if (cb == NULL) {
+ return (CS_ERR_INVALID_PARAM);
+ }
+
+ pipe_error = pipe (pipe_fd);
+
+ if (pipe_error != 0) {
+ /*
+ * Pipe creation error
+ */
+ error = CS_ERR_LIBRARY;
+ goto error_exit;
+ }
+
+ sam_internal_data.cb_rpipe_fd = pipe_fd[0];
+ sam_internal_data.cb_wpipe_fd = pipe_fd[1];
+
+ /*
+ * Create thread attributes
+ */
+ error = pthread_attr_init (&thread_attr);
+ if (error != 0) {
+ error = CS_ERR_LIBRARY;
+ goto error_close_fd_exit;
+ }
+
+
+ pthread_attr_setdetachstate (&thread_attr, PTHREAD_CREATE_DETACHED);
+ pthread_attr_setstacksize (&thread_attr, 32768);
+
+ /*
+ * Create thread
+ */
+ error = pthread_create (&sam_internal_data.cb_thread, &thread_attr, hc_callback_thread, NULL);
+
+ if (error != 0) {
+ error = CS_ERR_LIBRARY;
+ goto error_attr_destroy_exit;
+ }
+
+ /*
+ * Cleanup
+ */
+ pthread_attr_destroy(&thread_attr);
+
+ sam_internal_data.cb_registered = 1;
+ sam_internal_data.hc_callback = cb;
+
+ return (CS_OK);
+
+error_attr_destroy_exit:
+ pthread_attr_destroy(&thread_attr);
+error_close_fd_exit:
+ sam_internal_data.cb_rpipe_fd = sam_internal_data.cb_wpipe_fd = 0;
+ close (pipe_fd[0]);
+ close (pipe_fd[1]);
+error_exit:
+ return (error);
+}
diff --git a/lib/util.h b/lib/util.h
new file mode 100644
index 0000000..a1610a7
--- /dev/null
+++ b/lib/util.h
@@ -0,0 +1,54 @@
+
+/*
+ * Copyright (c) 2002-2003 MontaVista Software, Inc.
+ * Copyright (c) 2012 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Author: Steven Dake (sdake@redhat.com)
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of the MontaVista Software, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef COROSYNC_UTIL_H_DEFINED
+#define COROSYNC_UTIL_H_DEFINED
+
+#include <corosync/corotypes.h>
+
+cs_error_t hdb_error_to_cs (int res);
+
+#ifdef HAVE_SMALL_MEMORY_FOOTPRINT
+#define IPC_REQUEST_SIZE 1024*64
+#define IPC_RESPONSE_SIZE 1024*64
+#define IPC_DISPATCH_SIZE 1024*64
+#else
+#define IPC_REQUEST_SIZE 8192*128
+#define IPC_RESPONSE_SIZE 8192*128
+#define IPC_DISPATCH_SIZE 8192*128
+#endif /* HAVE_SMALL_MEMORY_FOOTPRINT */
+
+#endif /* COROSYNC_UTIL_H_DEFINED */
diff --git a/lib/votequorum.c b/lib/votequorum.c
new file mode 100644
index 0000000..4bcac22
--- /dev/null
+++ b/lib/votequorum.c
@@ -0,0 +1,811 @@
+/*
+ * Copyright (c) 2009-2012 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Author: Christine Caulfield (ccaulfie@redhat.com)
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of the MontaVista Software, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Provides a quorum API using the corosync executive
+ */
+
+#include <config.h>
+
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/uio.h>
+#include <errno.h>
+
+#include <qb/qbdefs.h>
+#include <qb/qbipcc.h>
+
+#include <corosync/corotypes.h>
+#include <corosync/corodefs.h>
+#include <corosync/hdb.h>
+
+#include <corosync/votequorum.h>
+#include <corosync/ipc_votequorum.h>
+
+#include "util.h"
+
+struct votequorum_inst {
+ qb_ipcc_connection_t *c;
+ int finalize;
+ void *context;
+ votequorum_callbacks_t callbacks;
+};
+
+static void votequorum_inst_free (void *inst);
+
+DECLARE_HDB_DATABASE(votequorum_handle_t_db, votequorum_inst_free);
+
+cs_error_t votequorum_initialize (
+ votequorum_handle_t *handle,
+ votequorum_callbacks_t *callbacks)
+{
+ cs_error_t error;
+ struct votequorum_inst *votequorum_inst;
+
+ error = hdb_error_to_cs(hdb_handle_create (&votequorum_handle_t_db, sizeof (struct votequorum_inst), handle));
+ if (error != CS_OK) {
+ goto error_no_destroy;
+ }
+
+ error = hdb_error_to_cs(hdb_handle_get (&votequorum_handle_t_db, *handle, (void *)&votequorum_inst));
+ if (error != CS_OK) {
+ goto error_destroy;
+ }
+
+ votequorum_inst->finalize = 0;
+ votequorum_inst->c = qb_ipcc_connect ("votequorum", IPC_REQUEST_SIZE);
+ if (votequorum_inst->c == NULL) {
+ error = qb_to_cs_error(-errno);
+ goto error_put_destroy;
+ }
+
+ if (callbacks)
+ memcpy(&votequorum_inst->callbacks, callbacks, sizeof (*callbacks));
+ else
+ memset(&votequorum_inst->callbacks, 0, sizeof (*callbacks));
+
+ hdb_handle_put (&votequorum_handle_t_db, *handle);
+
+ return (CS_OK);
+
+error_put_destroy:
+ hdb_handle_put (&votequorum_handle_t_db, *handle);
+error_destroy:
+ hdb_handle_destroy (&votequorum_handle_t_db, *handle);
+error_no_destroy:
+ return (error);
+}
+
+static void votequorum_inst_free (void *inst)
+{
+ struct votequorum_inst *vq_inst = (struct votequorum_inst *)inst;
+ qb_ipcc_disconnect(vq_inst->c);
+}
+
+cs_error_t votequorum_finalize (
+ votequorum_handle_t handle)
+{
+ struct votequorum_inst *votequorum_inst;
+ cs_error_t error;
+
+ error = hdb_error_to_cs(hdb_handle_get (&votequorum_handle_t_db, handle, (void *)&votequorum_inst));
+ if (error != CS_OK) {
+ return (error);
+ }
+
+ /*
+ * Another thread has already started finalizing
+ */
+ if (votequorum_inst->finalize) {
+ hdb_handle_put (&votequorum_handle_t_db, handle);
+ return (CS_ERR_BAD_HANDLE);
+ }
+
+ votequorum_inst->finalize = 1;
+
+ hdb_handle_destroy (&votequorum_handle_t_db, handle);
+
+ hdb_handle_put (&votequorum_handle_t_db, handle);
+
+ return (CS_OK);
+}
+
+
+cs_error_t votequorum_getinfo (
+ votequorum_handle_t handle,
+ unsigned int nodeid,
+ struct votequorum_info *info)
+{
+ cs_error_t error;
+ struct votequorum_inst *votequorum_inst;
+ struct iovec iov;
+ struct req_lib_votequorum_getinfo req_lib_votequorum_getinfo;
+ struct res_lib_votequorum_getinfo res_lib_votequorum_getinfo;
+
+ error = hdb_error_to_cs(hdb_handle_get (&votequorum_handle_t_db, handle, (void *)&votequorum_inst));
+ if (error != CS_OK) {
+ return (error);
+ }
+
+ req_lib_votequorum_getinfo.header.size = sizeof (struct req_lib_votequorum_getinfo);
+ req_lib_votequorum_getinfo.header.id = MESSAGE_REQ_VOTEQUORUM_GETINFO;
+ req_lib_votequorum_getinfo.nodeid = nodeid;
+
+ iov.iov_base = (char *)&req_lib_votequorum_getinfo;
+ iov.iov_len = sizeof (struct req_lib_votequorum_getinfo);
+
+ error = qb_to_cs_error(qb_ipcc_sendv_recv (
+ votequorum_inst->c,
+ &iov,
+ 1,
+ &res_lib_votequorum_getinfo,
+ sizeof (struct res_lib_votequorum_getinfo), CS_IPC_TIMEOUT_MS));
+
+ if (error != CS_OK) {
+ goto error_exit;
+ }
+
+ error = res_lib_votequorum_getinfo.header.error;
+
+ info->node_id = res_lib_votequorum_getinfo.nodeid;
+ info->node_state = res_lib_votequorum_getinfo.state;
+ info->node_votes = res_lib_votequorum_getinfo.votes;
+ info->node_expected_votes = res_lib_votequorum_getinfo.expected_votes;
+ info->highest_expected = res_lib_votequorum_getinfo.highest_expected;
+ info->total_votes = res_lib_votequorum_getinfo.total_votes;
+ info->quorum = res_lib_votequorum_getinfo.quorum;
+ info->flags = res_lib_votequorum_getinfo.flags;
+ info->qdevice_votes = res_lib_votequorum_getinfo.qdevice_votes;
+ memset(info->qdevice_name, 0, VOTEQUORUM_QDEVICE_MAX_NAME_LEN);
+ strcpy(info->qdevice_name, res_lib_votequorum_getinfo.qdevice_name);
+
+error_exit:
+ hdb_handle_put (&votequorum_handle_t_db, handle);
+
+ return (error);
+}
+
+cs_error_t votequorum_setexpected (
+ votequorum_handle_t handle,
+ unsigned int expected_votes)
+{
+ cs_error_t error;
+ struct votequorum_inst *votequorum_inst;
+ struct iovec iov;
+ struct req_lib_votequorum_setexpected req_lib_votequorum_setexpected;
+ struct res_lib_votequorum_status res_lib_votequorum_status;
+
+ error = hdb_error_to_cs(hdb_handle_get (&votequorum_handle_t_db, handle, (void *)&votequorum_inst));
+ if (error != CS_OK) {
+ return (error);
+ }
+
+
+ req_lib_votequorum_setexpected.header.size = sizeof (struct req_lib_votequorum_setexpected);
+ req_lib_votequorum_setexpected.header.id = MESSAGE_REQ_VOTEQUORUM_SETEXPECTED;
+ req_lib_votequorum_setexpected.expected_votes = expected_votes;
+
+ iov.iov_base = (char *)&req_lib_votequorum_setexpected;
+ iov.iov_len = sizeof (struct req_lib_votequorum_setexpected);
+
+ error = qb_to_cs_error(qb_ipcc_sendv_recv (
+ votequorum_inst->c,
+ &iov,
+ 1,
+ &res_lib_votequorum_status,
+ sizeof (struct res_lib_votequorum_status), CS_IPC_TIMEOUT_MS));
+
+ if (error != CS_OK) {
+ goto error_exit;
+ }
+
+ error = res_lib_votequorum_status.header.error;
+
+error_exit:
+ hdb_handle_put (&votequorum_handle_t_db, handle);
+
+ return (error);
+}
+
+cs_error_t votequorum_setvotes (
+ votequorum_handle_t handle,
+ unsigned int nodeid,
+ unsigned int votes)
+{
+ cs_error_t error;
+ struct votequorum_inst *votequorum_inst;
+ struct iovec iov;
+ struct req_lib_votequorum_setvotes req_lib_votequorum_setvotes;
+ struct res_lib_votequorum_status res_lib_votequorum_status;
+
+ error = hdb_error_to_cs(hdb_handle_get (&votequorum_handle_t_db, handle, (void *)&votequorum_inst));
+ if (error != CS_OK) {
+ return (error);
+ }
+
+ req_lib_votequorum_setvotes.header.size = sizeof (struct req_lib_votequorum_setvotes);
+ req_lib_votequorum_setvotes.header.id = MESSAGE_REQ_VOTEQUORUM_SETVOTES;
+ req_lib_votequorum_setvotes.nodeid = nodeid;
+ req_lib_votequorum_setvotes.votes = votes;
+
+ iov.iov_base = (char *)&req_lib_votequorum_setvotes;
+ iov.iov_len = sizeof (struct req_lib_votequorum_setvotes);
+
+ error = qb_to_cs_error(qb_ipcc_sendv_recv (
+ votequorum_inst->c,
+ &iov,
+ 1,
+ &res_lib_votequorum_status,
+ sizeof (struct res_lib_votequorum_status), CS_IPC_TIMEOUT_MS));
+
+ if (error != CS_OK) {
+ goto error_exit;
+ }
+
+ error = res_lib_votequorum_status.header.error;
+
+error_exit:
+ hdb_handle_put (&votequorum_handle_t_db, handle);
+
+ return (error);
+}
+
+cs_error_t votequorum_trackstart (
+ votequorum_handle_t handle,
+ uint64_t context,
+ unsigned int flags)
+{
+ cs_error_t error;
+ struct votequorum_inst *votequorum_inst;
+ struct iovec iov;
+ struct req_lib_votequorum_trackstart req_lib_votequorum_trackstart;
+ struct res_lib_votequorum_status res_lib_votequorum_status;
+
+ error = hdb_error_to_cs(hdb_handle_get (&votequorum_handle_t_db, handle, (void *)&votequorum_inst));
+ if (error != CS_OK) {
+ return (error);
+ }
+
+ req_lib_votequorum_trackstart.header.size = sizeof (struct req_lib_votequorum_trackstart);
+ req_lib_votequorum_trackstart.header.id = MESSAGE_REQ_VOTEQUORUM_TRACKSTART;
+ req_lib_votequorum_trackstart.track_flags = flags;
+ req_lib_votequorum_trackstart.context = context;
+
+ iov.iov_base = (char *)&req_lib_votequorum_trackstart;
+ iov.iov_len = sizeof (struct req_lib_votequorum_trackstart);
+
+ error = qb_to_cs_error(qb_ipcc_sendv_recv (
+ votequorum_inst->c,
+ &iov,
+ 1,
+ &res_lib_votequorum_status,
+ sizeof (struct res_lib_votequorum_status), CS_IPC_TIMEOUT_MS));
+
+ if (error != CS_OK) {
+ goto error_exit;
+ }
+
+ error = res_lib_votequorum_status.header.error;
+
+error_exit:
+ hdb_handle_put (&votequorum_handle_t_db, handle);
+
+ return (error);
+}
+
+cs_error_t votequorum_trackstop (
+ votequorum_handle_t handle)
+{
+ cs_error_t error;
+ struct votequorum_inst *votequorum_inst;
+ struct iovec iov;
+ struct req_lib_votequorum_general req_lib_votequorum_general;
+ struct res_lib_votequorum_status res_lib_votequorum_status;
+
+ error = hdb_error_to_cs(hdb_handle_get (&votequorum_handle_t_db, handle, (void *)&votequorum_inst));
+ if (error != CS_OK) {
+ return (error);
+ }
+
+ req_lib_votequorum_general.header.size = sizeof (struct req_lib_votequorum_general);
+ req_lib_votequorum_general.header.id = MESSAGE_REQ_VOTEQUORUM_TRACKSTOP;
+
+ iov.iov_base = (char *)&req_lib_votequorum_general;
+ iov.iov_len = sizeof (struct req_lib_votequorum_general);
+
+ error = qb_to_cs_error(qb_ipcc_sendv_recv (
+ votequorum_inst->c,
+ &iov,
+ 1,
+ &res_lib_votequorum_status,
+ sizeof (struct res_lib_votequorum_status), CS_IPC_TIMEOUT_MS));
+
+ if (error != CS_OK) {
+ goto error_exit;
+ }
+
+ error = res_lib_votequorum_status.header.error;
+
+error_exit:
+ hdb_handle_put (&votequorum_handle_t_db, handle);
+
+ return (error);
+}
+
+
+cs_error_t votequorum_context_get (
+ votequorum_handle_t handle,
+ void **context)
+{
+ cs_error_t error;
+ struct votequorum_inst *votequorum_inst;
+
+ error = hdb_error_to_cs(hdb_handle_get (&votequorum_handle_t_db, handle, (void *)&votequorum_inst));
+ if (error != CS_OK) {
+ return (error);
+ }
+
+ *context = votequorum_inst->context;
+
+ hdb_handle_put (&votequorum_handle_t_db, handle);
+
+ return (CS_OK);
+}
+
+cs_error_t votequorum_context_set (
+ votequorum_handle_t handle,
+ void *context)
+{
+ cs_error_t error;
+ struct votequorum_inst *votequorum_inst;
+
+ error = hdb_error_to_cs(hdb_handle_get (&votequorum_handle_t_db, handle, (void *)&votequorum_inst));
+ if (error != CS_OK) {
+ return (error);
+ }
+
+ votequorum_inst->context = context;
+
+ hdb_handle_put (&votequorum_handle_t_db, handle);
+
+ return (CS_OK);
+}
+
+
+cs_error_t votequorum_fd_get (
+ votequorum_handle_t handle,
+ int *fd)
+{
+ cs_error_t error;
+ struct votequorum_inst *votequorum_inst;
+
+ error = hdb_error_to_cs(hdb_handle_get (&votequorum_handle_t_db, handle, (void *)&votequorum_inst));
+ if (error != CS_OK) {
+ return (error);
+ }
+
+ error = qb_to_cs_error(qb_ipcc_fd_get (votequorum_inst->c, fd));
+
+ (void)hdb_handle_put (&votequorum_handle_t_db, handle);
+
+ return (error);
+}
+
+cs_error_t votequorum_dispatch (
+ votequorum_handle_t handle,
+ cs_dispatch_flags_t dispatch_types)
+{
+ int timeout = -1;
+ cs_error_t error;
+ int cont = 1; /* always continue do loop except when set to 0 */
+ struct votequorum_inst *votequorum_inst;
+ votequorum_callbacks_t callbacks;
+ struct qb_ipc_response_header *dispatch_data;
+ struct res_lib_votequorum_quorum_notification *res_lib_votequorum_quorum_notification;
+ struct res_lib_votequorum_nodelist_notification *res_lib_votequorum_nodelist_notification;
+ struct res_lib_votequorum_expectedvotes_notification *res_lib_votequorum_expectedvotes_notification;
+ char dispatch_buf[IPC_DISPATCH_SIZE];
+ votequorum_ring_id_t ring_id;
+
+ if (dispatch_types != CS_DISPATCH_ONE &&
+ dispatch_types != CS_DISPATCH_ALL &&
+ dispatch_types != CS_DISPATCH_BLOCKING &&
+ dispatch_types != CS_DISPATCH_ONE_NONBLOCKING) {
+
+ return (CS_ERR_INVALID_PARAM);
+ }
+
+ error = hdb_error_to_cs(hdb_handle_get (&votequorum_handle_t_db, handle,
+ (void *)&votequorum_inst));
+ if (error != CS_OK) {
+ return (error);
+ }
+
+ /*
+ * Timeout instantly for CS_DISPATCH_ONE_NONBLOCKING or CS_DISPATCH_ALL and
+ * wait indefinately for CS_DISPATCH_ONE or CS_DISPATCH_BLOCKING
+ */
+ if (dispatch_types == CS_DISPATCH_ALL || dispatch_types == CS_DISPATCH_ONE_NONBLOCKING) {
+ timeout = 0;
+ }
+
+ dispatch_data = (struct qb_ipc_response_header *)dispatch_buf;
+ do {
+ error = qb_to_cs_error (qb_ipcc_event_recv (
+ votequorum_inst->c,
+ dispatch_buf,
+ IPC_DISPATCH_SIZE,
+ timeout));
+ if (error == CS_ERR_BAD_HANDLE) {
+ error = CS_OK;
+ goto error_put;
+ }
+ if (error == CS_ERR_TRY_AGAIN) {
+ if (dispatch_types == CS_DISPATCH_ONE_NONBLOCKING) {
+ /*
+ * Don't mask error
+ */
+ goto error_put;
+ }
+ error = CS_OK;
+ if (dispatch_types == CS_DISPATCH_ALL) {
+ break; /* exit do while cont is 1 loop */
+ } else {
+ continue; /* next poll */
+ }
+ }
+ if (error != CS_OK) {
+ goto error_put;
+ }
+
+ /*
+ * Make copy of callbacks, message data, unlock instance, and call callback
+ * A risk of this dispatch method is that the callback routines may
+ * operate at the same time that votequorum_finalize has been called in another thread.
+ */
+ memcpy (&callbacks, &votequorum_inst->callbacks, sizeof (votequorum_callbacks_t));
+
+ /*
+ * Dispatch incoming message
+ */
+ switch (dispatch_data->id) {
+
+ case MESSAGE_RES_VOTEQUORUM_QUORUM_NOTIFICATION:
+ if (callbacks.votequorum_quorum_notify_fn == NULL) {
+ break;
+ }
+ res_lib_votequorum_quorum_notification = (struct res_lib_votequorum_quorum_notification *)dispatch_data;
+
+ callbacks.votequorum_quorum_notify_fn ( handle,
+ res_lib_votequorum_quorum_notification->context,
+ res_lib_votequorum_quorum_notification->quorate,
+ res_lib_votequorum_quorum_notification->node_list_entries,
+ (votequorum_node_t *)res_lib_votequorum_quorum_notification->node_list );
+ break;
+
+ case MESSAGE_RES_VOTEQUORUM_NODELIST_NOTIFICATION:
+ if (callbacks.votequorum_nodelist_notify_fn == NULL) {
+ break;
+ }
+ res_lib_votequorum_nodelist_notification = (struct res_lib_votequorum_nodelist_notification *)dispatch_data;
+ marshall_from_mar_votequorum_ring_id (&ring_id, &res_lib_votequorum_nodelist_notification->ring_id);
+
+ callbacks.votequorum_nodelist_notify_fn ( handle,
+ res_lib_votequorum_nodelist_notification->context,
+ ring_id,
+ res_lib_votequorum_nodelist_notification->node_list_entries,
+ res_lib_votequorum_nodelist_notification->node_list );
+ break;
+
+ case MESSAGE_RES_VOTEQUORUM_EXPECTEDVOTES_NOTIFICATION:
+ if (callbacks.votequorum_expectedvotes_notify_fn == NULL) {
+ break;
+ }
+ res_lib_votequorum_expectedvotes_notification = (struct res_lib_votequorum_expectedvotes_notification *)dispatch_data;
+
+ callbacks.votequorum_expectedvotes_notify_fn ( handle,
+ res_lib_votequorum_expectedvotes_notification->context,
+ res_lib_votequorum_expectedvotes_notification->expected_votes);
+ break;
+
+ default:
+ error = CS_ERR_LIBRARY;
+ goto error_put;
+ break;
+ }
+ if (votequorum_inst->finalize) {
+ /*
+ * If the finalize has been called then get out of the dispatch.
+ */
+ error = CS_ERR_BAD_HANDLE;
+ goto error_put;
+ }
+
+ /*
+ * Determine if more messages should be processed
+ */
+ if (dispatch_types == CS_DISPATCH_ONE || dispatch_types == CS_DISPATCH_ONE_NONBLOCKING) {
+ cont = 0;
+ }
+ } while (cont);
+
+
+error_put:
+ hdb_handle_put (&votequorum_handle_t_db, handle);
+ return (error);
+}
+
+cs_error_t votequorum_qdevice_register (
+ votequorum_handle_t handle,
+ const char *name)
+{
+ cs_error_t error;
+ struct votequorum_inst *votequorum_inst;
+ struct iovec iov;
+ struct req_lib_votequorum_qdevice_register req_lib_votequorum_qdevice_register;
+ struct res_lib_votequorum_status res_lib_votequorum_status;
+
+ if ((strlen(name) == 0) ||
+ (strlen(name) >= VOTEQUORUM_QDEVICE_MAX_NAME_LEN)) {
+ return CS_ERR_INVALID_PARAM;
+ }
+
+ error = hdb_error_to_cs(hdb_handle_get (&votequorum_handle_t_db, handle, (void *)&votequorum_inst));
+ if (error != CS_OK) {
+ return (error);
+ }
+
+
+ req_lib_votequorum_qdevice_register.header.size = sizeof (struct req_lib_votequorum_qdevice_register);
+ req_lib_votequorum_qdevice_register.header.id = MESSAGE_REQ_VOTEQUORUM_QDEVICE_REGISTER;
+ strcpy(req_lib_votequorum_qdevice_register.name, name);
+
+ iov.iov_base = (char *)&req_lib_votequorum_qdevice_register;
+ iov.iov_len = sizeof (struct req_lib_votequorum_qdevice_register);
+
+ error = qb_to_cs_error(qb_ipcc_sendv_recv (
+ votequorum_inst->c,
+ &iov,
+ 1,
+ &res_lib_votequorum_status,
+ sizeof (struct res_lib_votequorum_status), CS_IPC_TIMEOUT_MS));
+
+ if (error != CS_OK) {
+ goto error_exit;
+ }
+
+ error = res_lib_votequorum_status.header.error;
+
+error_exit:
+ hdb_handle_put (&votequorum_handle_t_db, handle);
+
+ return (error);
+}
+
+cs_error_t votequorum_qdevice_poll (
+ votequorum_handle_t handle,
+ const char *name,
+ unsigned int cast_vote,
+ votequorum_ring_id_t ring_id)
+{
+ cs_error_t error;
+ struct votequorum_inst *votequorum_inst;
+ struct iovec iov;
+ struct req_lib_votequorum_qdevice_poll req_lib_votequorum_qdevice_poll;
+ struct res_lib_votequorum_status res_lib_votequorum_status;
+
+ if ((strlen(name) == 0) ||
+ (strlen(name) >= VOTEQUORUM_QDEVICE_MAX_NAME_LEN)) {
+ return CS_ERR_INVALID_PARAM;
+ }
+
+ error = hdb_error_to_cs(hdb_handle_get (&votequorum_handle_t_db, handle, (void *)&votequorum_inst));
+ if (error != CS_OK) {
+ return (error);
+ }
+
+ req_lib_votequorum_qdevice_poll.header.size = sizeof (struct req_lib_votequorum_qdevice_poll);
+ req_lib_votequorum_qdevice_poll.header.id = MESSAGE_REQ_VOTEQUORUM_QDEVICE_POLL;
+ strcpy(req_lib_votequorum_qdevice_poll.name, name);
+ req_lib_votequorum_qdevice_poll.cast_vote = cast_vote;
+ marshall_to_mar_votequorum_ring_id(&req_lib_votequorum_qdevice_poll.ring_id, &ring_id);
+
+ iov.iov_base = (char *)&req_lib_votequorum_qdevice_poll;
+ iov.iov_len = sizeof (struct req_lib_votequorum_qdevice_poll);
+
+ error = qb_to_cs_error(qb_ipcc_sendv_recv (
+ votequorum_inst->c,
+ &iov,
+ 1,
+ &res_lib_votequorum_status,
+ sizeof (struct res_lib_votequorum_status), CS_IPC_TIMEOUT_MS));
+
+ if (error != CS_OK) {
+ goto error_exit;
+ }
+
+ error = res_lib_votequorum_status.header.error;
+
+error_exit:
+ hdb_handle_put (&votequorum_handle_t_db, handle);
+
+ return (error);
+}
+
+cs_error_t votequorum_qdevice_master_wins (
+ votequorum_handle_t handle,
+ const char *name,
+ unsigned int allow)
+{
+ cs_error_t error;
+ struct votequorum_inst *votequorum_inst;
+ struct iovec iov;
+ struct req_lib_votequorum_qdevice_master_wins req_lib_votequorum_qdevice_master_wins;
+ struct res_lib_votequorum_status res_lib_votequorum_status;
+
+ if ((strlen(name) == 0) ||
+ (strlen(name) >= VOTEQUORUM_QDEVICE_MAX_NAME_LEN)) {
+ return CS_ERR_INVALID_PARAM;
+ }
+
+ error = hdb_error_to_cs(hdb_handle_get (&votequorum_handle_t_db, handle, (void *)&votequorum_inst));
+ if (error != CS_OK) {
+ return (error);
+ }
+
+ req_lib_votequorum_qdevice_master_wins.header.size = sizeof (struct req_lib_votequorum_qdevice_master_wins);
+ req_lib_votequorum_qdevice_master_wins.header.id = MESSAGE_REQ_VOTEQUORUM_QDEVICE_MASTER_WINS;
+ strcpy(req_lib_votequorum_qdevice_master_wins.name, name);
+ req_lib_votequorum_qdevice_master_wins.allow = allow;
+
+ iov.iov_base = (char *)&req_lib_votequorum_qdevice_master_wins;
+ iov.iov_len = sizeof (struct req_lib_votequorum_qdevice_master_wins);
+
+ error = qb_to_cs_error(qb_ipcc_sendv_recv (
+ votequorum_inst->c,
+ &iov,
+ 1,
+ &res_lib_votequorum_status,
+ sizeof (struct res_lib_votequorum_status), CS_IPC_TIMEOUT_MS));
+
+ if (error != CS_OK) {
+ goto error_exit;
+ }
+
+ error = res_lib_votequorum_status.header.error;
+
+error_exit:
+ hdb_handle_put (&votequorum_handle_t_db, handle);
+
+ return (error);
+}
+
+cs_error_t votequorum_qdevice_update (
+ votequorum_handle_t handle,
+ const char *oldname,
+ const char *newname)
+{
+ cs_error_t error;
+ struct votequorum_inst *votequorum_inst;
+ struct iovec iov;
+ struct req_lib_votequorum_qdevice_update req_lib_votequorum_qdevice_update;
+ struct res_lib_votequorum_status res_lib_votequorum_status;
+
+ if ((strlen(oldname) == 0) ||
+ (strlen(oldname) >= VOTEQUORUM_QDEVICE_MAX_NAME_LEN) ||
+ (strlen(newname) == 0) ||
+ (strlen(newname) >= VOTEQUORUM_QDEVICE_MAX_NAME_LEN)) {
+ return CS_ERR_INVALID_PARAM;
+ }
+
+ error = hdb_error_to_cs(hdb_handle_get (&votequorum_handle_t_db, handle, (void *)&votequorum_inst));
+ if (error != CS_OK) {
+ return (error);
+ }
+
+ req_lib_votequorum_qdevice_update.header.size = sizeof (struct req_lib_votequorum_qdevice_update);
+ req_lib_votequorum_qdevice_update.header.id = MESSAGE_REQ_VOTEQUORUM_QDEVICE_UPDATE;
+ strcpy(req_lib_votequorum_qdevice_update.oldname, oldname);
+ strcpy(req_lib_votequorum_qdevice_update.newname, newname);
+
+ iov.iov_base = (char *)&req_lib_votequorum_qdevice_update;
+ iov.iov_len = sizeof (struct req_lib_votequorum_qdevice_update);
+
+ error = qb_to_cs_error(qb_ipcc_sendv_recv (
+ votequorum_inst->c,
+ &iov,
+ 1,
+ &res_lib_votequorum_status,
+ sizeof (struct res_lib_votequorum_status), CS_IPC_TIMEOUT_MS));
+
+ if (error != CS_OK) {
+ goto error_exit;
+ }
+
+ error = res_lib_votequorum_status.header.error;
+
+error_exit:
+ hdb_handle_put (&votequorum_handle_t_db, handle);
+
+ return (error);
+}
+
+cs_error_t votequorum_qdevice_unregister (
+ votequorum_handle_t handle,
+ const char *name)
+{
+ cs_error_t error;
+ struct votequorum_inst *votequorum_inst;
+ struct iovec iov;
+ struct req_lib_votequorum_qdevice_unregister req_lib_votequorum_qdevice_unregister;
+ struct res_lib_votequorum_status res_lib_votequorum_status;
+
+ if ((strlen(name) == 0) ||
+ (strlen(name) >= VOTEQUORUM_QDEVICE_MAX_NAME_LEN)) {
+ return CS_ERR_INVALID_PARAM;
+ }
+
+ error = hdb_error_to_cs(hdb_handle_get (&votequorum_handle_t_db, handle, (void *)&votequorum_inst));
+ if (error != CS_OK) {
+ return (error);
+ }
+
+ req_lib_votequorum_qdevice_unregister.header.size = sizeof (struct req_lib_votequorum_qdevice_unregister);
+ req_lib_votequorum_qdevice_unregister.header.id = MESSAGE_REQ_VOTEQUORUM_QDEVICE_UNREGISTER;
+ strcpy(req_lib_votequorum_qdevice_unregister.name, name);
+
+ iov.iov_base = (char *)&req_lib_votequorum_qdevice_unregister;
+ iov.iov_len = sizeof (struct req_lib_votequorum_qdevice_unregister);
+
+ error = qb_to_cs_error(qb_ipcc_sendv_recv (
+ votequorum_inst->c,
+ &iov,
+ 1,
+ &res_lib_votequorum_status,
+ sizeof (struct res_lib_votequorum_status), CS_IPC_TIMEOUT_MS));
+
+ if (error != CS_OK) {
+ goto error_exit;
+ }
+
+ error = res_lib_votequorum_status.header.error;
+
+error_exit:
+ hdb_handle_put (&votequorum_handle_t_db, handle);
+
+ return (error);
+}
diff --git a/ltmain.sh b/ltmain.sh
new file mode 100644
index 0000000..63ae69d
--- /dev/null
+++ b/ltmain.sh
@@ -0,0 +1,9655 @@
+
+# libtool (GNU libtool) 2.4.2
+# Written by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
+
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006,
+# 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
+# This is free software; see the source for copying conditions. There is NO
+# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+# GNU Libtool 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.
+#
+# As a special exception to the GNU General Public License,
+# if you distribute this file as part of a program or library that
+# is built using GNU Libtool, you may include this file under the
+# same distribution terms that you use for the rest of that program.
+#
+# GNU Libtool 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 GNU Libtool; see the file COPYING. If not, a copy
+# can be downloaded from http://www.gnu.org/licenses/gpl.html,
+# or obtained by writing to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+# Usage: $progname [OPTION]... [MODE-ARG]...
+#
+# Provide generalized library-building support services.
+#
+# --config show all configuration variables
+# --debug enable verbose shell tracing
+# -n, --dry-run display commands without modifying any files
+# --features display basic configuration information and exit
+# --mode=MODE use operation mode MODE
+# --preserve-dup-deps don't remove duplicate dependency libraries
+# --quiet, --silent don't print informational messages
+# --no-quiet, --no-silent
+# print informational messages (default)
+# --no-warn don't display warning messages
+# --tag=TAG use configuration variables from tag TAG
+# -v, --verbose print more informational messages than default
+# --no-verbose don't print the extra informational messages
+# --version print version information
+# -h, --help, --help-all print short, long, or detailed help message
+#
+# MODE must be one of the following:
+#
+# clean remove files from the build directory
+# compile compile a source file into a libtool object
+# execute automatically set library path, then run a program
+# finish complete the installation of libtool libraries
+# install install libraries or executables
+# link create a library or an executable
+# uninstall remove libraries from an installed directory
+#
+# MODE-ARGS vary depending on the MODE. When passed as first option,
+# `--mode=MODE' may be abbreviated as `MODE' or a unique abbreviation of that.
+# Try `$progname --help --mode=MODE' for a more detailed description of MODE.
+#
+# When reporting a bug, please describe a test case to reproduce it and
+# include the following information:
+#
+# host-triplet: $host
+# shell: $SHELL
+# compiler: $LTCC
+# compiler flags: $LTCFLAGS
+# linker: $LD (gnu? $with_gnu_ld)
+# $progname: (GNU libtool) 2.4.2
+# automake: $automake_version
+# autoconf: $autoconf_version
+#
+# Report bugs to <bug-libtool@gnu.org>.
+# GNU libtool home page: <http://www.gnu.org/software/libtool/>.
+# General help using GNU software: <http://www.gnu.org/gethelp/>.
+
+PROGRAM=libtool
+PACKAGE=libtool
+VERSION=2.4.2
+TIMESTAMP=""
+package_revision=1.3337
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+ emulate sh
+ NULLCMD=:
+ # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac
+fi
+BIN_SH=xpg4; export BIN_SH # for Tru64
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
+{
+ eval 'cat <<_LTECHO_EOF
+$1
+_LTECHO_EOF'
+}
+
+# NLS nuisances: We save the old values to restore during execute mode.
+lt_user_locale=
+lt_safe_locale=
+for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES
+do
+ eval "if test \"\${$lt_var+set}\" = set; then
+ save_$lt_var=\$$lt_var
+ $lt_var=C
+ export $lt_var
+ lt_user_locale=\"$lt_var=\\\$save_\$lt_var; \$lt_user_locale\"
+ lt_safe_locale=\"$lt_var=C; \$lt_safe_locale\"
+ fi"
+done
+LC_ALL=C
+LANGUAGE=C
+export LANGUAGE LC_ALL
+
+$lt_unset CDPATH
+
+
+# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh
+# is ksh but when the shell is invoked as "sh" and the current value of
+# the _XPG environment variable is not equal to 1 (one), the special
+# positional parameter $0, within a function call, is the name of the
+# function.
+progpath="$0"
+
+
+
+: ${CP="cp -f"}
+test "${ECHO+set}" = set || ECHO=${as_echo-'printf %s\n'}
+: ${MAKE="make"}
+: ${MKDIR="mkdir"}
+: ${MV="mv -f"}
+: ${RM="rm -f"}
+: ${SHELL="${CONFIG_SHELL-/bin/sh}"}
+: ${Xsed="$SED -e 1s/^X//"}
+
+# Global variables:
+EXIT_SUCCESS=0
+EXIT_FAILURE=1
+EXIT_MISMATCH=63 # $? = 63 is used to indicate version mismatch to missing.
+EXIT_SKIP=77 # $? = 77 is used to indicate a skipped test to automake.
+
+exit_status=$EXIT_SUCCESS
+
+# Make sure IFS has a sensible default
+lt_nl='
+'
+IFS=" $lt_nl"
+
+dirname="s,/[^/]*$,,"
+basename="s,^.*/,,"
+
+# func_dirname file append nondir_replacement
+# Compute the dirname of FILE. If nonempty, add APPEND to the result,
+# otherwise set result to NONDIR_REPLACEMENT.
+func_dirname ()
+{
+ func_dirname_result=`$ECHO "${1}" | $SED "$dirname"`
+ if test "X$func_dirname_result" = "X${1}"; then
+ func_dirname_result="${3}"
+ else
+ func_dirname_result="$func_dirname_result${2}"
+ fi
+} # func_dirname may be replaced by extended shell implementation
+
+
+# func_basename file
+func_basename ()
+{
+ func_basename_result=`$ECHO "${1}" | $SED "$basename"`
+} # func_basename may be replaced by extended shell implementation
+
+
+# func_dirname_and_basename file append nondir_replacement
+# perform func_basename and func_dirname in a single function
+# call:
+# dirname: Compute the dirname of FILE. If nonempty,
+# add APPEND to the result, otherwise set result
+# to NONDIR_REPLACEMENT.
+# value returned in "$func_dirname_result"
+# basename: Compute filename of FILE.
+# value retuned in "$func_basename_result"
+# Implementation must be kept synchronized with func_dirname
+# and func_basename. For efficiency, we do not delegate to
+# those functions but instead duplicate the functionality here.
+func_dirname_and_basename ()
+{
+ # Extract subdirectory from the argument.
+ func_dirname_result=`$ECHO "${1}" | $SED -e "$dirname"`
+ if test "X$func_dirname_result" = "X${1}"; then
+ func_dirname_result="${3}"
+ else
+ func_dirname_result="$func_dirname_result${2}"
+ fi
+ func_basename_result=`$ECHO "${1}" | $SED -e "$basename"`
+} # func_dirname_and_basename may be replaced by extended shell implementation
+
+
+# func_stripname prefix suffix name
+# strip PREFIX and SUFFIX off of NAME.
+# PREFIX and SUFFIX must not contain globbing or regex special
+# characters, hashes, percent signs, but SUFFIX may contain a leading
+# dot (in which case that matches only a dot).
+# func_strip_suffix prefix name
+func_stripname ()
+{
+ case ${2} in
+ .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;;
+ *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;;
+ esac
+} # func_stripname may be replaced by extended shell implementation
+
+
+# These SED scripts presuppose an absolute path with a trailing slash.
+pathcar='s,^/\([^/]*\).*$,\1,'
+pathcdr='s,^/[^/]*,,'
+removedotparts=':dotsl
+ s@/\./@/@g
+ t dotsl
+ s,/\.$,/,'
+collapseslashes='s@/\{1,\}@/@g'
+finalslash='s,/*$,/,'
+
+# func_normal_abspath PATH
+# Remove doubled-up and trailing slashes, "." path components,
+# and cancel out any ".." path components in PATH after making
+# it an absolute path.
+# value returned in "$func_normal_abspath_result"
+func_normal_abspath ()
+{
+ # Start from root dir and reassemble the path.
+ func_normal_abspath_result=
+ func_normal_abspath_tpath=$1
+ func_normal_abspath_altnamespace=
+ case $func_normal_abspath_tpath in
+ "")
+ # Empty path, that just means $cwd.
+ func_stripname '' '/' "`pwd`"
+ func_normal_abspath_result=$func_stripname_result
+ return
+ ;;
+ # The next three entries are used to spot a run of precisely
+ # two leading slashes without using negated character classes;
+ # we take advantage of case's first-match behaviour.
+ ///*)
+ # Unusual form of absolute path, do nothing.
+ ;;
+ //*)
+ # Not necessarily an ordinary path; POSIX reserves leading '//'
+ # and for example Cygwin uses it to access remote file shares
+ # over CIFS/SMB, so we conserve a leading double slash if found.
+ func_normal_abspath_altnamespace=/
+ ;;
+ /*)
+ # Absolute path, do nothing.
+ ;;
+ *)
+ # Relative path, prepend $cwd.
+ func_normal_abspath_tpath=`pwd`/$func_normal_abspath_tpath
+ ;;
+ esac
+ # Cancel out all the simple stuff to save iterations. We also want
+ # the path to end with a slash for ease of parsing, so make sure
+ # there is one (and only one) here.
+ func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \
+ -e "$removedotparts" -e "$collapseslashes" -e "$finalslash"`
+ while :; do
+ # Processed it all yet?
+ if test "$func_normal_abspath_tpath" = / ; then
+ # If we ascended to the root using ".." the result may be empty now.
+ if test -z "$func_normal_abspath_result" ; then
+ func_normal_abspath_result=/
+ fi
+ break
+ fi
+ func_normal_abspath_tcomponent=`$ECHO "$func_normal_abspath_tpath" | $SED \
+ -e "$pathcar"`
+ func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \
+ -e "$pathcdr"`
+ # Figure out what to do with it
+ case $func_normal_abspath_tcomponent in
+ "")
+ # Trailing empty path component, ignore it.
+ ;;
+ ..)
+ # Parent dir; strip last assembled component from result.
+ func_dirname "$func_normal_abspath_result"
+ func_normal_abspath_result=$func_dirname_result
+ ;;
+ *)
+ # Actual path component, append it.
+ func_normal_abspath_result=$func_normal_abspath_result/$func_normal_abspath_tcomponent
+ ;;
+ esac
+ done
+ # Restore leading double-slash if one was found on entry.
+ func_normal_abspath_result=$func_normal_abspath_altnamespace$func_normal_abspath_result
+}
+
+# func_relative_path SRCDIR DSTDIR
+# generates a relative path from SRCDIR to DSTDIR, with a trailing
+# slash if non-empty, suitable for immediately appending a filename
+# without needing to append a separator.
+# value returned in "$func_relative_path_result"
+func_relative_path ()
+{
+ func_relative_path_result=
+ func_normal_abspath "$1"
+ func_relative_path_tlibdir=$func_normal_abspath_result
+ func_normal_abspath "$2"
+ func_relative_path_tbindir=$func_normal_abspath_result
+
+ # Ascend the tree starting from libdir
+ while :; do
+ # check if we have found a prefix of bindir
+ case $func_relative_path_tbindir in
+ $func_relative_path_tlibdir)
+ # found an exact match
+ func_relative_path_tcancelled=
+ break
+ ;;
+ $func_relative_path_tlibdir*)
+ # found a matching prefix
+ func_stripname "$func_relative_path_tlibdir" '' "$func_relative_path_tbindir"
+ func_relative_path_tcancelled=$func_stripname_result
+ if test -z "$func_relative_path_result"; then
+ func_relative_path_result=.
+ fi
+ break
+ ;;
+ *)
+ func_dirname $func_relative_path_tlibdir
+ func_relative_path_tlibdir=${func_dirname_result}
+ if test "x$func_relative_path_tlibdir" = x ; then
+ # Have to descend all the way to the root!
+ func_relative_path_result=../$func_relative_path_result
+ func_relative_path_tcancelled=$func_relative_path_tbindir
+ break
+ fi
+ func_relative_path_result=../$func_relative_path_result
+ ;;
+ esac
+ done
+
+ # Now calculate path; take care to avoid doubling-up slashes.
+ func_stripname '' '/' "$func_relative_path_result"
+ func_relative_path_result=$func_stripname_result
+ func_stripname '/' '/' "$func_relative_path_tcancelled"
+ if test "x$func_stripname_result" != x ; then
+ func_relative_path_result=${func_relative_path_result}/${func_stripname_result}
+ fi
+
+ # Normalisation. If bindir is libdir, return empty string,
+ # else relative path ending with a slash; either way, target
+ # file name can be directly appended.
+ if test ! -z "$func_relative_path_result"; then
+ func_stripname './' '' "$func_relative_path_result/"
+ func_relative_path_result=$func_stripname_result
+ fi
+}
+
+# The name of this program:
+func_dirname_and_basename "$progpath"
+progname=$func_basename_result
+
+# Make sure we have an absolute path for reexecution:
+case $progpath in
+ [\\/]*|[A-Za-z]:\\*) ;;
+ *[\\/]*)
+ progdir=$func_dirname_result
+ progdir=`cd "$progdir" && pwd`
+ progpath="$progdir/$progname"
+ ;;
+ *)
+ save_IFS="$IFS"
+ IFS=${PATH_SEPARATOR-:}
+ for progdir in $PATH; do
+ IFS="$save_IFS"
+ test -x "$progdir/$progname" && break
+ done
+ IFS="$save_IFS"
+ test -n "$progdir" || progdir=`pwd`
+ progpath="$progdir/$progname"
+ ;;
+esac
+
+# Sed substitution that helps us do robust quoting. It backslashifies
+# metacharacters that are still active within double-quoted strings.
+Xsed="${SED}"' -e 1s/^X//'
+sed_quote_subst='s/\([`"$\\]\)/\\\1/g'
+
+# Same as above, but do not quote variable references.
+double_quote_subst='s/\(["`\\]\)/\\\1/g'
+
+# Sed substitution that turns a string into a regex matching for the
+# string literally.
+sed_make_literal_regex='s,[].[^$\\*\/],\\&,g'
+
+# Sed substitution that converts a w32 file name or path
+# which contains forward slashes, into one that contains
+# (escaped) backslashes. A very naive implementation.
+lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g'
+
+# Re-`\' parameter expansions in output of double_quote_subst that were
+# `\'-ed in input to the same. If an odd number of `\' preceded a '$'
+# in input to double_quote_subst, that '$' was protected from expansion.
+# Since each input `\' is now two `\'s, look for any number of runs of
+# four `\'s followed by two `\'s and then a '$'. `\' that '$'.
+bs='\\'
+bs2='\\\\'
+bs4='\\\\\\\\'
+dollar='\$'
+sed_double_backslash="\
+ s/$bs4/&\\
+/g
+ s/^$bs2$dollar/$bs&/
+ s/\\([^$bs]\\)$bs2$dollar/\\1$bs2$bs$dollar/g
+ s/\n//g"
+
+# Standard options:
+opt_dry_run=false
+opt_help=false
+opt_quiet=false
+opt_verbose=false
+opt_warning=:
+
+# func_echo arg...
+# Echo program name prefixed message, along with the current mode
+# name if it has been set yet.
+func_echo ()
+{
+ $ECHO "$progname: ${opt_mode+$opt_mode: }$*"
+}
+
+# func_verbose arg...
+# Echo program name prefixed message in verbose mode only.
+func_verbose ()
+{
+ $opt_verbose && func_echo ${1+"$@"}
+
+ # A bug in bash halts the script if the last line of a function
+ # fails when set -e is in force, so we need another command to
+ # work around that:
+ :
+}
+
+# func_echo_all arg...
+# Invoke $ECHO with all args, space-separated.
+func_echo_all ()
+{
+ $ECHO "$*"
+}
+
+# func_error arg...
+# Echo program name prefixed message to standard error.
+func_error ()
+{
+ $ECHO "$progname: ${opt_mode+$opt_mode: }"${1+"$@"} 1>&2
+}
+
+# func_warning arg...
+# Echo program name prefixed warning message to standard error.
+func_warning ()
+{
+ $opt_warning && $ECHO "$progname: ${opt_mode+$opt_mode: }warning: "${1+"$@"} 1>&2
+
+ # bash bug again:
+ :
+}
+
+# func_fatal_error arg...
+# Echo program name prefixed message to standard error, and exit.
+func_fatal_error ()
+{
+ func_error ${1+"$@"}
+ exit $EXIT_FAILURE
+}
+
+# func_fatal_help arg...
+# Echo program name prefixed message to standard error, followed by
+# a help hint, and exit.
+func_fatal_help ()
+{
+ func_error ${1+"$@"}
+ func_fatal_error "$help"
+}
+help="Try \`$progname --help' for more information." ## default
+
+
+# func_grep expression filename
+# Check whether EXPRESSION matches any line of FILENAME, without output.
+func_grep ()
+{
+ $GREP "$1" "$2" >/dev/null 2>&1
+}
+
+
+# func_mkdir_p directory-path
+# Make sure the entire path to DIRECTORY-PATH is available.
+func_mkdir_p ()
+{
+ my_directory_path="$1"
+ my_dir_list=
+
+ if test -n "$my_directory_path" && test "$opt_dry_run" != ":"; then
+
+ # Protect directory names starting with `-'
+ case $my_directory_path in
+ -*) my_directory_path="./$my_directory_path" ;;
+ esac
+
+ # While some portion of DIR does not yet exist...
+ while test ! -d "$my_directory_path"; do
+ # ...make a list in topmost first order. Use a colon delimited
+ # list incase some portion of path contains whitespace.
+ my_dir_list="$my_directory_path:$my_dir_list"
+
+ # If the last portion added has no slash in it, the list is done
+ case $my_directory_path in */*) ;; *) break ;; esac
+
+ # ...otherwise throw away the child directory and loop
+ my_directory_path=`$ECHO "$my_directory_path" | $SED -e "$dirname"`
+ done
+ my_dir_list=`$ECHO "$my_dir_list" | $SED 's,:*$,,'`
+
+ save_mkdir_p_IFS="$IFS"; IFS=':'
+ for my_dir in $my_dir_list; do
+ IFS="$save_mkdir_p_IFS"
+ # mkdir can fail with a `File exist' error if two processes
+ # try to create one of the directories concurrently. Don't
+ # stop in that case!
+ $MKDIR "$my_dir" 2>/dev/null || :
+ done
+ IFS="$save_mkdir_p_IFS"
+
+ # Bail out if we (or some other process) failed to create a directory.
+ test -d "$my_directory_path" || \
+ func_fatal_error "Failed to create \`$1'"
+ fi
+}
+
+
+# func_mktempdir [string]
+# Make a temporary directory that won't clash with other running
+# libtool processes, and avoids race conditions if possible. If
+# given, STRING is the basename for that directory.
+func_mktempdir ()
+{
+ my_template="${TMPDIR-/tmp}/${1-$progname}"
+
+ if test "$opt_dry_run" = ":"; then
+ # Return a directory name, but don't create it in dry-run mode
+ my_tmpdir="${my_template}-$$"
+ else
+
+ # If mktemp works, use that first and foremost
+ my_tmpdir=`mktemp -d "${my_template}-XXXXXXXX" 2>/dev/null`
+
+ if test ! -d "$my_tmpdir"; then
+ # Failing that, at least try and use $RANDOM to avoid a race
+ my_tmpdir="${my_template}-${RANDOM-0}$$"
+
+ save_mktempdir_umask=`umask`
+ umask 0077
+ $MKDIR "$my_tmpdir"
+ umask $save_mktempdir_umask
+ fi
+
+ # If we're not in dry-run mode, bomb out on failure
+ test -d "$my_tmpdir" || \
+ func_fatal_error "cannot create temporary directory \`$my_tmpdir'"
+ fi
+
+ $ECHO "$my_tmpdir"
+}
+
+
+# func_quote_for_eval arg
+# Aesthetically quote ARG to be evaled later.
+# This function returns two values: FUNC_QUOTE_FOR_EVAL_RESULT
+# is double-quoted, suitable for a subsequent eval, whereas
+# FUNC_QUOTE_FOR_EVAL_UNQUOTED_RESULT has merely all characters
+# which are still active within double quotes backslashified.
+func_quote_for_eval ()
+{
+ case $1 in
+ *[\\\`\"\$]*)
+ func_quote_for_eval_unquoted_result=`$ECHO "$1" | $SED "$sed_quote_subst"` ;;
+ *)
+ func_quote_for_eval_unquoted_result="$1" ;;
+ esac
+
+ case $func_quote_for_eval_unquoted_result in
+ # Double-quote args containing shell metacharacters to delay
+ # word splitting, command substitution and and variable
+ # expansion for a subsequent eval.
+ # Many Bourne shells cannot handle close brackets correctly
+ # in scan sets, so we specify it separately.
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
+ func_quote_for_eval_result="\"$func_quote_for_eval_unquoted_result\""
+ ;;
+ *)
+ func_quote_for_eval_result="$func_quote_for_eval_unquoted_result"
+ esac
+}
+
+
+# func_quote_for_expand arg
+# Aesthetically quote ARG to be evaled later; same as above,
+# but do not quote variable references.
+func_quote_for_expand ()
+{
+ case $1 in
+ *[\\\`\"]*)
+ my_arg=`$ECHO "$1" | $SED \
+ -e "$double_quote_subst" -e "$sed_double_backslash"` ;;
+ *)
+ my_arg="$1" ;;
+ esac
+
+ case $my_arg in
+ # Double-quote args containing shell metacharacters to delay
+ # word splitting and command substitution for a subsequent eval.
+ # Many Bourne shells cannot handle close brackets correctly
+ # in scan sets, so we specify it separately.
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
+ my_arg="\"$my_arg\""
+ ;;
+ esac
+
+ func_quote_for_expand_result="$my_arg"
+}
+
+
+# func_show_eval cmd [fail_exp]
+# Unless opt_silent is true, then output CMD. Then, if opt_dryrun is
+# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP
+# is given, then evaluate it.
+func_show_eval ()
+{
+ my_cmd="$1"
+ my_fail_exp="${2-:}"
+
+ ${opt_silent-false} || {
+ func_quote_for_expand "$my_cmd"
+ eval "func_echo $func_quote_for_expand_result"
+ }
+
+ if ${opt_dry_run-false}; then :; else
+ eval "$my_cmd"
+ my_status=$?
+ if test "$my_status" -eq 0; then :; else
+ eval "(exit $my_status); $my_fail_exp"
+ fi
+ fi
+}
+
+
+# func_show_eval_locale cmd [fail_exp]
+# Unless opt_silent is true, then output CMD. Then, if opt_dryrun is
+# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP
+# is given, then evaluate it. Use the saved locale for evaluation.
+func_show_eval_locale ()
+{
+ my_cmd="$1"
+ my_fail_exp="${2-:}"
+
+ ${opt_silent-false} || {
+ func_quote_for_expand "$my_cmd"
+ eval "func_echo $func_quote_for_expand_result"
+ }
+
+ if ${opt_dry_run-false}; then :; else
+ eval "$lt_user_locale
+ $my_cmd"
+ my_status=$?
+ eval "$lt_safe_locale"
+ if test "$my_status" -eq 0; then :; else
+ eval "(exit $my_status); $my_fail_exp"
+ fi
+ fi
+}
+
+# func_tr_sh
+# Turn $1 into a string suitable for a shell variable name.
+# Result is stored in $func_tr_sh_result. All characters
+# not in the set a-zA-Z0-9_ are replaced with '_'. Further,
+# if $1 begins with a digit, a '_' is prepended as well.
+func_tr_sh ()
+{
+ case $1 in
+ [0-9]* | *[!a-zA-Z0-9_]*)
+ func_tr_sh_result=`$ECHO "$1" | $SED 's/^\([0-9]\)/_\1/; s/[^a-zA-Z0-9_]/_/g'`
+ ;;
+ * )
+ func_tr_sh_result=$1
+ ;;
+ esac
+}
+
+
+# func_version
+# Echo version message to standard output and exit.
+func_version ()
+{
+ $opt_debug
+
+ $SED -n '/(C)/!b go
+ :more
+ /\./!{
+ N
+ s/\n# / /
+ b more
+ }
+ :go
+ /^# '$PROGRAM' (GNU /,/# warranty; / {
+ s/^# //
+ s/^# *$//
+ s/\((C)\)[ 0-9,-]*\( [1-9][0-9]*\)/\1\2/
+ p
+ }' < "$progpath"
+ exit $?
+}
+
+# func_usage
+# Echo short help message to standard output and exit.
+func_usage ()
+{
+ $opt_debug
+
+ $SED -n '/^# Usage:/,/^# *.*--help/ {
+ s/^# //
+ s/^# *$//
+ s/\$progname/'$progname'/
+ p
+ }' < "$progpath"
+ echo
+ $ECHO "run \`$progname --help | more' for full usage"
+ exit $?
+}
+
+# func_help [NOEXIT]
+# Echo long help message to standard output and exit,
+# unless 'noexit' is passed as argument.
+func_help ()
+{
+ $opt_debug
+
+ $SED -n '/^# Usage:/,/# Report bugs to/ {
+ :print
+ s/^# //
+ s/^# *$//
+ s*\$progname*'$progname'*
+ s*\$host*'"$host"'*
+ s*\$SHELL*'"$SHELL"'*
+ s*\$LTCC*'"$LTCC"'*
+ s*\$LTCFLAGS*'"$LTCFLAGS"'*
+ s*\$LD*'"$LD"'*
+ s/\$with_gnu_ld/'"$with_gnu_ld"'/
+ s/\$automake_version/'"`(${AUTOMAKE-automake} --version) 2>/dev/null |$SED 1q`"'/
+ s/\$autoconf_version/'"`(${AUTOCONF-autoconf} --version) 2>/dev/null |$SED 1q`"'/
+ p
+ d
+ }
+ /^# .* home page:/b print
+ /^# General help using/b print
+ ' < "$progpath"
+ ret=$?
+ if test -z "$1"; then
+ exit $ret
+ fi
+}
+
+# func_missing_arg argname
+# Echo program name prefixed message to standard error and set global
+# exit_cmd.
+func_missing_arg ()
+{
+ $opt_debug
+
+ func_error "missing argument for $1."
+ exit_cmd=exit
+}
+
+
+# func_split_short_opt shortopt
+# Set func_split_short_opt_name and func_split_short_opt_arg shell
+# variables after splitting SHORTOPT after the 2nd character.
+func_split_short_opt ()
+{
+ my_sed_short_opt='1s/^\(..\).*$/\1/;q'
+ my_sed_short_rest='1s/^..\(.*\)$/\1/;q'
+
+ func_split_short_opt_name=`$ECHO "$1" | $SED "$my_sed_short_opt"`
+ func_split_short_opt_arg=`$ECHO "$1" | $SED "$my_sed_short_rest"`
+} # func_split_short_opt may be replaced by extended shell implementation
+
+
+# func_split_long_opt longopt
+# Set func_split_long_opt_name and func_split_long_opt_arg shell
+# variables after splitting LONGOPT at the `=' sign.
+func_split_long_opt ()
+{
+ my_sed_long_opt='1s/^\(--[^=]*\)=.*/\1/;q'
+ my_sed_long_arg='1s/^--[^=]*=//'
+
+ func_split_long_opt_name=`$ECHO "$1" | $SED "$my_sed_long_opt"`
+ func_split_long_opt_arg=`$ECHO "$1" | $SED "$my_sed_long_arg"`
+} # func_split_long_opt may be replaced by extended shell implementation
+
+exit_cmd=:
+
+
+
+
+
+magic="%%%MAGIC variable%%%"
+magic_exe="%%%MAGIC EXE variable%%%"
+
+# Global variables.
+nonopt=
+preserve_args=
+lo2o="s/\\.lo\$/.${objext}/"
+o2lo="s/\\.${objext}\$/.lo/"
+extracted_archives=
+extracted_serial=0
+
+# If this variable is set in any of the actions, the command in it
+# will be execed at the end. This prevents here-documents from being
+# left over by shells.
+exec_cmd=
+
+# func_append var value
+# Append VALUE to the end of shell variable VAR.
+func_append ()
+{
+ eval "${1}=\$${1}\${2}"
+} # func_append may be replaced by extended shell implementation
+
+# func_append_quoted var value
+# Quote VALUE and append to the end of shell variable VAR, separated
+# by a space.
+func_append_quoted ()
+{
+ func_quote_for_eval "${2}"
+ eval "${1}=\$${1}\\ \$func_quote_for_eval_result"
+} # func_append_quoted may be replaced by extended shell implementation
+
+
+# func_arith arithmetic-term...
+func_arith ()
+{
+ func_arith_result=`expr "${@}"`
+} # func_arith may be replaced by extended shell implementation
+
+
+# func_len string
+# STRING may not start with a hyphen.
+func_len ()
+{
+ func_len_result=`expr "${1}" : ".*" 2>/dev/null || echo $max_cmd_len`
+} # func_len may be replaced by extended shell implementation
+
+
+# func_lo2o object
+func_lo2o ()
+{
+ func_lo2o_result=`$ECHO "${1}" | $SED "$lo2o"`
+} # func_lo2o may be replaced by extended shell implementation
+
+
+# func_xform libobj-or-source
+func_xform ()
+{
+ func_xform_result=`$ECHO "${1}" | $SED 's/\.[^.]*$/.lo/'`
+} # func_xform may be replaced by extended shell implementation
+
+
+# func_fatal_configuration arg...
+# Echo program name prefixed message to standard error, followed by
+# a configuration failure hint, and exit.
+func_fatal_configuration ()
+{
+ func_error ${1+"$@"}
+ func_error "See the $PACKAGE documentation for more information."
+ func_fatal_error "Fatal configuration error."
+}
+
+
+# func_config
+# Display the configuration for all the tags in this script.
+func_config ()
+{
+ re_begincf='^# ### BEGIN LIBTOOL'
+ re_endcf='^# ### END LIBTOOL'
+
+ # Default configuration.
+ $SED "1,/$re_begincf CONFIG/d;/$re_endcf CONFIG/,\$d" < "$progpath"
+
+ # Now print the configurations for the tags.
+ for tagname in $taglist; do
+ $SED -n "/$re_begincf TAG CONFIG: $tagname\$/,/$re_endcf TAG CONFIG: $tagname\$/p" < "$progpath"
+ done
+
+ exit $?
+}
+
+# func_features
+# Display the features supported by this script.
+func_features ()
+{
+ echo "host: $host"
+ if test "$build_libtool_libs" = yes; then
+ echo "enable shared libraries"
+ else
+ echo "disable shared libraries"
+ fi
+ if test "$build_old_libs" = yes; then
+ echo "enable static libraries"
+ else
+ echo "disable static libraries"
+ fi
+
+ exit $?
+}
+
+# func_enable_tag tagname
+# Verify that TAGNAME is valid, and either flag an error and exit, or
+# enable the TAGNAME tag. We also add TAGNAME to the global $taglist
+# variable here.
+func_enable_tag ()
+{
+ # Global variable:
+ tagname="$1"
+
+ re_begincf="^# ### BEGIN LIBTOOL TAG CONFIG: $tagname\$"
+ re_endcf="^# ### END LIBTOOL TAG CONFIG: $tagname\$"
+ sed_extractcf="/$re_begincf/,/$re_endcf/p"
+
+ # Validate tagname.
+ case $tagname in
+ *[!-_A-Za-z0-9,/]*)
+ func_fatal_error "invalid tag name: $tagname"
+ ;;
+ esac
+
+ # Don't test for the "default" C tag, as we know it's
+ # there but not specially marked.
+ case $tagname in
+ CC) ;;
+ *)
+ if $GREP "$re_begincf" "$progpath" >/dev/null 2>&1; then
+ taglist="$taglist $tagname"
+
+ # Evaluate the configuration. Be careful to quote the path
+ # and the sed script, to avoid splitting on whitespace, but
+ # also don't use non-portable quotes within backquotes within
+ # quotes we have to do it in 2 steps:
+ extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"`
+ eval "$extractedcf"
+ else
+ func_error "ignoring unknown tag $tagname"
+ fi
+ ;;
+ esac
+}
+
+# func_check_version_match
+# Ensure that we are using m4 macros, and libtool script from the same
+# release of libtool.
+func_check_version_match ()
+{
+ if test "$package_revision" != "$macro_revision"; then
+ if test "$VERSION" != "$macro_version"; then
+ if test -z "$macro_version"; then
+ cat >&2 <<_LT_EOF
+$progname: Version mismatch error. This is $PACKAGE $VERSION, but the
+$progname: definition of this LT_INIT comes from an older release.
+$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION
+$progname: and run autoconf again.
+_LT_EOF
+ else
+ cat >&2 <<_LT_EOF
+$progname: Version mismatch error. This is $PACKAGE $VERSION, but the
+$progname: definition of this LT_INIT comes from $PACKAGE $macro_version.
+$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION
+$progname: and run autoconf again.
+_LT_EOF
+ fi
+ else
+ cat >&2 <<_LT_EOF
+$progname: Version mismatch error. This is $PACKAGE $VERSION, revision $package_revision,
+$progname: but the definition of this LT_INIT comes from revision $macro_revision.
+$progname: You should recreate aclocal.m4 with macros from revision $package_revision
+$progname: of $PACKAGE $VERSION and run autoconf again.
+_LT_EOF
+ fi
+
+ exit $EXIT_MISMATCH
+ fi
+}
+
+
+# Shorthand for --mode=foo, only valid as the first argument
+case $1 in
+clean|clea|cle|cl)
+ shift; set dummy --mode clean ${1+"$@"}; shift
+ ;;
+compile|compil|compi|comp|com|co|c)
+ shift; set dummy --mode compile ${1+"$@"}; shift
+ ;;
+execute|execut|execu|exec|exe|ex|e)
+ shift; set dummy --mode execute ${1+"$@"}; shift
+ ;;
+finish|finis|fini|fin|fi|f)
+ shift; set dummy --mode finish ${1+"$@"}; shift
+ ;;
+install|instal|insta|inst|ins|in|i)
+ shift; set dummy --mode install ${1+"$@"}; shift
+ ;;
+link|lin|li|l)
+ shift; set dummy --mode link ${1+"$@"}; shift
+ ;;
+uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u)
+ shift; set dummy --mode uninstall ${1+"$@"}; shift
+ ;;
+esac
+
+
+
+# Option defaults:
+opt_debug=:
+opt_dry_run=false
+opt_config=false
+opt_preserve_dup_deps=false
+opt_features=false
+opt_finish=false
+opt_help=false
+opt_help_all=false
+opt_silent=:
+opt_warning=:
+opt_verbose=:
+opt_silent=false
+opt_verbose=false
+
+
+# Parse options once, thoroughly. This comes as soon as possible in the
+# script to make things like `--version' happen as quickly as we can.
+{
+ # this just eases exit handling
+ while test $# -gt 0; do
+ opt="$1"
+ shift
+ case $opt in
+ --debug|-x) opt_debug='set -x'
+ func_echo "enabling shell trace mode"
+ $opt_debug
+ ;;
+ --dry-run|--dryrun|-n)
+ opt_dry_run=:
+ ;;
+ --config)
+ opt_config=:
+func_config
+ ;;
+ --dlopen|-dlopen)
+ optarg="$1"
+ opt_dlopen="${opt_dlopen+$opt_dlopen
+}$optarg"
+ shift
+ ;;
+ --preserve-dup-deps)
+ opt_preserve_dup_deps=:
+ ;;
+ --features)
+ opt_features=:
+func_features
+ ;;
+ --finish)
+ opt_finish=:
+set dummy --mode finish ${1+"$@"}; shift
+ ;;
+ --help)
+ opt_help=:
+ ;;
+ --help-all)
+ opt_help_all=:
+opt_help=': help-all'
+ ;;
+ --mode)
+ test $# = 0 && func_missing_arg $opt && break
+ optarg="$1"
+ opt_mode="$optarg"
+case $optarg in
+ # Valid mode arguments:
+ clean|compile|execute|finish|install|link|relink|uninstall) ;;
+
+ # Catch anything else as an error
+ *) func_error "invalid argument for $opt"
+ exit_cmd=exit
+ break
+ ;;
+esac
+ shift
+ ;;
+ --no-silent|--no-quiet)
+ opt_silent=false
+func_append preserve_args " $opt"
+ ;;
+ --no-warning|--no-warn)
+ opt_warning=false
+func_append preserve_args " $opt"
+ ;;
+ --no-verbose)
+ opt_verbose=false
+func_append preserve_args " $opt"
+ ;;
+ --silent|--quiet)
+ opt_silent=:
+func_append preserve_args " $opt"
+ opt_verbose=false
+ ;;
+ --verbose|-v)
+ opt_verbose=:
+func_append preserve_args " $opt"
+opt_silent=false
+ ;;
+ --tag)
+ test $# = 0 && func_missing_arg $opt && break
+ optarg="$1"
+ opt_tag="$optarg"
+func_append preserve_args " $opt $optarg"
+func_enable_tag "$optarg"
+ shift
+ ;;
+
+ -\?|-h) func_usage ;;
+ --help) func_help ;;
+ --version) func_version ;;
+
+ # Separate optargs to long options:
+ --*=*)
+ func_split_long_opt "$opt"
+ set dummy "$func_split_long_opt_name" "$func_split_long_opt_arg" ${1+"$@"}
+ shift
+ ;;
+
+ # Separate non-argument short options:
+ -\?*|-h*|-n*|-v*)
+ func_split_short_opt "$opt"
+ set dummy "$func_split_short_opt_name" "-$func_split_short_opt_arg" ${1+"$@"}
+ shift
+ ;;
+
+ --) break ;;
+ -*) func_fatal_help "unrecognized option \`$opt'" ;;
+ *) set dummy "$opt" ${1+"$@"}; shift; break ;;
+ esac
+ done
+
+ # Validate options:
+
+ # save first non-option argument
+ if test "$#" -gt 0; then
+ nonopt="$opt"
+ shift
+ fi
+
+ # preserve --debug
+ test "$opt_debug" = : || func_append preserve_args " --debug"
+
+ case $host in
+ *cygwin* | *mingw* | *pw32* | *cegcc*)
+ # don't eliminate duplications in $postdeps and $predeps
+ opt_duplicate_compiler_generated_deps=:
+ ;;
+ *)
+ opt_duplicate_compiler_generated_deps=$opt_preserve_dup_deps
+ ;;
+ esac
+
+ $opt_help || {
+ # Sanity checks first:
+ func_check_version_match
+
+ if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then
+ func_fatal_configuration "not configured to build any kind of library"
+ fi
+
+ # Darwin sucks
+ eval std_shrext=\"$shrext_cmds\"
+
+ # Only execute mode is allowed to have -dlopen flags.
+ if test -n "$opt_dlopen" && test "$opt_mode" != execute; then
+ func_error "unrecognized option \`-dlopen'"
+ $ECHO "$help" 1>&2
+ exit $EXIT_FAILURE
+ fi
+
+ # Change the help message to a mode-specific one.
+ generic_help="$help"
+ help="Try \`$progname --help --mode=$opt_mode' for more information."
+ }
+
+
+ # Bail if the options were screwed
+ $exit_cmd $EXIT_FAILURE
+}
+
+
+
+
+## ----------- ##
+## Main. ##
+## ----------- ##
+
+# func_lalib_p file
+# True iff FILE is a libtool `.la' library or `.lo' object file.
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_lalib_p ()
+{
+ test -f "$1" &&
+ $SED -e 4q "$1" 2>/dev/null \
+ | $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1
+}
+
+# func_lalib_unsafe_p file
+# True iff FILE is a libtool `.la' library or `.lo' object file.
+# This function implements the same check as func_lalib_p without
+# resorting to external programs. To this end, it redirects stdin and
+# closes it afterwards, without saving the original file descriptor.
+# As a safety measure, use it only where a negative result would be
+# fatal anyway. Works if `file' does not exist.
+func_lalib_unsafe_p ()
+{
+ lalib_p=no
+ if test -f "$1" && test -r "$1" && exec 5<&0 <"$1"; then
+ for lalib_p_l in 1 2 3 4
+ do
+ read lalib_p_line
+ case "$lalib_p_line" in
+ \#\ Generated\ by\ *$PACKAGE* ) lalib_p=yes; break;;
+ esac
+ done
+ exec 0<&5 5<&-
+ fi
+ test "$lalib_p" = yes
+}
+
+# func_ltwrapper_script_p file
+# True iff FILE is a libtool wrapper script
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_ltwrapper_script_p ()
+{
+ func_lalib_p "$1"
+}
+
+# func_ltwrapper_executable_p file
+# True iff FILE is a libtool wrapper executable
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_ltwrapper_executable_p ()
+{
+ func_ltwrapper_exec_suffix=
+ case $1 in
+ *.exe) ;;
+ *) func_ltwrapper_exec_suffix=.exe ;;
+ esac
+ $GREP "$magic_exe" "$1$func_ltwrapper_exec_suffix" >/dev/null 2>&1
+}
+
+# func_ltwrapper_scriptname file
+# Assumes file is an ltwrapper_executable
+# uses $file to determine the appropriate filename for a
+# temporary ltwrapper_script.
+func_ltwrapper_scriptname ()
+{
+ func_dirname_and_basename "$1" "" "."
+ func_stripname '' '.exe' "$func_basename_result"
+ func_ltwrapper_scriptname_result="$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper"
+}
+
+# func_ltwrapper_p file
+# True iff FILE is a libtool wrapper script or wrapper executable
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_ltwrapper_p ()
+{
+ func_ltwrapper_script_p "$1" || func_ltwrapper_executable_p "$1"
+}
+
+
+# func_execute_cmds commands fail_cmd
+# Execute tilde-delimited COMMANDS.
+# If FAIL_CMD is given, eval that upon failure.
+# FAIL_CMD may read-access the current command in variable CMD!
+func_execute_cmds ()
+{
+ $opt_debug
+ save_ifs=$IFS; IFS='~'
+ for cmd in $1; do
+ IFS=$save_ifs
+ eval cmd=\"$cmd\"
+ func_show_eval "$cmd" "${2-:}"
+ done
+ IFS=$save_ifs
+}
+
+
+# func_source file
+# Source FILE, adding directory component if necessary.
+# Note that it is not necessary on cygwin/mingw to append a dot to
+# FILE even if both FILE and FILE.exe exist: automatic-append-.exe
+# behavior happens only for exec(3), not for open(2)! Also, sourcing
+# `FILE.' does not work on cygwin managed mounts.
+func_source ()
+{
+ $opt_debug
+ case $1 in
+ */* | *\\*) . "$1" ;;
+ *) . "./$1" ;;
+ esac
+}
+
+
+# func_resolve_sysroot PATH
+# Replace a leading = in PATH with a sysroot. Store the result into
+# func_resolve_sysroot_result
+func_resolve_sysroot ()
+{
+ func_resolve_sysroot_result=$1
+ case $func_resolve_sysroot_result in
+ =*)
+ func_stripname '=' '' "$func_resolve_sysroot_result"
+ func_resolve_sysroot_result=$lt_sysroot$func_stripname_result
+ ;;
+ esac
+}
+
+# func_replace_sysroot PATH
+# If PATH begins with the sysroot, replace it with = and
+# store the result into func_replace_sysroot_result.
+func_replace_sysroot ()
+{
+ case "$lt_sysroot:$1" in
+ ?*:"$lt_sysroot"*)
+ func_stripname "$lt_sysroot" '' "$1"
+ func_replace_sysroot_result="=$func_stripname_result"
+ ;;
+ *)
+ # Including no sysroot.
+ func_replace_sysroot_result=$1
+ ;;
+ esac
+}
+
+# func_infer_tag arg
+# Infer tagged configuration to use if any are available and
+# if one wasn't chosen via the "--tag" command line option.
+# Only attempt this if the compiler in the base compile
+# command doesn't match the default compiler.
+# arg is usually of the form 'gcc ...'
+func_infer_tag ()
+{
+ $opt_debug
+ if test -n "$available_tags" && test -z "$tagname"; then
+ CC_quoted=
+ for arg in $CC; do
+ func_append_quoted CC_quoted "$arg"
+ done
+ CC_expanded=`func_echo_all $CC`
+ CC_quoted_expanded=`func_echo_all $CC_quoted`
+ case $@ in
+ # Blanks in the command may have been stripped by the calling shell,
+ # but not from the CC environment variable when configure was run.
+ " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \
+ " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) ;;
+ # Blanks at the start of $base_compile will cause this to fail
+ # if we don't check for them as well.
+ *)
+ for z in $available_tags; do
+ if $GREP "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then
+ # Evaluate the configuration.
+ eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`"
+ CC_quoted=
+ for arg in $CC; do
+ # Double-quote args containing other shell metacharacters.
+ func_append_quoted CC_quoted "$arg"
+ done
+ CC_expanded=`func_echo_all $CC`
+ CC_quoted_expanded=`func_echo_all $CC_quoted`
+ case "$@ " in
+ " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \
+ " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*)
+ # The compiler in the base compile command matches
+ # the one in the tagged configuration.
+ # Assume this is the tagged configuration we want.
+ tagname=$z
+ break
+ ;;
+ esac
+ fi
+ done
+ # If $tagname still isn't set, then no tagged configuration
+ # was found and let the user know that the "--tag" command
+ # line option must be used.
+ if test -z "$tagname"; then
+ func_echo "unable to infer tagged configuration"
+ func_fatal_error "specify a tag with \`--tag'"
+# else
+# func_verbose "using $tagname tagged configuration"
+ fi
+ ;;
+ esac
+ fi
+}
+
+
+
+# func_write_libtool_object output_name pic_name nonpic_name
+# Create a libtool object file (analogous to a ".la" file),
+# but don't create it if we're doing a dry run.
+func_write_libtool_object ()
+{
+ write_libobj=${1}
+ if test "$build_libtool_libs" = yes; then
+ write_lobj=\'${2}\'
+ else
+ write_lobj=none
+ fi
+
+ if test "$build_old_libs" = yes; then
+ write_oldobj=\'${3}\'
+ else
+ write_oldobj=none
+ fi
+
+ $opt_dry_run || {
+ cat >${write_libobj}T <<EOF
+# $write_libobj - a libtool object file
+# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION
+#
+# Please DO NOT delete this file!
+# It is necessary for linking the library.
+
+# Name of the PIC object.
+pic_object=$write_lobj
+
+# Name of the non-PIC object
+non_pic_object=$write_oldobj
+
+EOF
+ $MV "${write_libobj}T" "${write_libobj}"
+ }
+}
+
+
+##################################################
+# FILE NAME AND PATH CONVERSION HELPER FUNCTIONS #
+##################################################
+
+# func_convert_core_file_wine_to_w32 ARG
+# Helper function used by file name conversion functions when $build is *nix,
+# and $host is mingw, cygwin, or some other w32 environment. Relies on a
+# correctly configured wine environment available, with the winepath program
+# in $build's $PATH.
+#
+# ARG is the $build file name to be converted to w32 format.
+# Result is available in $func_convert_core_file_wine_to_w32_result, and will
+# be empty on error (or when ARG is empty)
+func_convert_core_file_wine_to_w32 ()
+{
+ $opt_debug
+ func_convert_core_file_wine_to_w32_result="$1"
+ if test -n "$1"; then
+ # Unfortunately, winepath does not exit with a non-zero error code, so we
+ # are forced to check the contents of stdout. On the other hand, if the
+ # command is not found, the shell will set an exit code of 127 and print
+ # *an error message* to stdout. So we must check for both error code of
+ # zero AND non-empty stdout, which explains the odd construction:
+ func_convert_core_file_wine_to_w32_tmp=`winepath -w "$1" 2>/dev/null`
+ if test "$?" -eq 0 && test -n "${func_convert_core_file_wine_to_w32_tmp}"; then
+ func_convert_core_file_wine_to_w32_result=`$ECHO "$func_convert_core_file_wine_to_w32_tmp" |
+ $SED -e "$lt_sed_naive_backslashify"`
+ else
+ func_convert_core_file_wine_to_w32_result=
+ fi
+ fi
+}
+# end: func_convert_core_file_wine_to_w32
+
+
+# func_convert_core_path_wine_to_w32 ARG
+# Helper function used by path conversion functions when $build is *nix, and
+# $host is mingw, cygwin, or some other w32 environment. Relies on a correctly
+# configured wine environment available, with the winepath program in $build's
+# $PATH. Assumes ARG has no leading or trailing path separator characters.
+#
+# ARG is path to be converted from $build format to win32.
+# Result is available in $func_convert_core_path_wine_to_w32_result.
+# Unconvertible file (directory) names in ARG are skipped; if no directory names
+# are convertible, then the result may be empty.
+func_convert_core_path_wine_to_w32 ()
+{
+ $opt_debug
+ # unfortunately, winepath doesn't convert paths, only file names
+ func_convert_core_path_wine_to_w32_result=""
+ if test -n "$1"; then
+ oldIFS=$IFS
+ IFS=:
+ for func_convert_core_path_wine_to_w32_f in $1; do
+ IFS=$oldIFS
+ func_convert_core_file_wine_to_w32 "$func_convert_core_path_wine_to_w32_f"
+ if test -n "$func_convert_core_file_wine_to_w32_result" ; then
+ if test -z "$func_convert_core_path_wine_to_w32_result"; then
+ func_convert_core_path_wine_to_w32_result="$func_convert_core_file_wine_to_w32_result"
+ else
+ func_append func_convert_core_path_wine_to_w32_result ";$func_convert_core_file_wine_to_w32_result"
+ fi
+ fi
+ done
+ IFS=$oldIFS
+ fi
+}
+# end: func_convert_core_path_wine_to_w32
+
+
+# func_cygpath ARGS...
+# Wrapper around calling the cygpath program via LT_CYGPATH. This is used when
+# when (1) $build is *nix and Cygwin is hosted via a wine environment; or (2)
+# $build is MSYS and $host is Cygwin, or (3) $build is Cygwin. In case (1) or
+# (2), returns the Cygwin file name or path in func_cygpath_result (input
+# file name or path is assumed to be in w32 format, as previously converted
+# from $build's *nix or MSYS format). In case (3), returns the w32 file name
+# or path in func_cygpath_result (input file name or path is assumed to be in
+# Cygwin format). Returns an empty string on error.
+#
+# ARGS are passed to cygpath, with the last one being the file name or path to
+# be converted.
+#
+# Specify the absolute *nix (or w32) name to cygpath in the LT_CYGPATH
+# environment variable; do not put it in $PATH.
+func_cygpath ()
+{
+ $opt_debug
+ if test -n "$LT_CYGPATH" && test -f "$LT_CYGPATH"; then
+ func_cygpath_result=`$LT_CYGPATH "$@" 2>/dev/null`
+ if test "$?" -ne 0; then
+ # on failure, ensure result is empty
+ func_cygpath_result=
+ fi
+ else
+ func_cygpath_result=
+ func_error "LT_CYGPATH is empty or specifies non-existent file: \`$LT_CYGPATH'"
+ fi
+}
+#end: func_cygpath
+
+
+# func_convert_core_msys_to_w32 ARG
+# Convert file name or path ARG from MSYS format to w32 format. Return
+# result in func_convert_core_msys_to_w32_result.
+func_convert_core_msys_to_w32 ()
+{
+ $opt_debug
+ # awkward: cmd appends spaces to result
+ func_convert_core_msys_to_w32_result=`( cmd //c echo "$1" ) 2>/dev/null |
+ $SED -e 's/[ ]*$//' -e "$lt_sed_naive_backslashify"`
+}
+#end: func_convert_core_msys_to_w32
+
+
+# func_convert_file_check ARG1 ARG2
+# Verify that ARG1 (a file name in $build format) was converted to $host
+# format in ARG2. Otherwise, emit an error message, but continue (resetting
+# func_to_host_file_result to ARG1).
+func_convert_file_check ()
+{
+ $opt_debug
+ if test -z "$2" && test -n "$1" ; then
+ func_error "Could not determine host file name corresponding to"
+ func_error " \`$1'"
+ func_error "Continuing, but uninstalled executables may not work."
+ # Fallback:
+ func_to_host_file_result="$1"
+ fi
+}
+# end func_convert_file_check
+
+
+# func_convert_path_check FROM_PATHSEP TO_PATHSEP FROM_PATH TO_PATH
+# Verify that FROM_PATH (a path in $build format) was converted to $host
+# format in TO_PATH. Otherwise, emit an error message, but continue, resetting
+# func_to_host_file_result to a simplistic fallback value (see below).
+func_convert_path_check ()
+{
+ $opt_debug
+ if test -z "$4" && test -n "$3"; then
+ func_error "Could not determine the host path corresponding to"
+ func_error " \`$3'"
+ func_error "Continuing, but uninstalled executables may not work."
+ # Fallback. This is a deliberately simplistic "conversion" and
+ # should not be "improved". See libtool.info.
+ if test "x$1" != "x$2"; then
+ lt_replace_pathsep_chars="s|$1|$2|g"
+ func_to_host_path_result=`echo "$3" |
+ $SED -e "$lt_replace_pathsep_chars"`
+ else
+ func_to_host_path_result="$3"
+ fi
+ fi
+}
+# end func_convert_path_check
+
+
+# func_convert_path_front_back_pathsep FRONTPAT BACKPAT REPL ORIG
+# Modifies func_to_host_path_result by prepending REPL if ORIG matches FRONTPAT
+# and appending REPL if ORIG matches BACKPAT.
+func_convert_path_front_back_pathsep ()
+{
+ $opt_debug
+ case $4 in
+ $1 ) func_to_host_path_result="$3$func_to_host_path_result"
+ ;;
+ esac
+ case $4 in
+ $2 ) func_append func_to_host_path_result "$3"
+ ;;
+ esac
+}
+# end func_convert_path_front_back_pathsep
+
+
+##################################################
+# $build to $host FILE NAME CONVERSION FUNCTIONS #
+##################################################
+# invoked via `$to_host_file_cmd ARG'
+#
+# In each case, ARG is the path to be converted from $build to $host format.
+# Result will be available in $func_to_host_file_result.
+
+
+# func_to_host_file ARG
+# Converts the file name ARG from $build format to $host format. Return result
+# in func_to_host_file_result.
+func_to_host_file ()
+{
+ $opt_debug
+ $to_host_file_cmd "$1"
+}
+# end func_to_host_file
+
+
+# func_to_tool_file ARG LAZY
+# converts the file name ARG from $build format to toolchain format. Return
+# result in func_to_tool_file_result. If the conversion in use is listed
+# in (the comma separated) LAZY, no conversion takes place.
+func_to_tool_file ()
+{
+ $opt_debug
+ case ,$2, in
+ *,"$to_tool_file_cmd",*)
+ func_to_tool_file_result=$1
+ ;;
+ *)
+ $to_tool_file_cmd "$1"
+ func_to_tool_file_result=$func_to_host_file_result
+ ;;
+ esac
+}
+# end func_to_tool_file
+
+
+# func_convert_file_noop ARG
+# Copy ARG to func_to_host_file_result.
+func_convert_file_noop ()
+{
+ func_to_host_file_result="$1"
+}
+# end func_convert_file_noop
+
+
+# func_convert_file_msys_to_w32 ARG
+# Convert file name ARG from (mingw) MSYS to (mingw) w32 format; automatic
+# conversion to w32 is not available inside the cwrapper. Returns result in
+# func_to_host_file_result.
+func_convert_file_msys_to_w32 ()
+{
+ $opt_debug
+ func_to_host_file_result="$1"
+ if test -n "$1"; then
+ func_convert_core_msys_to_w32 "$1"
+ func_to_host_file_result="$func_convert_core_msys_to_w32_result"
+ fi
+ func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_msys_to_w32
+
+
+# func_convert_file_cygwin_to_w32 ARG
+# Convert file name ARG from Cygwin to w32 format. Returns result in
+# func_to_host_file_result.
+func_convert_file_cygwin_to_w32 ()
+{
+ $opt_debug
+ func_to_host_file_result="$1"
+ if test -n "$1"; then
+ # because $build is cygwin, we call "the" cygpath in $PATH; no need to use
+ # LT_CYGPATH in this case.
+ func_to_host_file_result=`cygpath -m "$1"`
+ fi
+ func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_cygwin_to_w32
+
+
+# func_convert_file_nix_to_w32 ARG
+# Convert file name ARG from *nix to w32 format. Requires a wine environment
+# and a working winepath. Returns result in func_to_host_file_result.
+func_convert_file_nix_to_w32 ()
+{
+ $opt_debug
+ func_to_host_file_result="$1"
+ if test -n "$1"; then
+ func_convert_core_file_wine_to_w32 "$1"
+ func_to_host_file_result="$func_convert_core_file_wine_to_w32_result"
+ fi
+ func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_nix_to_w32
+
+
+# func_convert_file_msys_to_cygwin ARG
+# Convert file name ARG from MSYS to Cygwin format. Requires LT_CYGPATH set.
+# Returns result in func_to_host_file_result.
+func_convert_file_msys_to_cygwin ()
+{
+ $opt_debug
+ func_to_host_file_result="$1"
+ if test -n "$1"; then
+ func_convert_core_msys_to_w32 "$1"
+ func_cygpath -u "$func_convert_core_msys_to_w32_result"
+ func_to_host_file_result="$func_cygpath_result"
+ fi
+ func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_msys_to_cygwin
+
+
+# func_convert_file_nix_to_cygwin ARG
+# Convert file name ARG from *nix to Cygwin format. Requires Cygwin installed
+# in a wine environment, working winepath, and LT_CYGPATH set. Returns result
+# in func_to_host_file_result.
+func_convert_file_nix_to_cygwin ()
+{
+ $opt_debug
+ func_to_host_file_result="$1"
+ if test -n "$1"; then
+ # convert from *nix to w32, then use cygpath to convert from w32 to cygwin.
+ func_convert_core_file_wine_to_w32 "$1"
+ func_cygpath -u "$func_convert_core_file_wine_to_w32_result"
+ func_to_host_file_result="$func_cygpath_result"
+ fi
+ func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_nix_to_cygwin
+
+
+#############################################
+# $build to $host PATH CONVERSION FUNCTIONS #
+#############################################
+# invoked via `$to_host_path_cmd ARG'
+#
+# In each case, ARG is the path to be converted from $build to $host format.
+# The result will be available in $func_to_host_path_result.
+#
+# Path separators are also converted from $build format to $host format. If
+# ARG begins or ends with a path separator character, it is preserved (but
+# converted to $host format) on output.
+#
+# All path conversion functions are named using the following convention:
+# file name conversion function : func_convert_file_X_to_Y ()
+# path conversion function : func_convert_path_X_to_Y ()
+# where, for any given $build/$host combination the 'X_to_Y' value is the
+# same. If conversion functions are added for new $build/$host combinations,
+# the two new functions must follow this pattern, or func_init_to_host_path_cmd
+# will break.
+
+
+# func_init_to_host_path_cmd
+# Ensures that function "pointer" variable $to_host_path_cmd is set to the
+# appropriate value, based on the value of $to_host_file_cmd.
+to_host_path_cmd=
+func_init_to_host_path_cmd ()
+{
+ $opt_debug
+ if test -z "$to_host_path_cmd"; then
+ func_stripname 'func_convert_file_' '' "$to_host_file_cmd"
+ to_host_path_cmd="func_convert_path_${func_stripname_result}"
+ fi
+}
+
+
+# func_to_host_path ARG
+# Converts the path ARG from $build format to $host format. Return result
+# in func_to_host_path_result.
+func_to_host_path ()
+{
+ $opt_debug
+ func_init_to_host_path_cmd
+ $to_host_path_cmd "$1"
+}
+# end func_to_host_path
+
+
+# func_convert_path_noop ARG
+# Copy ARG to func_to_host_path_result.
+func_convert_path_noop ()
+{
+ func_to_host_path_result="$1"
+}
+# end func_convert_path_noop
+
+
+# func_convert_path_msys_to_w32 ARG
+# Convert path ARG from (mingw) MSYS to (mingw) w32 format; automatic
+# conversion to w32 is not available inside the cwrapper. Returns result in
+# func_to_host_path_result.
+func_convert_path_msys_to_w32 ()
+{
+ $opt_debug
+ func_to_host_path_result="$1"
+ if test -n "$1"; then
+ # Remove leading and trailing path separator characters from ARG. MSYS
+ # behavior is inconsistent here; cygpath turns them into '.;' and ';.';
+ # and winepath ignores them completely.
+ func_stripname : : "$1"
+ func_to_host_path_tmp1=$func_stripname_result
+ func_convert_core_msys_to_w32 "$func_to_host_path_tmp1"
+ func_to_host_path_result="$func_convert_core_msys_to_w32_result"
+ func_convert_path_check : ";" \
+ "$func_to_host_path_tmp1" "$func_to_host_path_result"
+ func_convert_path_front_back_pathsep ":*" "*:" ";" "$1"
+ fi
+}
+# end func_convert_path_msys_to_w32
+
+
+# func_convert_path_cygwin_to_w32 ARG
+# Convert path ARG from Cygwin to w32 format. Returns result in
+# func_to_host_file_result.
+func_convert_path_cygwin_to_w32 ()
+{
+ $opt_debug
+ func_to_host_path_result="$1"
+ if test -n "$1"; then
+ # See func_convert_path_msys_to_w32:
+ func_stripname : : "$1"
+ func_to_host_path_tmp1=$func_stripname_result
+ func_to_host_path_result=`cygpath -m -p "$func_to_host_path_tmp1"`
+ func_convert_path_check : ";" \
+ "$func_to_host_path_tmp1" "$func_to_host_path_result"
+ func_convert_path_front_back_pathsep ":*" "*:" ";" "$1"
+ fi
+}
+# end func_convert_path_cygwin_to_w32
+
+
+# func_convert_path_nix_to_w32 ARG
+# Convert path ARG from *nix to w32 format. Requires a wine environment and
+# a working winepath. Returns result in func_to_host_file_result.
+func_convert_path_nix_to_w32 ()
+{
+ $opt_debug
+ func_to_host_path_result="$1"
+ if test -n "$1"; then
+ # See func_convert_path_msys_to_w32:
+ func_stripname : : "$1"
+ func_to_host_path_tmp1=$func_stripname_result
+ func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1"
+ func_to_host_path_result="$func_convert_core_path_wine_to_w32_result"
+ func_convert_path_check : ";" \
+ "$func_to_host_path_tmp1" "$func_to_host_path_result"
+ func_convert_path_front_back_pathsep ":*" "*:" ";" "$1"
+ fi
+}
+# end func_convert_path_nix_to_w32
+
+
+# func_convert_path_msys_to_cygwin ARG
+# Convert path ARG from MSYS to Cygwin format. Requires LT_CYGPATH set.
+# Returns result in func_to_host_file_result.
+func_convert_path_msys_to_cygwin ()
+{
+ $opt_debug
+ func_to_host_path_result="$1"
+ if test -n "$1"; then
+ # See func_convert_path_msys_to_w32:
+ func_stripname : : "$1"
+ func_to_host_path_tmp1=$func_stripname_result
+ func_convert_core_msys_to_w32 "$func_to_host_path_tmp1"
+ func_cygpath -u -p "$func_convert_core_msys_to_w32_result"
+ func_to_host_path_result="$func_cygpath_result"
+ func_convert_path_check : : \
+ "$func_to_host_path_tmp1" "$func_to_host_path_result"
+ func_convert_path_front_back_pathsep ":*" "*:" : "$1"
+ fi
+}
+# end func_convert_path_msys_to_cygwin
+
+
+# func_convert_path_nix_to_cygwin ARG
+# Convert path ARG from *nix to Cygwin format. Requires Cygwin installed in a
+# a wine environment, working winepath, and LT_CYGPATH set. Returns result in
+# func_to_host_file_result.
+func_convert_path_nix_to_cygwin ()
+{
+ $opt_debug
+ func_to_host_path_result="$1"
+ if test -n "$1"; then
+ # Remove leading and trailing path separator characters from
+ # ARG. msys behavior is inconsistent here, cygpath turns them
+ # into '.;' and ';.', and winepath ignores them completely.
+ func_stripname : : "$1"
+ func_to_host_path_tmp1=$func_stripname_result
+ func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1"
+ func_cygpath -u -p "$func_convert_core_path_wine_to_w32_result"
+ func_to_host_path_result="$func_cygpath_result"
+ func_convert_path_check : : \
+ "$func_to_host_path_tmp1" "$func_to_host_path_result"
+ func_convert_path_front_back_pathsep ":*" "*:" : "$1"
+ fi
+}
+# end func_convert_path_nix_to_cygwin
+
+
+# func_mode_compile arg...
+func_mode_compile ()
+{
+ $opt_debug
+ # Get the compilation command and the source file.
+ base_compile=
+ srcfile="$nonopt" # always keep a non-empty value in "srcfile"
+ suppress_opt=yes
+ suppress_output=
+ arg_mode=normal
+ libobj=
+ later=
+ pie_flag=
+
+ for arg
+ do
+ case $arg_mode in
+ arg )
+ # do not "continue". Instead, add this to base_compile
+ lastarg="$arg"
+ arg_mode=normal
+ ;;
+
+ target )
+ libobj="$arg"
+ arg_mode=normal
+ continue
+ ;;
+
+ normal )
+ # Accept any command-line options.
+ case $arg in
+ -o)
+ test -n "$libobj" && \
+ func_fatal_error "you cannot specify \`-o' more than once"
+ arg_mode=target
+ continue
+ ;;
+
+ -pie | -fpie | -fPIE)
+ func_append pie_flag " $arg"
+ continue
+ ;;
+
+ -shared | -static | -prefer-pic | -prefer-non-pic)
+ func_append later " $arg"
+ continue
+ ;;
+
+ -no-suppress)
+ suppress_opt=no
+ continue
+ ;;
+
+ -Xcompiler)
+ arg_mode=arg # the next one goes into the "base_compile" arg list
+ continue # The current "srcfile" will either be retained or
+ ;; # replaced later. I would guess that would be a bug.
+
+ -Wc,*)
+ func_stripname '-Wc,' '' "$arg"
+ args=$func_stripname_result
+ lastarg=
+ save_ifs="$IFS"; IFS=','
+ for arg in $args; do
+ IFS="$save_ifs"
+ func_append_quoted lastarg "$arg"
+ done
+ IFS="$save_ifs"
+ func_stripname ' ' '' "$lastarg"
+ lastarg=$func_stripname_result
+
+ # Add the arguments to base_compile.
+ func_append base_compile " $lastarg"
+ continue
+ ;;
+
+ *)
+ # Accept the current argument as the source file.
+ # The previous "srcfile" becomes the current argument.
+ #
+ lastarg="$srcfile"
+ srcfile="$arg"
+ ;;
+ esac # case $arg
+ ;;
+ esac # case $arg_mode
+
+ # Aesthetically quote the previous argument.
+ func_append_quoted base_compile "$lastarg"
+ done # for arg
+
+ case $arg_mode in
+ arg)
+ func_fatal_error "you must specify an argument for -Xcompile"
+ ;;
+ target)
+ func_fatal_error "you must specify a target with \`-o'"
+ ;;
+ *)
+ # Get the name of the library object.
+ test -z "$libobj" && {
+ func_basename "$srcfile"
+ libobj="$func_basename_result"
+ }
+ ;;
+ esac
+
+ # Recognize several different file suffixes.
+ # If the user specifies -o file.o, it is replaced with file.lo
+ case $libobj in
+ *.[cCFSifmso] | \
+ *.ada | *.adb | *.ads | *.asm | \
+ *.c++ | *.cc | *.ii | *.class | *.cpp | *.cxx | \
+ *.[fF][09]? | *.for | *.java | *.go | *.obj | *.sx | *.cu | *.cup)
+ func_xform "$libobj"
+ libobj=$func_xform_result
+ ;;
+ esac
+
+ case $libobj in
+ *.lo) func_lo2o "$libobj"; obj=$func_lo2o_result ;;
+ *)
+ func_fatal_error "cannot determine name of library object from \`$libobj'"
+ ;;
+ esac
+
+ func_infer_tag $base_compile
+
+ for arg in $later; do
+ case $arg in
+ -shared)
+ test "$build_libtool_libs" != yes && \
+ func_fatal_configuration "can not build a shared library"
+ build_old_libs=no
+ continue
+ ;;
+
+ -static)
+ build_libtool_libs=no
+ build_old_libs=yes
+ continue
+ ;;
+
+ -prefer-pic)
+ pic_mode=yes
+ continue
+ ;;
+
+ -prefer-non-pic)
+ pic_mode=no
+ continue
+ ;;
+ esac
+ done
+
+ func_quote_for_eval "$libobj"
+ test "X$libobj" != "X$func_quote_for_eval_result" \
+ && $ECHO "X$libobj" | $GREP '[]~#^*{};<>?"'"'"' &()|`$[]' \
+ && func_warning "libobj name \`$libobj' may not contain shell special characters."
+ func_dirname_and_basename "$obj" "/" ""
+ objname="$func_basename_result"
+ xdir="$func_dirname_result"
+ lobj=${xdir}$objdir/$objname
+
+ test -z "$base_compile" && \
+ func_fatal_help "you must specify a compilation command"
+
+ # Delete any leftover library objects.
+ if test "$build_old_libs" = yes; then
+ removelist="$obj $lobj $libobj ${libobj}T"
+ else
+ removelist="$lobj $libobj ${libobj}T"
+ fi
+
+ # On Cygwin there's no "real" PIC flag so we must build both object types
+ case $host_os in
+ cygwin* | mingw* | pw32* | os2* | cegcc*)
+ pic_mode=default
+ ;;
+ esac
+ if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then
+ # non-PIC code in shared libraries is not supported
+ pic_mode=default
+ fi
+
+ # Calculate the filename of the output object if compiler does
+ # not support -o with -c
+ if test "$compiler_c_o" = no; then
+ output_obj=`$ECHO "$srcfile" | $SED 's%^.*/%%; s%\.[^.]*$%%'`.${objext}
+ lockfile="$output_obj.lock"
+ else
+ output_obj=
+ need_locks=no
+ lockfile=
+ fi
+
+ # Lock this critical section if it is needed
+ # We use this script file to make the link, it avoids creating a new file
+ if test "$need_locks" = yes; then
+ until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do
+ func_echo "Waiting for $lockfile to be removed"
+ sleep 2
+ done
+ elif test "$need_locks" = warn; then
+ if test -f "$lockfile"; then
+ $ECHO "\
+*** ERROR, $lockfile exists and contains:
+`cat $lockfile 2>/dev/null`
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together. If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+ $opt_dry_run || $RM $removelist
+ exit $EXIT_FAILURE
+ fi
+ func_append removelist " $output_obj"
+ $ECHO "$srcfile" > "$lockfile"
+ fi
+
+ $opt_dry_run || $RM $removelist
+ func_append removelist " $lockfile"
+ trap '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' 1 2 15
+
+ func_to_tool_file "$srcfile" func_convert_file_msys_to_w32
+ srcfile=$func_to_tool_file_result
+ func_quote_for_eval "$srcfile"
+ qsrcfile=$func_quote_for_eval_result
+
+ # Only build a PIC object if we are building libtool libraries.
+ if test "$build_libtool_libs" = yes; then
+ # Without this assignment, base_compile gets emptied.
+ fbsd_hideous_sh_bug=$base_compile
+
+ if test "$pic_mode" != no; then
+ command="$base_compile $qsrcfile $pic_flag"
+ else
+ # Don't build PIC code
+ command="$base_compile $qsrcfile"
+ fi
+
+ func_mkdir_p "$xdir$objdir"
+
+ if test -z "$output_obj"; then
+ # Place PIC objects in $objdir
+ func_append command " -o $lobj"
+ fi
+
+ func_show_eval_locale "$command" \
+ 'test -n "$output_obj" && $RM $removelist; exit $EXIT_FAILURE'
+
+ if test "$need_locks" = warn &&
+ test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then
+ $ECHO "\
+*** ERROR, $lockfile contains:
+`cat $lockfile 2>/dev/null`
+
+but it should contain:
+$srcfile
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together. If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+ $opt_dry_run || $RM $removelist
+ exit $EXIT_FAILURE
+ fi
+
+ # Just move the object if needed, then go on to compile the next one
+ if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then
+ func_show_eval '$MV "$output_obj" "$lobj"' \
+ 'error=$?; $opt_dry_run || $RM $removelist; exit $error'
+ fi
+
+ # Allow error messages only from the first compilation.
+ if test "$suppress_opt" = yes; then
+ suppress_output=' >/dev/null 2>&1'
+ fi
+ fi
+
+ # Only build a position-dependent object if we build old libraries.
+ if test "$build_old_libs" = yes; then
+ if test "$pic_mode" != yes; then
+ # Don't build PIC code
+ command="$base_compile $qsrcfile$pie_flag"
+ else
+ command="$base_compile $qsrcfile $pic_flag"
+ fi
+ if test "$compiler_c_o" = yes; then
+ func_append command " -o $obj"
+ fi
+
+ # Suppress compiler output if we already did a PIC compilation.
+ func_append command "$suppress_output"
+ func_show_eval_locale "$command" \
+ '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE'
+
+ if test "$need_locks" = warn &&
+ test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then
+ $ECHO "\
+*** ERROR, $lockfile contains:
+`cat $lockfile 2>/dev/null`
+
+but it should contain:
+$srcfile
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together. If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+ $opt_dry_run || $RM $removelist
+ exit $EXIT_FAILURE
+ fi
+
+ # Just move the object if needed
+ if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then
+ func_show_eval '$MV "$output_obj" "$obj"' \
+ 'error=$?; $opt_dry_run || $RM $removelist; exit $error'
+ fi
+ fi
+
+ $opt_dry_run || {
+ func_write_libtool_object "$libobj" "$objdir/$objname" "$objname"
+
+ # Unlock the critical section if it was locked
+ if test "$need_locks" != no; then
+ removelist=$lockfile
+ $RM "$lockfile"
+ fi
+ }
+
+ exit $EXIT_SUCCESS
+}
+
+$opt_help || {
+ test "$opt_mode" = compile && func_mode_compile ${1+"$@"}
+}
+
+func_mode_help ()
+{
+ # We need to display help for each of the modes.
+ case $opt_mode in
+ "")
+ # Generic help is extracted from the usage comments
+ # at the start of this file.
+ func_help
+ ;;
+
+ clean)
+ $ECHO \
+"Usage: $progname [OPTION]... --mode=clean RM [RM-OPTION]... FILE...
+
+Remove files from the build directory.
+
+RM is the name of the program to use to delete files associated with each FILE
+(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed
+to RM.
+
+If FILE is a libtool library, object or program, all the files associated
+with it are deleted. Otherwise, only FILE itself is deleted using RM."
+ ;;
+
+ compile)
+ $ECHO \
+"Usage: $progname [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE
+
+Compile a source file into a libtool library object.
+
+This mode accepts the following additional options:
+
+ -o OUTPUT-FILE set the output file name to OUTPUT-FILE
+ -no-suppress do not suppress compiler output for multiple passes
+ -prefer-pic try to build PIC objects only
+ -prefer-non-pic try to build non-PIC objects only
+ -shared do not build a \`.o' file suitable for static linking
+ -static only build a \`.o' file suitable for static linking
+ -Wc,FLAG pass FLAG directly to the compiler
+
+COMPILE-COMMAND is a command to be used in creating a \`standard' object file
+from the given SOURCEFILE.
+
+The output file name is determined by removing the directory component from
+SOURCEFILE, then substituting the C source code suffix \`.c' with the
+library object suffix, \`.lo'."
+ ;;
+
+ execute)
+ $ECHO \
+"Usage: $progname [OPTION]... --mode=execute COMMAND [ARGS]...
+
+Automatically set library path, then run a program.
+
+This mode accepts the following additional options:
+
+ -dlopen FILE add the directory containing FILE to the library path
+
+This mode sets the library path environment variable according to \`-dlopen'
+flags.
+
+If any of the ARGS are libtool executable wrappers, then they are translated
+into their corresponding uninstalled binary, and any of their required library
+directories are added to the library path.
+
+Then, COMMAND is executed, with ARGS as arguments."
+ ;;
+
+ finish)
+ $ECHO \
+"Usage: $progname [OPTION]... --mode=finish [LIBDIR]...
+
+Complete the installation of libtool libraries.
+
+Each LIBDIR is a directory that contains libtool libraries.
+
+The commands that this mode executes may require superuser privileges. Use
+the \`--dry-run' option if you just want to see what would be executed."
+ ;;
+
+ install)
+ $ECHO \
+"Usage: $progname [OPTION]... --mode=install INSTALL-COMMAND...
+
+Install executables or libraries.
+
+INSTALL-COMMAND is the installation command. The first component should be
+either the \`install' or \`cp' program.
+
+The following components of INSTALL-COMMAND are treated specially:
+
+ -inst-prefix-dir PREFIX-DIR Use PREFIX-DIR as a staging area for installation
+
+The rest of the components are interpreted as arguments to that command (only
+BSD-compatible install options are recognized)."
+ ;;
+
+ link)
+ $ECHO \
+"Usage: $progname [OPTION]... --mode=link LINK-COMMAND...
+
+Link object files or libraries together to form another library, or to
+create an executable program.
+
+LINK-COMMAND is a command using the C compiler that you would use to create
+a program from several object files.
+
+The following components of LINK-COMMAND are treated specially:
+
+ -all-static do not do any dynamic linking at all
+ -avoid-version do not add a version suffix if possible
+ -bindir BINDIR specify path to binaries directory (for systems where
+ libraries must be found in the PATH setting at runtime)
+ -dlopen FILE \`-dlpreopen' FILE if it cannot be dlopened at runtime
+ -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols
+ -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3)
+ -export-symbols SYMFILE
+ try to export only the symbols listed in SYMFILE
+ -export-symbols-regex REGEX
+ try to export only the symbols matching REGEX
+ -LLIBDIR search LIBDIR for required installed libraries
+ -lNAME OUTPUT-FILE requires the installed library libNAME
+ -module build a library that can dlopened
+ -no-fast-install disable the fast-install mode
+ -no-install link a not-installable executable
+ -no-undefined declare that a library does not refer to external symbols
+ -o OUTPUT-FILE create OUTPUT-FILE from the specified objects
+ -objectlist FILE Use a list of object files found in FILE to specify objects
+ -precious-files-regex REGEX
+ don't remove output files matching REGEX
+ -release RELEASE specify package release information
+ -rpath LIBDIR the created library will eventually be installed in LIBDIR
+ -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries
+ -shared only do dynamic linking of libtool libraries
+ -shrext SUFFIX override the standard shared library file extension
+ -static do not do any dynamic linking of uninstalled libtool libraries
+ -static-libtool-libs
+ do not do any dynamic linking of libtool libraries
+ -version-info CURRENT[:REVISION[:AGE]]
+ specify library version info [each variable defaults to 0]
+ -weak LIBNAME declare that the target provides the LIBNAME interface
+ -Wc,FLAG
+ -Xcompiler FLAG pass linker-specific FLAG directly to the compiler
+ -Wl,FLAG
+ -Xlinker FLAG pass linker-specific FLAG directly to the linker
+ -XCClinker FLAG pass link-specific FLAG to the compiler driver (CC)
+
+All other options (arguments beginning with \`-') are ignored.
+
+Every other argument is treated as a filename. Files ending in \`.la' are
+treated as uninstalled libtool libraries, other files are standard or library
+object files.
+
+If the OUTPUT-FILE ends in \`.la', then a libtool library is created,
+only library objects (\`.lo' files) may be specified, and \`-rpath' is
+required, except when creating a convenience library.
+
+If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created
+using \`ar' and \`ranlib', or on Windows using \`lib'.
+
+If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file
+is created, otherwise an executable program is created."
+ ;;
+
+ uninstall)
+ $ECHO \
+"Usage: $progname [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE...
+
+Remove libraries from an installation directory.
+
+RM is the name of the program to use to delete files associated with each FILE
+(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed
+to RM.
+
+If FILE is a libtool library, all the files associated with it are deleted.
+Otherwise, only FILE itself is deleted using RM."
+ ;;
+
+ *)
+ func_fatal_help "invalid operation mode \`$opt_mode'"
+ ;;
+ esac
+
+ echo
+ $ECHO "Try \`$progname --help' for more information about other modes."
+}
+
+# Now that we've collected a possible --mode arg, show help if necessary
+if $opt_help; then
+ if test "$opt_help" = :; then
+ func_mode_help
+ else
+ {
+ func_help noexit
+ for opt_mode in compile link execute install finish uninstall clean; do
+ func_mode_help
+ done
+ } | sed -n '1p; 2,$s/^Usage:/ or: /p'
+ {
+ func_help noexit
+ for opt_mode in compile link execute install finish uninstall clean; do
+ echo
+ func_mode_help
+ done
+ } |
+ sed '1d
+ /^When reporting/,/^Report/{
+ H
+ d
+ }
+ $x
+ /information about other modes/d
+ /more detailed .*MODE/d
+ s/^Usage:.*--mode=\([^ ]*\) .*/Description of \1 mode:/'
+ fi
+ exit $?
+fi
+
+
+# func_mode_execute arg...
+func_mode_execute ()
+{
+ $opt_debug
+ # The first argument is the command name.
+ cmd="$nonopt"
+ test -z "$cmd" && \
+ func_fatal_help "you must specify a COMMAND"
+
+ # Handle -dlopen flags immediately.
+ for file in $opt_dlopen; do
+ test -f "$file" \
+ || func_fatal_help "\`$file' is not a file"
+
+ dir=
+ case $file in
+ *.la)
+ func_resolve_sysroot "$file"
+ file=$func_resolve_sysroot_result
+
+ # Check to see that this really is a libtool archive.
+ func_lalib_unsafe_p "$file" \
+ || func_fatal_help "\`$lib' is not a valid libtool archive"
+
+ # Read the libtool library.
+ dlname=
+ library_names=
+ func_source "$file"
+
+ # Skip this library if it cannot be dlopened.
+ if test -z "$dlname"; then
+ # Warn if it was a shared library.
+ test -n "$library_names" && \
+ func_warning "\`$file' was not linked with \`-export-dynamic'"
+ continue
+ fi
+
+ func_dirname "$file" "" "."
+ dir="$func_dirname_result"
+
+ if test -f "$dir/$objdir/$dlname"; then
+ func_append dir "/$objdir"
+ else
+ if test ! -f "$dir/$dlname"; then
+ func_fatal_error "cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'"
+ fi
+ fi
+ ;;
+
+ *.lo)
+ # Just add the directory containing the .lo file.
+ func_dirname "$file" "" "."
+ dir="$func_dirname_result"
+ ;;
+
+ *)
+ func_warning "\`-dlopen' is ignored for non-libtool libraries and objects"
+ continue
+ ;;
+ esac
+
+ # Get the absolute pathname.
+ absdir=`cd "$dir" && pwd`
+ test -n "$absdir" && dir="$absdir"
+
+ # Now add the directory to shlibpath_var.
+ if eval "test -z \"\$$shlibpath_var\""; then
+ eval "$shlibpath_var=\"\$dir\""
+ else
+ eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\""
+ fi
+ done
+
+ # This variable tells wrapper scripts just to set shlibpath_var
+ # rather than running their programs.
+ libtool_execute_magic="$magic"
+
+ # Check if any of the arguments is a wrapper script.
+ args=
+ for file
+ do
+ case $file in
+ -* | *.la | *.lo ) ;;
+ *)
+ # Do a test to see if this is really a libtool program.
+ if func_ltwrapper_script_p "$file"; then
+ func_source "$file"
+ # Transform arg to wrapped name.
+ file="$progdir/$program"
+ elif func_ltwrapper_executable_p "$file"; then
+ func_ltwrapper_scriptname "$file"
+ func_source "$func_ltwrapper_scriptname_result"
+ # Transform arg to wrapped name.
+ file="$progdir/$program"
+ fi
+ ;;
+ esac
+ # Quote arguments (to preserve shell metacharacters).
+ func_append_quoted args "$file"
+ done
+
+ if test "X$opt_dry_run" = Xfalse; then
+ if test -n "$shlibpath_var"; then
+ # Export the shlibpath_var.
+ eval "export $shlibpath_var"
+ fi
+
+ # Restore saved environment variables
+ for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES
+ do
+ eval "if test \"\${save_$lt_var+set}\" = set; then
+ $lt_var=\$save_$lt_var; export $lt_var
+ else
+ $lt_unset $lt_var
+ fi"
+ done
+
+ # Now prepare to actually exec the command.
+ exec_cmd="\$cmd$args"
+ else
+ # Display what would be done.
+ if test -n "$shlibpath_var"; then
+ eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\""
+ echo "export $shlibpath_var"
+ fi
+ $ECHO "$cmd$args"
+ exit $EXIT_SUCCESS
+ fi
+}
+
+test "$opt_mode" = execute && func_mode_execute ${1+"$@"}
+
+
+# func_mode_finish arg...
+func_mode_finish ()
+{
+ $opt_debug
+ libs=
+ libdirs=
+ admincmds=
+
+ for opt in "$nonopt" ${1+"$@"}
+ do
+ if test -d "$opt"; then
+ func_append libdirs " $opt"
+
+ elif test -f "$opt"; then
+ if func_lalib_unsafe_p "$opt"; then
+ func_append libs " $opt"
+ else
+ func_warning "\`$opt' is not a valid libtool archive"
+ fi
+
+ else
+ func_fatal_error "invalid argument \`$opt'"
+ fi
+ done
+
+ if test -n "$libs"; then
+ if test -n "$lt_sysroot"; then
+ sysroot_regex=`$ECHO "$lt_sysroot" | $SED "$sed_make_literal_regex"`
+ sysroot_cmd="s/\([ ']\)$sysroot_regex/\1/g;"
+ else
+ sysroot_cmd=
+ fi
+
+ # Remove sysroot references
+ if $opt_dry_run; then
+ for lib in $libs; do
+ echo "removing references to $lt_sysroot and \`=' prefixes from $lib"
+ done
+ else
+ tmpdir=`func_mktempdir`
+ for lib in $libs; do
+ sed -e "${sysroot_cmd} s/\([ ']-[LR]\)=/\1/g; s/\([ ']\)=/\1/g" $lib \
+ > $tmpdir/tmp-la
+ mv -f $tmpdir/tmp-la $lib
+ done
+ ${RM}r "$tmpdir"
+ fi
+ fi
+
+ if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then
+ for libdir in $libdirs; do
+ if test -n "$finish_cmds"; then
+ # Do each command in the finish commands.
+ func_execute_cmds "$finish_cmds" 'admincmds="$admincmds
+'"$cmd"'"'
+ fi
+ if test -n "$finish_eval"; then
+ # Do the single finish_eval.
+ eval cmds=\"$finish_eval\"
+ $opt_dry_run || eval "$cmds" || func_append admincmds "
+ $cmds"
+ fi
+ done
+ fi
+
+ # Exit here if they wanted silent mode.
+ $opt_silent && exit $EXIT_SUCCESS
+
+ if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then
+ echo "----------------------------------------------------------------------"
+ echo "Libraries have been installed in:"
+ for libdir in $libdirs; do
+ $ECHO " $libdir"
+ done
+ echo
+ echo "If you ever happen to want to link against installed libraries"
+ echo "in a given directory, LIBDIR, you must either use libtool, and"
+ echo "specify the full pathname of the library, or use the \`-LLIBDIR'"
+ echo "flag during linking and do at least one of the following:"
+ if test -n "$shlibpath_var"; then
+ echo " - add LIBDIR to the \`$shlibpath_var' environment variable"
+ echo " during execution"
+ fi
+ if test -n "$runpath_var"; then
+ echo " - add LIBDIR to the \`$runpath_var' environment variable"
+ echo " during linking"
+ fi
+ if test -n "$hardcode_libdir_flag_spec"; then
+ libdir=LIBDIR
+ eval flag=\"$hardcode_libdir_flag_spec\"
+
+ $ECHO " - use the \`$flag' linker flag"
+ fi
+ if test -n "$admincmds"; then
+ $ECHO " - have your system administrator run these commands:$admincmds"
+ fi
+ if test -f /etc/ld.so.conf; then
+ echo " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'"
+ fi
+ echo
+
+ echo "See any operating system documentation about shared libraries for"
+ case $host in
+ solaris2.[6789]|solaris2.1[0-9])
+ echo "more information, such as the ld(1), crle(1) and ld.so(8) manual"
+ echo "pages."
+ ;;
+ *)
+ echo "more information, such as the ld(1) and ld.so(8) manual pages."
+ ;;
+ esac
+ echo "----------------------------------------------------------------------"
+ fi
+ exit $EXIT_SUCCESS
+}
+
+test "$opt_mode" = finish && func_mode_finish ${1+"$@"}
+
+
+# func_mode_install arg...
+func_mode_install ()
+{
+ $opt_debug
+ # There may be an optional sh(1) argument at the beginning of
+ # install_prog (especially on Windows NT).
+ if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh ||
+ # Allow the use of GNU shtool's install command.
+ case $nonopt in *shtool*) :;; *) false;; esac; then
+ # Aesthetically quote it.
+ func_quote_for_eval "$nonopt"
+ install_prog="$func_quote_for_eval_result "
+ arg=$1
+ shift
+ else
+ install_prog=
+ arg=$nonopt
+ fi
+
+ # The real first argument should be the name of the installation program.
+ # Aesthetically quote it.
+ func_quote_for_eval "$arg"
+ func_append install_prog "$func_quote_for_eval_result"
+ install_shared_prog=$install_prog
+ case " $install_prog " in
+ *[\\\ /]cp\ *) install_cp=: ;;
+ *) install_cp=false ;;
+ esac
+
+ # We need to accept at least all the BSD install flags.
+ dest=
+ files=
+ opts=
+ prev=
+ install_type=
+ isdir=no
+ stripme=
+ no_mode=:
+ for arg
+ do
+ arg2=
+ if test -n "$dest"; then
+ func_append files " $dest"
+ dest=$arg
+ continue
+ fi
+
+ case $arg in
+ -d) isdir=yes ;;
+ -f)
+ if $install_cp; then :; else
+ prev=$arg
+ fi
+ ;;
+ -g | -m | -o)
+ prev=$arg
+ ;;
+ -s)
+ stripme=" -s"
+ continue
+ ;;
+ -*)
+ ;;
+ *)
+ # If the previous option needed an argument, then skip it.
+ if test -n "$prev"; then
+ if test "x$prev" = x-m && test -n "$install_override_mode"; then
+ arg2=$install_override_mode
+ no_mode=false
+ fi
+ prev=
+ else
+ dest=$arg
+ continue
+ fi
+ ;;
+ esac
+
+ # Aesthetically quote the argument.
+ func_quote_for_eval "$arg"
+ func_append install_prog " $func_quote_for_eval_result"
+ if test -n "$arg2"; then
+ func_quote_for_eval "$arg2"
+ fi
+ func_append install_shared_prog " $func_quote_for_eval_result"
+ done
+
+ test -z "$install_prog" && \
+ func_fatal_help "you must specify an install program"
+
+ test -n "$prev" && \
+ func_fatal_help "the \`$prev' option requires an argument"
+
+ if test -n "$install_override_mode" && $no_mode; then
+ if $install_cp; then :; else
+ func_quote_for_eval "$install_override_mode"
+ func_append install_shared_prog " -m $func_quote_for_eval_result"
+ fi
+ fi
+
+ if test -z "$files"; then
+ if test -z "$dest"; then
+ func_fatal_help "no file or destination specified"
+ else
+ func_fatal_help "you must specify a destination"
+ fi
+ fi
+
+ # Strip any trailing slash from the destination.
+ func_stripname '' '/' "$dest"
+ dest=$func_stripname_result
+
+ # Check to see that the destination is a directory.
+ test -d "$dest" && isdir=yes
+ if test "$isdir" = yes; then
+ destdir="$dest"
+ destname=
+ else
+ func_dirname_and_basename "$dest" "" "."
+ destdir="$func_dirname_result"
+ destname="$func_basename_result"
+
+ # Not a directory, so check to see that there is only one file specified.
+ set dummy $files; shift
+ test "$#" -gt 1 && \
+ func_fatal_help "\`$dest' is not a directory"
+ fi
+ case $destdir in
+ [\\/]* | [A-Za-z]:[\\/]*) ;;
+ *)
+ for file in $files; do
+ case $file in
+ *.lo) ;;
+ *)
+ func_fatal_help "\`$destdir' must be an absolute directory name"
+ ;;
+ esac
+ done
+ ;;
+ esac
+
+ # This variable tells wrapper scripts just to set variables rather
+ # than running their programs.
+ libtool_install_magic="$magic"
+
+ staticlibs=
+ future_libdirs=
+ current_libdirs=
+ for file in $files; do
+
+ # Do each installation.
+ case $file in
+ *.$libext)
+ # Do the static libraries later.
+ func_append staticlibs " $file"
+ ;;
+
+ *.la)
+ func_resolve_sysroot "$file"
+ file=$func_resolve_sysroot_result
+
+ # Check to see that this really is a libtool archive.
+ func_lalib_unsafe_p "$file" \
+ || func_fatal_help "\`$file' is not a valid libtool archive"
+
+ library_names=
+ old_library=
+ relink_command=
+ func_source "$file"
+
+ # Add the libdir to current_libdirs if it is the destination.
+ if test "X$destdir" = "X$libdir"; then
+ case "$current_libdirs " in
+ *" $libdir "*) ;;
+ *) func_append current_libdirs " $libdir" ;;
+ esac
+ else
+ # Note the libdir as a future libdir.
+ case "$future_libdirs " in
+ *" $libdir "*) ;;
+ *) func_append future_libdirs " $libdir" ;;
+ esac
+ fi
+
+ func_dirname "$file" "/" ""
+ dir="$func_dirname_result"
+ func_append dir "$objdir"
+
+ if test -n "$relink_command"; then
+ # Determine the prefix the user has applied to our future dir.
+ inst_prefix_dir=`$ECHO "$destdir" | $SED -e "s%$libdir\$%%"`
+
+ # Don't allow the user to place us outside of our expected
+ # location b/c this prevents finding dependent libraries that
+ # are installed to the same prefix.
+ # At present, this check doesn't affect windows .dll's that
+ # are installed into $libdir/../bin (currently, that works fine)
+ # but it's something to keep an eye on.
+ test "$inst_prefix_dir" = "$destdir" && \
+ func_fatal_error "error: cannot install \`$file' to a directory not ending in $libdir"
+
+ if test -n "$inst_prefix_dir"; then
+ # Stick the inst_prefix_dir data into the link command.
+ relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"`
+ else
+ relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%%"`
+ fi
+
+ func_warning "relinking \`$file'"
+ func_show_eval "$relink_command" \
+ 'func_fatal_error "error: relink \`$file'\'' with the above command before installing it"'
+ fi
+
+ # See the names of the shared library.
+ set dummy $library_names; shift
+ if test -n "$1"; then
+ realname="$1"
+ shift
+
+ srcname="$realname"
+ test -n "$relink_command" && srcname="$realname"T
+
+ # Install the shared library and build the symlinks.
+ func_show_eval "$install_shared_prog $dir/$srcname $destdir/$realname" \
+ 'exit $?'
+ tstripme="$stripme"
+ case $host_os in
+ cygwin* | mingw* | pw32* | cegcc*)
+ case $realname in
+ *.dll.a)
+ tstripme=""
+ ;;
+ esac
+ ;;
+ esac
+ if test -n "$tstripme" && test -n "$striplib"; then
+ func_show_eval "$striplib $destdir/$realname" 'exit $?'
+ fi
+
+ if test "$#" -gt 0; then
+ # Delete the old symlinks, and create new ones.
+ # Try `ln -sf' first, because the `ln' binary might depend on
+ # the symlink we replace! Solaris /bin/ln does not understand -f,
+ # so we also need to try rm && ln -s.
+ for linkname
+ do
+ test "$linkname" != "$realname" \
+ && func_show_eval "(cd $destdir && { $LN_S -f $realname $linkname || { $RM $linkname && $LN_S $realname $linkname; }; })"
+ done
+ fi
+
+ # Do each command in the postinstall commands.
+ lib="$destdir/$realname"
+ func_execute_cmds "$postinstall_cmds" 'exit $?'
+ fi
+
+ # Install the pseudo-library for information purposes.
+ func_basename "$file"
+ name="$func_basename_result"
+ instname="$dir/$name"i
+ func_show_eval "$install_prog $instname $destdir/$name" 'exit $?'
+
+ # Maybe install the static library, too.
+ test -n "$old_library" && func_append staticlibs " $dir/$old_library"
+ ;;
+
+ *.lo)
+ # Install (i.e. copy) a libtool object.
+
+ # Figure out destination file name, if it wasn't already specified.
+ if test -n "$destname"; then
+ destfile="$destdir/$destname"
+ else
+ func_basename "$file"
+ destfile="$func_basename_result"
+ destfile="$destdir/$destfile"
+ fi
+
+ # Deduce the name of the destination old-style object file.
+ case $destfile in
+ *.lo)
+ func_lo2o "$destfile"
+ staticdest=$func_lo2o_result
+ ;;
+ *.$objext)
+ staticdest="$destfile"
+ destfile=
+ ;;
+ *)
+ func_fatal_help "cannot copy a libtool object to \`$destfile'"
+ ;;
+ esac
+
+ # Install the libtool object if requested.
+ test -n "$destfile" && \
+ func_show_eval "$install_prog $file $destfile" 'exit $?'
+
+ # Install the old object if enabled.
+ if test "$build_old_libs" = yes; then
+ # Deduce the name of the old-style object file.
+ func_lo2o "$file"
+ staticobj=$func_lo2o_result
+ func_show_eval "$install_prog \$staticobj \$staticdest" 'exit $?'
+ fi
+ exit $EXIT_SUCCESS
+ ;;
+
+ *)
+ # Figure out destination file name, if it wasn't already specified.
+ if test -n "$destname"; then
+ destfile="$destdir/$destname"
+ else
+ func_basename "$file"
+ destfile="$func_basename_result"
+ destfile="$destdir/$destfile"
+ fi
+
+ # If the file is missing, and there is a .exe on the end, strip it
+ # because it is most likely a libtool script we actually want to
+ # install
+ stripped_ext=""
+ case $file in
+ *.exe)
+ if test ! -f "$file"; then
+ func_stripname '' '.exe' "$file"
+ file=$func_stripname_result
+ stripped_ext=".exe"
+ fi
+ ;;
+ esac
+
+ # Do a test to see if this is really a libtool program.
+ case $host in
+ *cygwin* | *mingw*)
+ if func_ltwrapper_executable_p "$file"; then
+ func_ltwrapper_scriptname "$file"
+ wrapper=$func_ltwrapper_scriptname_result
+ else
+ func_stripname '' '.exe' "$file"
+ wrapper=$func_stripname_result
+ fi
+ ;;
+ *)
+ wrapper=$file
+ ;;
+ esac
+ if func_ltwrapper_script_p "$wrapper"; then
+ notinst_deplibs=
+ relink_command=
+
+ func_source "$wrapper"
+
+ # Check the variables that should have been set.
+ test -z "$generated_by_libtool_version" && \
+ func_fatal_error "invalid libtool wrapper script \`$wrapper'"
+
+ finalize=yes
+ for lib in $notinst_deplibs; do
+ # Check to see that each library is installed.
+ libdir=
+ if test -f "$lib"; then
+ func_source "$lib"
+ fi
+ libfile="$libdir/"`$ECHO "$lib" | $SED 's%^.*/%%g'` ### testsuite: skip nested quoting test
+ if test -n "$libdir" && test ! -f "$libfile"; then
+ func_warning "\`$lib' has not been installed in \`$libdir'"
+ finalize=no
+ fi
+ done
+
+ relink_command=
+ func_source "$wrapper"
+
+ outputname=
+ if test "$fast_install" = no && test -n "$relink_command"; then
+ $opt_dry_run || {
+ if test "$finalize" = yes; then
+ tmpdir=`func_mktempdir`
+ func_basename "$file$stripped_ext"
+ file="$func_basename_result"
+ outputname="$tmpdir/$file"
+ # Replace the output file specification.
+ relink_command=`$ECHO "$relink_command" | $SED 's%@OUTPUT@%'"$outputname"'%g'`
+
+ $opt_silent || {
+ func_quote_for_expand "$relink_command"
+ eval "func_echo $func_quote_for_expand_result"
+ }
+ if eval "$relink_command"; then :
+ else
+ func_error "error: relink \`$file' with the above command before installing it"
+ $opt_dry_run || ${RM}r "$tmpdir"
+ continue
+ fi
+ file="$outputname"
+ else
+ func_warning "cannot relink \`$file'"
+ fi
+ }
+ else
+ # Install the binary that we compiled earlier.
+ file=`$ECHO "$file$stripped_ext" | $SED "s%\([^/]*\)$%$objdir/\1%"`
+ fi
+ fi
+
+ # remove .exe since cygwin /usr/bin/install will append another
+ # one anyway
+ case $install_prog,$host in
+ */usr/bin/install*,*cygwin*)
+ case $file:$destfile in
+ *.exe:*.exe)
+ # this is ok
+ ;;
+ *.exe:*)
+ destfile=$destfile.exe
+ ;;
+ *:*.exe)
+ func_stripname '' '.exe' "$destfile"
+ destfile=$func_stripname_result
+ ;;
+ esac
+ ;;
+ esac
+ func_show_eval "$install_prog\$stripme \$file \$destfile" 'exit $?'
+ $opt_dry_run || if test -n "$outputname"; then
+ ${RM}r "$tmpdir"
+ fi
+ ;;
+ esac
+ done
+
+ for file in $staticlibs; do
+ func_basename "$file"
+ name="$func_basename_result"
+
+ # Set up the ranlib parameters.
+ oldlib="$destdir/$name"
+ func_to_tool_file "$oldlib" func_convert_file_msys_to_w32
+ tool_oldlib=$func_to_tool_file_result
+
+ func_show_eval "$install_prog \$file \$oldlib" 'exit $?'
+
+ if test -n "$stripme" && test -n "$old_striplib"; then
+ func_show_eval "$old_striplib $tool_oldlib" 'exit $?'
+ fi
+
+ # Do each command in the postinstall commands.
+ func_execute_cmds "$old_postinstall_cmds" 'exit $?'
+ done
+
+ test -n "$future_libdirs" && \
+ func_warning "remember to run \`$progname --finish$future_libdirs'"
+
+ if test -n "$current_libdirs"; then
+ # Maybe just do a dry run.
+ $opt_dry_run && current_libdirs=" -n$current_libdirs"
+ exec_cmd='$SHELL $progpath $preserve_args --finish$current_libdirs'
+ else
+ exit $EXIT_SUCCESS
+ fi
+}
+
+test "$opt_mode" = install && func_mode_install ${1+"$@"}
+
+
+# func_generate_dlsyms outputname originator pic_p
+# Extract symbols from dlprefiles and create ${outputname}S.o with
+# a dlpreopen symbol table.
+func_generate_dlsyms ()
+{
+ $opt_debug
+ my_outputname="$1"
+ my_originator="$2"
+ my_pic_p="${3-no}"
+ my_prefix=`$ECHO "$my_originator" | sed 's%[^a-zA-Z0-9]%_%g'`
+ my_dlsyms=
+
+ if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+ if test -n "$NM" && test -n "$global_symbol_pipe"; then
+ my_dlsyms="${my_outputname}S.c"
+ else
+ func_error "not configured to extract global symbols from dlpreopened files"
+ fi
+ fi
+
+ if test -n "$my_dlsyms"; then
+ case $my_dlsyms in
+ "") ;;
+ *.c)
+ # Discover the nlist of each of the dlfiles.
+ nlist="$output_objdir/${my_outputname}.nm"
+
+ func_show_eval "$RM $nlist ${nlist}S ${nlist}T"
+
+ # Parse the name list into a source file.
+ func_verbose "creating $output_objdir/$my_dlsyms"
+
+ $opt_dry_run || $ECHO > "$output_objdir/$my_dlsyms" "\
+/* $my_dlsyms - symbol resolution table for \`$my_outputname' dlsym emulation. */
+/* Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION */
+
+#ifdef __cplusplus
+extern \"C\" {
+#endif
+
+#if defined(__GNUC__) && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 4))
+#pragma GCC diagnostic ignored \"-Wstrict-prototypes\"
+#endif
+
+/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */
+#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE)
+/* DATA imports from DLLs on WIN32 con't be const, because runtime
+ relocations are performed -- see ld's documentation on pseudo-relocs. */
+# define LT_DLSYM_CONST
+#elif defined(__osf__)
+/* This system does not cope well with relocations in const data. */
+# define LT_DLSYM_CONST
+#else
+# define LT_DLSYM_CONST const
+#endif
+
+/* External symbol declarations for the compiler. */\
+"
+
+ if test "$dlself" = yes; then
+ func_verbose "generating symbol list for \`$output'"
+
+ $opt_dry_run || echo ': @PROGRAM@ ' > "$nlist"
+
+ # Add our own program objects to the symbol list.
+ progfiles=`$ECHO "$objs$old_deplibs" | $SP2NL | $SED "$lo2o" | $NL2SP`
+ for progfile in $progfiles; do
+ func_to_tool_file "$progfile" func_convert_file_msys_to_w32
+ func_verbose "extracting global C symbols from \`$func_to_tool_file_result'"
+ $opt_dry_run || eval "$NM $func_to_tool_file_result | $global_symbol_pipe >> '$nlist'"
+ done
+
+ if test -n "$exclude_expsyms"; then
+ $opt_dry_run || {
+ eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T'
+ eval '$MV "$nlist"T "$nlist"'
+ }
+ fi
+
+ if test -n "$export_symbols_regex"; then
+ $opt_dry_run || {
+ eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T'
+ eval '$MV "$nlist"T "$nlist"'
+ }
+ fi
+
+ # Prepare the list of exported symbols
+ if test -z "$export_symbols"; then
+ export_symbols="$output_objdir/$outputname.exp"
+ $opt_dry_run || {
+ $RM $export_symbols
+ eval "${SED} -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"'
+ case $host in
+ *cygwin* | *mingw* | *cegcc* )
+ eval "echo EXPORTS "'> "$output_objdir/$outputname.def"'
+ eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"'
+ ;;
+ esac
+ }
+ else
+ $opt_dry_run || {
+ eval "${SED} -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"'
+ eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T'
+ eval '$MV "$nlist"T "$nlist"'
+ case $host in
+ *cygwin* | *mingw* | *cegcc* )
+ eval "echo EXPORTS "'> "$output_objdir/$outputname.def"'
+ eval 'cat "$nlist" >> "$output_objdir/$outputname.def"'
+ ;;
+ esac
+ }
+ fi
+ fi
+
+ for dlprefile in $dlprefiles; do
+ func_verbose "extracting global C symbols from \`$dlprefile'"
+ func_basename "$dlprefile"
+ name="$func_basename_result"
+ case $host in
+ *cygwin* | *mingw* | *cegcc* )
+ # if an import library, we need to obtain dlname
+ if func_win32_import_lib_p "$dlprefile"; then
+ func_tr_sh "$dlprefile"
+ eval "curr_lafile=\$libfile_$func_tr_sh_result"
+ dlprefile_dlbasename=""
+ if test -n "$curr_lafile" && func_lalib_p "$curr_lafile"; then
+ # Use subshell, to avoid clobbering current variable values
+ dlprefile_dlname=`source "$curr_lafile" && echo "$dlname"`
+ if test -n "$dlprefile_dlname" ; then
+ func_basename "$dlprefile_dlname"
+ dlprefile_dlbasename="$func_basename_result"
+ else
+ # no lafile. user explicitly requested -dlpreopen <import library>.
+ $sharedlib_from_linklib_cmd "$dlprefile"
+ dlprefile_dlbasename=$sharedlib_from_linklib_result
+ fi
+ fi
+ $opt_dry_run || {
+ if test -n "$dlprefile_dlbasename" ; then
+ eval '$ECHO ": $dlprefile_dlbasename" >> "$nlist"'
+ else
+ func_warning "Could not compute DLL name from $name"
+ eval '$ECHO ": $name " >> "$nlist"'
+ fi
+ func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32
+ eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe |
+ $SED -e '/I __imp/d' -e 's/I __nm_/D /;s/_nm__//' >> '$nlist'"
+ }
+ else # not an import lib
+ $opt_dry_run || {
+ eval '$ECHO ": $name " >> "$nlist"'
+ func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32
+ eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'"
+ }
+ fi
+ ;;
+ *)
+ $opt_dry_run || {
+ eval '$ECHO ": $name " >> "$nlist"'
+ func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32
+ eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'"
+ }
+ ;;
+ esac
+ done
+
+ $opt_dry_run || {
+ # Make sure we have at least an empty file.
+ test -f "$nlist" || : > "$nlist"
+
+ if test -n "$exclude_expsyms"; then
+ $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T
+ $MV "$nlist"T "$nlist"
+ fi
+
+ # Try sorting and uniquifying the output.
+ if $GREP -v "^: " < "$nlist" |
+ if sort -k 3 </dev/null >/dev/null 2>&1; then
+ sort -k 3
+ else
+ sort +2
+ fi |
+ uniq > "$nlist"S; then
+ :
+ else
+ $GREP -v "^: " < "$nlist" > "$nlist"S
+ fi
+
+ if test -f "$nlist"S; then
+ eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$my_dlsyms"'
+ else
+ echo '/* NONE */' >> "$output_objdir/$my_dlsyms"
+ fi
+
+ echo >> "$output_objdir/$my_dlsyms" "\
+
+/* The mapping between symbol names and symbols. */
+typedef struct {
+ const char *name;
+ void *address;
+} lt_dlsymlist;
+extern LT_DLSYM_CONST lt_dlsymlist
+lt_${my_prefix}_LTX_preloaded_symbols[];
+LT_DLSYM_CONST lt_dlsymlist
+lt_${my_prefix}_LTX_preloaded_symbols[] =
+{\
+ { \"$my_originator\", (void *) 0 },"
+
+ case $need_lib_prefix in
+ no)
+ eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$my_dlsyms"
+ ;;
+ *)
+ eval "$global_symbol_to_c_name_address_lib_prefix" < "$nlist" >> "$output_objdir/$my_dlsyms"
+ ;;
+ esac
+ echo >> "$output_objdir/$my_dlsyms" "\
+ {0, (void *) 0}
+};
+
+/* This works around a problem in FreeBSD linker */
+#ifdef FREEBSD_WORKAROUND
+static const void *lt_preloaded_setup() {
+ return lt_${my_prefix}_LTX_preloaded_symbols;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif\
+"
+ } # !$opt_dry_run
+
+ pic_flag_for_symtable=
+ case "$compile_command " in
+ *" -static "*) ;;
+ *)
+ case $host in
+ # compiling the symbol table file with pic_flag works around
+ # a FreeBSD bug that causes programs to crash when -lm is
+ # linked before any other PIC object. But we must not use
+ # pic_flag when linking with -static. The problem exists in
+ # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1.
+ *-*-freebsd2.*|*-*-freebsd3.0*|*-*-freebsdelf3.0*)
+ pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND" ;;
+ *-*-hpux*)
+ pic_flag_for_symtable=" $pic_flag" ;;
+ *)
+ if test "X$my_pic_p" != Xno; then
+ pic_flag_for_symtable=" $pic_flag"
+ fi
+ ;;
+ esac
+ ;;
+ esac
+ symtab_cflags=
+ for arg in $LTCFLAGS; do
+ case $arg in
+ -pie | -fpie | -fPIE) ;;
+ *) func_append symtab_cflags " $arg" ;;
+ esac
+ done
+
+ # Now compile the dynamic symbol file.
+ func_show_eval '(cd $output_objdir && $LTCC$symtab_cflags -c$no_builtin_flag$pic_flag_for_symtable "$my_dlsyms")' 'exit $?'
+
+ # Clean up the generated files.
+ func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T"'
+
+ # Transform the symbol file into the correct name.
+ symfileobj="$output_objdir/${my_outputname}S.$objext"
+ case $host in
+ *cygwin* | *mingw* | *cegcc* )
+ if test -f "$output_objdir/$my_outputname.def"; then
+ compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"`
+ finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"`
+ else
+ compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"`
+ finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"`
+ fi
+ ;;
+ *)
+ compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"`
+ finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"`
+ ;;
+ esac
+ ;;
+ *)
+ func_fatal_error "unknown suffix for \`$my_dlsyms'"
+ ;;
+ esac
+ else
+ # We keep going just in case the user didn't refer to
+ # lt_preloaded_symbols. The linker will fail if global_symbol_pipe
+ # really was required.
+
+ # Nullify the symbol file.
+ compile_command=`$ECHO "$compile_command" | $SED "s% @SYMFILE@%%"`
+ finalize_command=`$ECHO "$finalize_command" | $SED "s% @SYMFILE@%%"`
+ fi
+}
+
+# func_win32_libid arg
+# return the library type of file 'arg'
+#
+# Need a lot of goo to handle *both* DLLs and import libs
+# Has to be a shell function in order to 'eat' the argument
+# that is supplied when $file_magic_command is called.
+# Despite the name, also deal with 64 bit binaries.
+func_win32_libid ()
+{
+ $opt_debug
+ win32_libid_type="unknown"
+ win32_fileres=`file -L $1 2>/dev/null`
+ case $win32_fileres in
+ *ar\ archive\ import\ library*) # definitely import
+ win32_libid_type="x86 archive import"
+ ;;
+ *ar\ archive*) # could be an import, or static
+ # Keep the egrep pattern in sync with the one in _LT_CHECK_MAGIC_METHOD.
+ if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null |
+ $EGREP 'file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' >/dev/null; then
+ func_to_tool_file "$1" func_convert_file_msys_to_w32
+ win32_nmres=`eval $NM -f posix -A \"$func_to_tool_file_result\" |
+ $SED -n -e '
+ 1,100{
+ / I /{
+ s,.*,import,
+ p
+ q
+ }
+ }'`
+ case $win32_nmres in
+ import*) win32_libid_type="x86 archive import";;
+ *) win32_libid_type="x86 archive static";;
+ esac
+ fi
+ ;;
+ *DLL*)
+ win32_libid_type="x86 DLL"
+ ;;
+ *executable*) # but shell scripts are "executable" too...
+ case $win32_fileres in
+ *MS\ Windows\ PE\ Intel*)
+ win32_libid_type="x86 DLL"
+ ;;
+ esac
+ ;;
+ esac
+ $ECHO "$win32_libid_type"
+}
+
+# func_cygming_dll_for_implib ARG
+#
+# Platform-specific function to extract the
+# name of the DLL associated with the specified
+# import library ARG.
+# Invoked by eval'ing the libtool variable
+# $sharedlib_from_linklib_cmd
+# Result is available in the variable
+# $sharedlib_from_linklib_result
+func_cygming_dll_for_implib ()
+{
+ $opt_debug
+ sharedlib_from_linklib_result=`$DLLTOOL --identify-strict --identify "$1"`
+}
+
+# func_cygming_dll_for_implib_fallback_core SECTION_NAME LIBNAMEs
+#
+# The is the core of a fallback implementation of a
+# platform-specific function to extract the name of the
+# DLL associated with the specified import library LIBNAME.
+#
+# SECTION_NAME is either .idata$6 or .idata$7, depending
+# on the platform and compiler that created the implib.
+#
+# Echos the name of the DLL associated with the
+# specified import library.
+func_cygming_dll_for_implib_fallback_core ()
+{
+ $opt_debug
+ match_literal=`$ECHO "$1" | $SED "$sed_make_literal_regex"`
+ $OBJDUMP -s --section "$1" "$2" 2>/dev/null |
+ $SED '/^Contents of section '"$match_literal"':/{
+ # Place marker at beginning of archive member dllname section
+ s/.*/====MARK====/
+ p
+ d
+ }
+ # These lines can sometimes be longer than 43 characters, but
+ # are always uninteresting
+ /:[ ]*file format pe[i]\{,1\}-/d
+ /^In archive [^:]*:/d
+ # Ensure marker is printed
+ /^====MARK====/p
+ # Remove all lines with less than 43 characters
+ /^.\{43\}/!d
+ # From remaining lines, remove first 43 characters
+ s/^.\{43\}//' |
+ $SED -n '
+ # Join marker and all lines until next marker into a single line
+ /^====MARK====/ b para
+ H
+ $ b para
+ b
+ :para
+ x
+ s/\n//g
+ # Remove the marker
+ s/^====MARK====//
+ # Remove trailing dots and whitespace
+ s/[\. \t]*$//
+ # Print
+ /./p' |
+ # we now have a list, one entry per line, of the stringified
+ # contents of the appropriate section of all members of the
+ # archive which possess that section. Heuristic: eliminate
+ # all those which have a first or second character that is
+ # a '.' (that is, objdump's representation of an unprintable
+ # character.) This should work for all archives with less than
+ # 0x302f exports -- but will fail for DLLs whose name actually
+ # begins with a literal '.' or a single character followed by
+ # a '.'.
+ #
+ # Of those that remain, print the first one.
+ $SED -e '/^\./d;/^.\./d;q'
+}
+
+# func_cygming_gnu_implib_p ARG
+# This predicate returns with zero status (TRUE) if
+# ARG is a GNU/binutils-style import library. Returns
+# with nonzero status (FALSE) otherwise.
+func_cygming_gnu_implib_p ()
+{
+ $opt_debug
+ func_to_tool_file "$1" func_convert_file_msys_to_w32
+ func_cygming_gnu_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $EGREP ' (_head_[A-Za-z0-9_]+_[ad]l*|[A-Za-z0-9_]+_[ad]l*_iname)$'`
+ test -n "$func_cygming_gnu_implib_tmp"
+}
+
+# func_cygming_ms_implib_p ARG
+# This predicate returns with zero status (TRUE) if
+# ARG is an MS-style import library. Returns
+# with nonzero status (FALSE) otherwise.
+func_cygming_ms_implib_p ()
+{
+ $opt_debug
+ func_to_tool_file "$1" func_convert_file_msys_to_w32
+ func_cygming_ms_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $GREP '_NULL_IMPORT_DESCRIPTOR'`
+ test -n "$func_cygming_ms_implib_tmp"
+}
+
+# func_cygming_dll_for_implib_fallback ARG
+# Platform-specific function to extract the
+# name of the DLL associated with the specified
+# import library ARG.
+#
+# This fallback implementation is for use when $DLLTOOL
+# does not support the --identify-strict option.
+# Invoked by eval'ing the libtool variable
+# $sharedlib_from_linklib_cmd
+# Result is available in the variable
+# $sharedlib_from_linklib_result
+func_cygming_dll_for_implib_fallback ()
+{
+ $opt_debug
+ if func_cygming_gnu_implib_p "$1" ; then
+ # binutils import library
+ sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$7' "$1"`
+ elif func_cygming_ms_implib_p "$1" ; then
+ # ms-generated import library
+ sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$6' "$1"`
+ else
+ # unknown
+ sharedlib_from_linklib_result=""
+ fi
+}
+
+
+# func_extract_an_archive dir oldlib
+func_extract_an_archive ()
+{
+ $opt_debug
+ f_ex_an_ar_dir="$1"; shift
+ f_ex_an_ar_oldlib="$1"
+ if test "$lock_old_archive_extraction" = yes; then
+ lockfile=$f_ex_an_ar_oldlib.lock
+ until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do
+ func_echo "Waiting for $lockfile to be removed"
+ sleep 2
+ done
+ fi
+ func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" \
+ 'stat=$?; rm -f "$lockfile"; exit $stat'
+ if test "$lock_old_archive_extraction" = yes; then
+ $opt_dry_run || rm -f "$lockfile"
+ fi
+ if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then
+ :
+ else
+ func_fatal_error "object name conflicts in archive: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib"
+ fi
+}
+
+
+# func_extract_archives gentop oldlib ...
+func_extract_archives ()
+{
+ $opt_debug
+ my_gentop="$1"; shift
+ my_oldlibs=${1+"$@"}
+ my_oldobjs=""
+ my_xlib=""
+ my_xabs=""
+ my_xdir=""
+
+ for my_xlib in $my_oldlibs; do
+ # Extract the objects.
+ case $my_xlib in
+ [\\/]* | [A-Za-z]:[\\/]*) my_xabs="$my_xlib" ;;
+ *) my_xabs=`pwd`"/$my_xlib" ;;
+ esac
+ func_basename "$my_xlib"
+ my_xlib="$func_basename_result"
+ my_xlib_u=$my_xlib
+ while :; do
+ case " $extracted_archives " in
+ *" $my_xlib_u "*)
+ func_arith $extracted_serial + 1
+ extracted_serial=$func_arith_result
+ my_xlib_u=lt$extracted_serial-$my_xlib ;;
+ *) break ;;
+ esac
+ done
+ extracted_archives="$extracted_archives $my_xlib_u"
+ my_xdir="$my_gentop/$my_xlib_u"
+
+ func_mkdir_p "$my_xdir"
+
+ case $host in
+ *-darwin*)
+ func_verbose "Extracting $my_xabs"
+ # Do not bother doing anything if just a dry run
+ $opt_dry_run || {
+ darwin_orig_dir=`pwd`
+ cd $my_xdir || exit $?
+ darwin_archive=$my_xabs
+ darwin_curdir=`pwd`
+ darwin_base_archive=`basename "$darwin_archive"`
+ darwin_arches=`$LIPO -info "$darwin_archive" 2>/dev/null | $GREP Architectures 2>/dev/null || true`
+ if test -n "$darwin_arches"; then
+ darwin_arches=`$ECHO "$darwin_arches" | $SED -e 's/.*are://'`
+ darwin_arch=
+ func_verbose "$darwin_base_archive has multiple architectures $darwin_arches"
+ for darwin_arch in $darwin_arches ; do
+ func_mkdir_p "unfat-$$/${darwin_base_archive}-${darwin_arch}"
+ $LIPO -thin $darwin_arch -output "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" "${darwin_archive}"
+ cd "unfat-$$/${darwin_base_archive}-${darwin_arch}"
+ func_extract_an_archive "`pwd`" "${darwin_base_archive}"
+ cd "$darwin_curdir"
+ $RM "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}"
+ done # $darwin_arches
+ ## Okay now we've a bunch of thin objects, gotta fatten them up :)
+ darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$basename" | sort -u`
+ darwin_file=
+ darwin_files=
+ for darwin_file in $darwin_filelist; do
+ darwin_files=`find unfat-$$ -name $darwin_file -print | sort | $NL2SP`
+ $LIPO -create -output "$darwin_file" $darwin_files
+ done # $darwin_filelist
+ $RM -rf unfat-$$
+ cd "$darwin_orig_dir"
+ else
+ cd $darwin_orig_dir
+ func_extract_an_archive "$my_xdir" "$my_xabs"
+ fi # $darwin_arches
+ } # !$opt_dry_run
+ ;;
+ *)
+ func_extract_an_archive "$my_xdir" "$my_xabs"
+ ;;
+ esac
+ my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | sort | $NL2SP`
+ done
+
+ func_extract_archives_result="$my_oldobjs"
+}
+
+
+# func_emit_wrapper [arg=no]
+#
+# Emit a libtool wrapper script on stdout.
+# Don't directly open a file because we may want to
+# incorporate the script contents within a cygwin/mingw
+# wrapper executable. Must ONLY be called from within
+# func_mode_link because it depends on a number of variables
+# set therein.
+#
+# ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR
+# variable will take. If 'yes', then the emitted script
+# will assume that the directory in which it is stored is
+# the $objdir directory. This is a cygwin/mingw-specific
+# behavior.
+func_emit_wrapper ()
+{
+ func_emit_wrapper_arg1=${1-no}
+
+ $ECHO "\
+#! $SHELL
+
+# $output - temporary wrapper script for $objdir/$outputname
+# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION
+#
+# The $output program cannot be directly executed until all the libtool
+# libraries that it depends on are installed.
+#
+# This wrapper script should never be moved out of the build directory.
+# If it is, it will not operate correctly.
+
+# Sed substitution that helps us do robust quoting. It backslashifies
+# metacharacters that are still active within double-quoted strings.
+sed_quote_subst='$sed_quote_subst'
+
+# Be Bourne compatible
+if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then
+ emulate sh
+ NULLCMD=:
+ # Zsh 3.x and 4.x performs word splitting on \${1+\"\$@\"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '\${1+\"\$@\"}'='\"\$@\"'
+ setopt NO_GLOB_SUBST
+else
+ case \`(set -o) 2>/dev/null\` in *posix*) set -o posix;; esac
+fi
+BIN_SH=xpg4; export BIN_SH # for Tru64
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+relink_command=\"$relink_command\"
+
+# This environment variable determines our operation mode.
+if test \"\$libtool_install_magic\" = \"$magic\"; then
+ # install mode needs the following variables:
+ generated_by_libtool_version='$macro_version'
+ notinst_deplibs='$notinst_deplibs'
+else
+ # When we are sourced in execute mode, \$file and \$ECHO are already set.
+ if test \"\$libtool_execute_magic\" != \"$magic\"; then
+ file=\"\$0\""
+
+ qECHO=`$ECHO "$ECHO" | $SED "$sed_quote_subst"`
+ $ECHO "\
+
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
+{
+ eval 'cat <<_LTECHO_EOF
+\$1
+_LTECHO_EOF'
+}
+ ECHO=\"$qECHO\"
+ fi
+
+# Very basic option parsing. These options are (a) specific to
+# the libtool wrapper, (b) are identical between the wrapper
+# /script/ and the wrapper /executable/ which is used only on
+# windows platforms, and (c) all begin with the string "--lt-"
+# (application programs are unlikely to have options which match
+# this pattern).
+#
+# There are only two supported options: --lt-debug and
+# --lt-dump-script. There is, deliberately, no --lt-help.
+#
+# The first argument to this parsing function should be the
+# script's $0 value, followed by "$@".
+lt_option_debug=
+func_parse_lt_options ()
+{
+ lt_script_arg0=\$0
+ shift
+ for lt_opt
+ do
+ case \"\$lt_opt\" in
+ --lt-debug) lt_option_debug=1 ;;
+ --lt-dump-script)
+ lt_dump_D=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%/[^/]*$%%'\`
+ test \"X\$lt_dump_D\" = \"X\$lt_script_arg0\" && lt_dump_D=.
+ lt_dump_F=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%^.*/%%'\`
+ cat \"\$lt_dump_D/\$lt_dump_F\"
+ exit 0
+ ;;
+ --lt-*)
+ \$ECHO \"Unrecognized --lt- option: '\$lt_opt'\" 1>&2
+ exit 1
+ ;;
+ esac
+ done
+
+ # Print the debug banner immediately:
+ if test -n \"\$lt_option_debug\"; then
+ echo \"${outputname}:${output}:\${LINENO}: libtool wrapper (GNU $PACKAGE$TIMESTAMP) $VERSION\" 1>&2
+ fi
+}
+
+# Used when --lt-debug. Prints its arguments to stdout
+# (redirection is the responsibility of the caller)
+func_lt_dump_args ()
+{
+ lt_dump_args_N=1;
+ for lt_arg
+ do
+ \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[\$lt_dump_args_N]: \$lt_arg\"
+ lt_dump_args_N=\`expr \$lt_dump_args_N + 1\`
+ done
+}
+
+# Core function for launching the target application
+func_exec_program_core ()
+{
+"
+ case $host in
+ # Backslashes separate directories on plain windows
+ *-*-mingw | *-*-os2* | *-cegcc*)
+ $ECHO "\
+ if test -n \"\$lt_option_debug\"; then
+ \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[0]: \$progdir\\\\\$program\" 1>&2
+ func_lt_dump_args \${1+\"\$@\"} 1>&2
+ fi
+ exec \"\$progdir\\\\\$program\" \${1+\"\$@\"}
+"
+ ;;
+
+ *)
+ $ECHO "\
+ if test -n \"\$lt_option_debug\"; then
+ \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[0]: \$progdir/\$program\" 1>&2
+ func_lt_dump_args \${1+\"\$@\"} 1>&2
+ fi
+ exec \"\$progdir/\$program\" \${1+\"\$@\"}
+"
+ ;;
+ esac
+ $ECHO "\
+ \$ECHO \"\$0: cannot exec \$program \$*\" 1>&2
+ exit 1
+}
+
+# A function to encapsulate launching the target application
+# Strips options in the --lt-* namespace from \$@ and
+# launches target application with the remaining arguments.
+func_exec_program ()
+{
+ case \" \$* \" in
+ *\\ --lt-*)
+ for lt_wr_arg
+ do
+ case \$lt_wr_arg in
+ --lt-*) ;;
+ *) set x \"\$@\" \"\$lt_wr_arg\"; shift;;
+ esac
+ shift
+ done ;;
+ esac
+ func_exec_program_core \${1+\"\$@\"}
+}
+
+ # Parse options
+ func_parse_lt_options \"\$0\" \${1+\"\$@\"}
+
+ # Find the directory that this script lives in.
+ thisdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*$%%'\`
+ test \"x\$thisdir\" = \"x\$file\" && thisdir=.
+
+ # Follow symbolic links until we get to the real thisdir.
+ file=\`ls -ld \"\$file\" | $SED -n 's/.*-> //p'\`
+ while test -n \"\$file\"; do
+ destdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*\$%%'\`
+
+ # If there was a directory component, then change thisdir.
+ if test \"x\$destdir\" != \"x\$file\"; then
+ case \"\$destdir\" in
+ [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;;
+ *) thisdir=\"\$thisdir/\$destdir\" ;;
+ esac
+ fi
+
+ file=\`\$ECHO \"\$file\" | $SED 's%^.*/%%'\`
+ file=\`ls -ld \"\$thisdir/\$file\" | $SED -n 's/.*-> //p'\`
+ done
+
+ # Usually 'no', except on cygwin/mingw when embedded into
+ # the cwrapper.
+ WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_arg1
+ if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then
+ # special case for '.'
+ if test \"\$thisdir\" = \".\"; then
+ thisdir=\`pwd\`
+ fi
+ # remove .libs from thisdir
+ case \"\$thisdir\" in
+ *[\\\\/]$objdir ) thisdir=\`\$ECHO \"\$thisdir\" | $SED 's%[\\\\/][^\\\\/]*$%%'\` ;;
+ $objdir ) thisdir=. ;;
+ esac
+ fi
+
+ # Try to get the absolute directory name.
+ absdir=\`cd \"\$thisdir\" && pwd\`
+ test -n \"\$absdir\" && thisdir=\"\$absdir\"
+"
+
+ if test "$fast_install" = yes; then
+ $ECHO "\
+ program=lt-'$outputname'$exeext
+ progdir=\"\$thisdir/$objdir\"
+
+ if test ! -f \"\$progdir/\$program\" ||
+ { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | ${SED} 1q\`; \\
+ test \"X\$file\" != \"X\$progdir/\$program\"; }; then
+
+ file=\"\$\$-\$program\"
+
+ if test ! -d \"\$progdir\"; then
+ $MKDIR \"\$progdir\"
+ else
+ $RM \"\$progdir/\$file\"
+ fi"
+
+ $ECHO "\
+
+ # relink executable if necessary
+ if test -n \"\$relink_command\"; then
+ if relink_command_output=\`eval \$relink_command 2>&1\`; then :
+ else
+ $ECHO \"\$relink_command_output\" >&2
+ $RM \"\$progdir/\$file\"
+ exit 1
+ fi
+ fi
+
+ $MV \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null ||
+ { $RM \"\$progdir/\$program\";
+ $MV \"\$progdir/\$file\" \"\$progdir/\$program\"; }
+ $RM \"\$progdir/\$file\"
+ fi"
+ else
+ $ECHO "\
+ program='$outputname'
+ progdir=\"\$thisdir/$objdir\"
+"
+ fi
+
+ $ECHO "\
+
+ if test -f \"\$progdir/\$program\"; then"
+
+ # fixup the dll searchpath if we need to.
+ #
+ # Fix the DLL searchpath if we need to. Do this before prepending
+ # to shlibpath, because on Windows, both are PATH and uninstalled
+ # libraries must come first.
+ if test -n "$dllsearchpath"; then
+ $ECHO "\
+ # Add the dll search path components to the executable PATH
+ PATH=$dllsearchpath:\$PATH
+"
+ fi
+
+ # Export our shlibpath_var if we have one.
+ if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then
+ $ECHO "\
+ # Add our own library path to $shlibpath_var
+ $shlibpath_var=\"$temp_rpath\$$shlibpath_var\"
+
+ # Some systems cannot cope with colon-terminated $shlibpath_var
+ # The second colon is a workaround for a bug in BeOS R4 sed
+ $shlibpath_var=\`\$ECHO \"\$$shlibpath_var\" | $SED 's/::*\$//'\`
+
+ export $shlibpath_var
+"
+ fi
+
+ $ECHO "\
+ if test \"\$libtool_execute_magic\" != \"$magic\"; then
+ # Run the actual program with our arguments.
+ func_exec_program \${1+\"\$@\"}
+ fi
+ else
+ # The program doesn't exist.
+ \$ECHO \"\$0: error: \\\`\$progdir/\$program' does not exist\" 1>&2
+ \$ECHO \"This script is just a wrapper for \$program.\" 1>&2
+ \$ECHO \"See the $PACKAGE documentation for more information.\" 1>&2
+ exit 1
+ fi
+fi\
+"
+}
+
+
+# func_emit_cwrapperexe_src
+# emit the source code for a wrapper executable on stdout
+# Must ONLY be called from within func_mode_link because
+# it depends on a number of variable set therein.
+func_emit_cwrapperexe_src ()
+{
+ cat <<EOF
+
+/* $cwrappersource - temporary wrapper executable for $objdir/$outputname
+ Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION
+
+ The $output program cannot be directly executed until all the libtool
+ libraries that it depends on are installed.
+
+ This wrapper executable should never be moved out of the build directory.
+ If it is, it will not operate correctly.
+*/
+EOF
+ cat <<"EOF"
+#ifdef _MSC_VER
+# define _CRT_SECURE_NO_DEPRECATE 1
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef _MSC_VER
+# include <direct.h>
+# include <process.h>
+# include <io.h>
+#else
+# include <unistd.h>
+# include <stdint.h>
+# ifdef __CYGWIN__
+# include <io.h>
+# endif
+#endif
+#include <malloc.h>
+#include <stdarg.h>
+#include <assert.h>
+#include <string.h>
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+
+/* declarations of non-ANSI functions */
+#if defined(__MINGW32__)
+# ifdef __STRICT_ANSI__
+int _putenv (const char *);
+# endif
+#elif defined(__CYGWIN__)
+# ifdef __STRICT_ANSI__
+char *realpath (const char *, char *);
+int putenv (char *);
+int setenv (const char *, const char *, int);
+# endif
+/* #elif defined (other platforms) ... */
+#endif
+
+/* portability defines, excluding path handling macros */
+#if defined(_MSC_VER)
+# define setmode _setmode
+# define stat _stat
+# define chmod _chmod
+# define getcwd _getcwd
+# define putenv _putenv
+# define S_IXUSR _S_IEXEC
+# ifndef _INTPTR_T_DEFINED
+# define _INTPTR_T_DEFINED
+# define intptr_t int
+# endif
+#elif defined(__MINGW32__)
+# define setmode _setmode
+# define stat _stat
+# define chmod _chmod
+# define getcwd _getcwd
+# define putenv _putenv
+#elif defined(__CYGWIN__)
+# define HAVE_SETENV
+# define FOPEN_WB "wb"
+/* #elif defined (other platforms) ... */
+#endif
+
+#if defined(PATH_MAX)
+# define LT_PATHMAX PATH_MAX
+#elif defined(MAXPATHLEN)
+# define LT_PATHMAX MAXPATHLEN
+#else
+# define LT_PATHMAX 1024
+#endif
+
+#ifndef S_IXOTH
+# define S_IXOTH 0
+#endif
+#ifndef S_IXGRP
+# define S_IXGRP 0
+#endif
+
+/* path handling portability macros */
+#ifndef DIR_SEPARATOR
+# define DIR_SEPARATOR '/'
+# define PATH_SEPARATOR ':'
+#endif
+
+#if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \
+ defined (__OS2__)
+# define HAVE_DOS_BASED_FILE_SYSTEM
+# define FOPEN_WB "wb"
+# ifndef DIR_SEPARATOR_2
+# define DIR_SEPARATOR_2 '\\'
+# endif
+# ifndef PATH_SEPARATOR_2
+# define PATH_SEPARATOR_2 ';'
+# endif
+#endif
+
+#ifndef DIR_SEPARATOR_2
+# define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR)
+#else /* DIR_SEPARATOR_2 */
+# define IS_DIR_SEPARATOR(ch) \
+ (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2))
+#endif /* DIR_SEPARATOR_2 */
+
+#ifndef PATH_SEPARATOR_2
+# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR)
+#else /* PATH_SEPARATOR_2 */
+# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2)
+#endif /* PATH_SEPARATOR_2 */
+
+#ifndef FOPEN_WB
+# define FOPEN_WB "w"
+#endif
+#ifndef _O_BINARY
+# define _O_BINARY 0
+#endif
+
+#define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type)))
+#define XFREE(stale) do { \
+ if (stale) { free ((void *) stale); stale = 0; } \
+} while (0)
+
+#if defined(LT_DEBUGWRAPPER)
+static int lt_debug = 1;
+#else
+static int lt_debug = 0;
+#endif
+
+const char *program_name = "libtool-wrapper"; /* in case xstrdup fails */
+
+void *xmalloc (size_t num);
+char *xstrdup (const char *string);
+const char *base_name (const char *name);
+char *find_executable (const char *wrapper);
+char *chase_symlinks (const char *pathspec);
+int make_executable (const char *path);
+int check_executable (const char *path);
+char *strendzap (char *str, const char *pat);
+void lt_debugprintf (const char *file, int line, const char *fmt, ...);
+void lt_fatal (const char *file, int line, const char *message, ...);
+static const char *nonnull (const char *s);
+static const char *nonempty (const char *s);
+void lt_setenv (const char *name, const char *value);
+char *lt_extend_str (const char *orig_value, const char *add, int to_end);
+void lt_update_exe_path (const char *name, const char *value);
+void lt_update_lib_path (const char *name, const char *value);
+char **prepare_spawn (char **argv);
+void lt_dump_script (FILE *f);
+EOF
+
+ cat <<EOF
+volatile const char * MAGIC_EXE = "$magic_exe";
+const char * LIB_PATH_VARNAME = "$shlibpath_var";
+EOF
+
+ if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then
+ func_to_host_path "$temp_rpath"
+ cat <<EOF
+const char * LIB_PATH_VALUE = "$func_to_host_path_result";
+EOF
+ else
+ cat <<"EOF"
+const char * LIB_PATH_VALUE = "";
+EOF
+ fi
+
+ if test -n "$dllsearchpath"; then
+ func_to_host_path "$dllsearchpath:"
+ cat <<EOF
+const char * EXE_PATH_VARNAME = "PATH";
+const char * EXE_PATH_VALUE = "$func_to_host_path_result";
+EOF
+ else
+ cat <<"EOF"
+const char * EXE_PATH_VARNAME = "";
+const char * EXE_PATH_VALUE = "";
+EOF
+ fi
+
+ if test "$fast_install" = yes; then
+ cat <<EOF
+const char * TARGET_PROGRAM_NAME = "lt-$outputname"; /* hopefully, no .exe */
+EOF
+ else
+ cat <<EOF
+const char * TARGET_PROGRAM_NAME = "$outputname"; /* hopefully, no .exe */
+EOF
+ fi
+
+
+ cat <<"EOF"
+
+#define LTWRAPPER_OPTION_PREFIX "--lt-"
+
+static const char *ltwrapper_option_prefix = LTWRAPPER_OPTION_PREFIX;
+static const char *dumpscript_opt = LTWRAPPER_OPTION_PREFIX "dump-script";
+static const char *debug_opt = LTWRAPPER_OPTION_PREFIX "debug";
+
+int
+main (int argc, char *argv[])
+{
+ char **newargz;
+ int newargc;
+ char *tmp_pathspec;
+ char *actual_cwrapper_path;
+ char *actual_cwrapper_name;
+ char *target_name;
+ char *lt_argv_zero;
+ intptr_t rval = 127;
+
+ int i;
+
+ program_name = (char *) xstrdup (base_name (argv[0]));
+ newargz = XMALLOC (char *, argc + 1);
+
+ /* very simple arg parsing; don't want to rely on getopt
+ * also, copy all non cwrapper options to newargz, except
+ * argz[0], which is handled differently
+ */
+ newargc=0;
+ for (i = 1; i < argc; i++)
+ {
+ if (strcmp (argv[i], dumpscript_opt) == 0)
+ {
+EOF
+ case "$host" in
+ *mingw* | *cygwin* )
+ # make stdout use "unix" line endings
+ echo " setmode(1,_O_BINARY);"
+ ;;
+ esac
+
+ cat <<"EOF"
+ lt_dump_script (stdout);
+ return 0;
+ }
+ if (strcmp (argv[i], debug_opt) == 0)
+ {
+ lt_debug = 1;
+ continue;
+ }
+ if (strcmp (argv[i], ltwrapper_option_prefix) == 0)
+ {
+ /* however, if there is an option in the LTWRAPPER_OPTION_PREFIX
+ namespace, but it is not one of the ones we know about and
+ have already dealt with, above (inluding dump-script), then
+ report an error. Otherwise, targets might begin to believe
+ they are allowed to use options in the LTWRAPPER_OPTION_PREFIX
+ namespace. The first time any user complains about this, we'll
+ need to make LTWRAPPER_OPTION_PREFIX a configure-time option
+ or a configure.ac-settable value.
+ */
+ lt_fatal (__FILE__, __LINE__,
+ "unrecognized %s option: '%s'",
+ ltwrapper_option_prefix, argv[i]);
+ }
+ /* otherwise ... */
+ newargz[++newargc] = xstrdup (argv[i]);
+ }
+ newargz[++newargc] = NULL;
+
+EOF
+ cat <<EOF
+ /* The GNU banner must be the first non-error debug message */
+ lt_debugprintf (__FILE__, __LINE__, "libtool wrapper (GNU $PACKAGE$TIMESTAMP) $VERSION\n");
+EOF
+ cat <<"EOF"
+ lt_debugprintf (__FILE__, __LINE__, "(main) argv[0]: %s\n", argv[0]);
+ lt_debugprintf (__FILE__, __LINE__, "(main) program_name: %s\n", program_name);
+
+ tmp_pathspec = find_executable (argv[0]);
+ if (tmp_pathspec == NULL)
+ lt_fatal (__FILE__, __LINE__, "couldn't find %s", argv[0]);
+ lt_debugprintf (__FILE__, __LINE__,
+ "(main) found exe (before symlink chase) at: %s\n",
+ tmp_pathspec);
+
+ actual_cwrapper_path = chase_symlinks (tmp_pathspec);
+ lt_debugprintf (__FILE__, __LINE__,
+ "(main) found exe (after symlink chase) at: %s\n",
+ actual_cwrapper_path);
+ XFREE (tmp_pathspec);
+
+ actual_cwrapper_name = xstrdup (base_name (actual_cwrapper_path));
+ strendzap (actual_cwrapper_path, actual_cwrapper_name);
+
+ /* wrapper name transforms */
+ strendzap (actual_cwrapper_name, ".exe");
+ tmp_pathspec = lt_extend_str (actual_cwrapper_name, ".exe", 1);
+ XFREE (actual_cwrapper_name);
+ actual_cwrapper_name = tmp_pathspec;
+ tmp_pathspec = 0;
+
+ /* target_name transforms -- use actual target program name; might have lt- prefix */
+ target_name = xstrdup (base_name (TARGET_PROGRAM_NAME));
+ strendzap (target_name, ".exe");
+ tmp_pathspec = lt_extend_str (target_name, ".exe", 1);
+ XFREE (target_name);
+ target_name = tmp_pathspec;
+ tmp_pathspec = 0;
+
+ lt_debugprintf (__FILE__, __LINE__,
+ "(main) libtool target name: %s\n",
+ target_name);
+EOF
+
+ cat <<EOF
+ newargz[0] =
+ XMALLOC (char, (strlen (actual_cwrapper_path) +
+ strlen ("$objdir") + 1 + strlen (actual_cwrapper_name) + 1));
+ strcpy (newargz[0], actual_cwrapper_path);
+ strcat (newargz[0], "$objdir");
+ strcat (newargz[0], "/");
+EOF
+
+ cat <<"EOF"
+ /* stop here, and copy so we don't have to do this twice */
+ tmp_pathspec = xstrdup (newargz[0]);
+
+ /* do NOT want the lt- prefix here, so use actual_cwrapper_name */
+ strcat (newargz[0], actual_cwrapper_name);
+
+ /* DO want the lt- prefix here if it exists, so use target_name */
+ lt_argv_zero = lt_extend_str (tmp_pathspec, target_name, 1);
+ XFREE (tmp_pathspec);
+ tmp_pathspec = NULL;
+EOF
+
+ case $host_os in
+ mingw*)
+ cat <<"EOF"
+ {
+ char* p;
+ while ((p = strchr (newargz[0], '\\')) != NULL)
+ {
+ *p = '/';
+ }
+ while ((p = strchr (lt_argv_zero, '\\')) != NULL)
+ {
+ *p = '/';
+ }
+ }
+EOF
+ ;;
+ esac
+
+ cat <<"EOF"
+ XFREE (target_name);
+ XFREE (actual_cwrapper_path);
+ XFREE (actual_cwrapper_name);
+
+ lt_setenv ("BIN_SH", "xpg4"); /* for Tru64 */
+ lt_setenv ("DUALCASE", "1"); /* for MSK sh */
+ /* Update the DLL searchpath. EXE_PATH_VALUE ($dllsearchpath) must
+ be prepended before (that is, appear after) LIB_PATH_VALUE ($temp_rpath)
+ because on Windows, both *_VARNAMEs are PATH but uninstalled
+ libraries must come first. */
+ lt_update_exe_path (EXE_PATH_VARNAME, EXE_PATH_VALUE);
+ lt_update_lib_path (LIB_PATH_VARNAME, LIB_PATH_VALUE);
+
+ lt_debugprintf (__FILE__, __LINE__, "(main) lt_argv_zero: %s\n",
+ nonnull (lt_argv_zero));
+ for (i = 0; i < newargc; i++)
+ {
+ lt_debugprintf (__FILE__, __LINE__, "(main) newargz[%d]: %s\n",
+ i, nonnull (newargz[i]));
+ }
+
+EOF
+
+ case $host_os in
+ mingw*)
+ cat <<"EOF"
+ /* execv doesn't actually work on mingw as expected on unix */
+ newargz = prepare_spawn (newargz);
+ rval = _spawnv (_P_WAIT, lt_argv_zero, (const char * const *) newargz);
+ if (rval == -1)
+ {
+ /* failed to start process */
+ lt_debugprintf (__FILE__, __LINE__,
+ "(main) failed to launch target \"%s\": %s\n",
+ lt_argv_zero, nonnull (strerror (errno)));
+ return 127;
+ }
+ return rval;
+EOF
+ ;;
+ *)
+ cat <<"EOF"
+ execv (lt_argv_zero, newargz);
+ return rval; /* =127, but avoids unused variable warning */
+EOF
+ ;;
+ esac
+
+ cat <<"EOF"
+}
+
+void *
+xmalloc (size_t num)
+{
+ void *p = (void *) malloc (num);
+ if (!p)
+ lt_fatal (__FILE__, __LINE__, "memory exhausted");
+
+ return p;
+}
+
+char *
+xstrdup (const char *string)
+{
+ return string ? strcpy ((char *) xmalloc (strlen (string) + 1),
+ string) : NULL;
+}
+
+const char *
+base_name (const char *name)
+{
+ const char *base;
+
+#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
+ /* Skip over the disk name in MSDOS pathnames. */
+ if (isalpha ((unsigned char) name[0]) && name[1] == ':')
+ name += 2;
+#endif
+
+ for (base = name; *name; name++)
+ if (IS_DIR_SEPARATOR (*name))
+ base = name + 1;
+ return base;
+}
+
+int
+check_executable (const char *path)
+{
+ struct stat st;
+
+ lt_debugprintf (__FILE__, __LINE__, "(check_executable): %s\n",
+ nonempty (path));
+ if ((!path) || (!*path))
+ return 0;
+
+ if ((stat (path, &st) >= 0)
+ && (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)))
+ return 1;
+ else
+ return 0;
+}
+
+int
+make_executable (const char *path)
+{
+ int rval = 0;
+ struct stat st;
+
+ lt_debugprintf (__FILE__, __LINE__, "(make_executable): %s\n",
+ nonempty (path));
+ if ((!path) || (!*path))
+ return 0;
+
+ if (stat (path, &st) >= 0)
+ {
+ rval = chmod (path, st.st_mode | S_IXOTH | S_IXGRP | S_IXUSR);
+ }
+ return rval;
+}
+
+/* Searches for the full path of the wrapper. Returns
+ newly allocated full path name if found, NULL otherwise
+ Does not chase symlinks, even on platforms that support them.
+*/
+char *
+find_executable (const char *wrapper)
+{
+ int has_slash = 0;
+ const char *p;
+ const char *p_next;
+ /* static buffer for getcwd */
+ char tmp[LT_PATHMAX + 1];
+ int tmp_len;
+ char *concat_name;
+
+ lt_debugprintf (__FILE__, __LINE__, "(find_executable): %s\n",
+ nonempty (wrapper));
+
+ if ((wrapper == NULL) || (*wrapper == '\0'))
+ return NULL;
+
+ /* Absolute path? */
+#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
+ if (isalpha ((unsigned char) wrapper[0]) && wrapper[1] == ':')
+ {
+ concat_name = xstrdup (wrapper);
+ if (check_executable (concat_name))
+ return concat_name;
+ XFREE (concat_name);
+ }
+ else
+ {
+#endif
+ if (IS_DIR_SEPARATOR (wrapper[0]))
+ {
+ concat_name = xstrdup (wrapper);
+ if (check_executable (concat_name))
+ return concat_name;
+ XFREE (concat_name);
+ }
+#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
+ }
+#endif
+
+ for (p = wrapper; *p; p++)
+ if (*p == '/')
+ {
+ has_slash = 1;
+ break;
+ }
+ if (!has_slash)
+ {
+ /* no slashes; search PATH */
+ const char *path = getenv ("PATH");
+ if (path != NULL)
+ {
+ for (p = path; *p; p = p_next)
+ {
+ const char *q;
+ size_t p_len;
+ for (q = p; *q; q++)
+ if (IS_PATH_SEPARATOR (*q))
+ break;
+ p_len = q - p;
+ p_next = (*q == '\0' ? q : q + 1);
+ if (p_len == 0)
+ {
+ /* empty path: current directory */
+ if (getcwd (tmp, LT_PATHMAX) == NULL)
+ lt_fatal (__FILE__, __LINE__, "getcwd failed: %s",
+ nonnull (strerror (errno)));
+ tmp_len = strlen (tmp);
+ concat_name =
+ XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1);
+ memcpy (concat_name, tmp, tmp_len);
+ concat_name[tmp_len] = '/';
+ strcpy (concat_name + tmp_len + 1, wrapper);
+ }
+ else
+ {
+ concat_name =
+ XMALLOC (char, p_len + 1 + strlen (wrapper) + 1);
+ memcpy (concat_name, p, p_len);
+ concat_name[p_len] = '/';
+ strcpy (concat_name + p_len + 1, wrapper);
+ }
+ if (check_executable (concat_name))
+ return concat_name;
+ XFREE (concat_name);
+ }
+ }
+ /* not found in PATH; assume curdir */
+ }
+ /* Relative path | not found in path: prepend cwd */
+ if (getcwd (tmp, LT_PATHMAX) == NULL)
+ lt_fatal (__FILE__, __LINE__, "getcwd failed: %s",
+ nonnull (strerror (errno)));
+ tmp_len = strlen (tmp);
+ concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1);
+ memcpy (concat_name, tmp, tmp_len);
+ concat_name[tmp_len] = '/';
+ strcpy (concat_name + tmp_len + 1, wrapper);
+
+ if (check_executable (concat_name))
+ return concat_name;
+ XFREE (concat_name);
+ return NULL;
+}
+
+char *
+chase_symlinks (const char *pathspec)
+{
+#ifndef S_ISLNK
+ return xstrdup (pathspec);
+#else
+ char buf[LT_PATHMAX];
+ struct stat s;
+ char *tmp_pathspec = xstrdup (pathspec);
+ char *p;
+ int has_symlinks = 0;
+ while (strlen (tmp_pathspec) && !has_symlinks)
+ {
+ lt_debugprintf (__FILE__, __LINE__,
+ "checking path component for symlinks: %s\n",
+ tmp_pathspec);
+ if (lstat (tmp_pathspec, &s) == 0)
+ {
+ if (S_ISLNK (s.st_mode) != 0)
+ {
+ has_symlinks = 1;
+ break;
+ }
+
+ /* search backwards for last DIR_SEPARATOR */
+ p = tmp_pathspec + strlen (tmp_pathspec) - 1;
+ while ((p > tmp_pathspec) && (!IS_DIR_SEPARATOR (*p)))
+ p--;
+ if ((p == tmp_pathspec) && (!IS_DIR_SEPARATOR (*p)))
+ {
+ /* no more DIR_SEPARATORS left */
+ break;
+ }
+ *p = '\0';
+ }
+ else
+ {
+ lt_fatal (__FILE__, __LINE__,
+ "error accessing file \"%s\": %s",
+ tmp_pathspec, nonnull (strerror (errno)));
+ }
+ }
+ XFREE (tmp_pathspec);
+
+ if (!has_symlinks)
+ {
+ return xstrdup (pathspec);
+ }
+
+ tmp_pathspec = realpath (pathspec, buf);
+ if (tmp_pathspec == 0)
+ {
+ lt_fatal (__FILE__, __LINE__,
+ "could not follow symlinks for %s", pathspec);
+ }
+ return xstrdup (tmp_pathspec);
+#endif
+}
+
+char *
+strendzap (char *str, const char *pat)
+{
+ size_t len, patlen;
+
+ assert (str != NULL);
+ assert (pat != NULL);
+
+ len = strlen (str);
+ patlen = strlen (pat);
+
+ if (patlen <= len)
+ {
+ str += len - patlen;
+ if (strcmp (str, pat) == 0)
+ *str = '\0';
+ }
+ return str;
+}
+
+void
+lt_debugprintf (const char *file, int line, const char *fmt, ...)
+{
+ va_list args;
+ if (lt_debug)
+ {
+ (void) fprintf (stderr, "%s:%s:%d: ", program_name, file, line);
+ va_start (args, fmt);
+ (void) vfprintf (stderr, fmt, args);
+ va_end (args);
+ }
+}
+
+static void
+lt_error_core (int exit_status, const char *file,
+ int line, const char *mode,
+ const char *message, va_list ap)
+{
+ fprintf (stderr, "%s:%s:%d: %s: ", program_name, file, line, mode);
+ vfprintf (stderr, message, ap);
+ fprintf (stderr, ".\n");
+
+ if (exit_status >= 0)
+ exit (exit_status);
+}
+
+void
+lt_fatal (const char *file, int line, const char *message, ...)
+{
+ va_list ap;
+ va_start (ap, message);
+ lt_error_core (EXIT_FAILURE, file, line, "FATAL", message, ap);
+ va_end (ap);
+}
+
+static const char *
+nonnull (const char *s)
+{
+ return s ? s : "(null)";
+}
+
+static const char *
+nonempty (const char *s)
+{
+ return (s && !*s) ? "(empty)" : nonnull (s);
+}
+
+void
+lt_setenv (const char *name, const char *value)
+{
+ lt_debugprintf (__FILE__, __LINE__,
+ "(lt_setenv) setting '%s' to '%s'\n",
+ nonnull (name), nonnull (value));
+ {
+#ifdef HAVE_SETENV
+ /* always make a copy, for consistency with !HAVE_SETENV */
+ char *str = xstrdup (value);
+ setenv (name, str, 1);
+#else
+ int len = strlen (name) + 1 + strlen (value) + 1;
+ char *str = XMALLOC (char, len);
+ sprintf (str, "%s=%s", name, value);
+ if (putenv (str) != EXIT_SUCCESS)
+ {
+ XFREE (str);
+ }
+#endif
+ }
+}
+
+char *
+lt_extend_str (const char *orig_value, const char *add, int to_end)
+{
+ char *new_value;
+ if (orig_value && *orig_value)
+ {
+ int orig_value_len = strlen (orig_value);
+ int add_len = strlen (add);
+ new_value = XMALLOC (char, add_len + orig_value_len + 1);
+ if (to_end)
+ {
+ strcpy (new_value, orig_value);
+ strcpy (new_value + orig_value_len, add);
+ }
+ else
+ {
+ strcpy (new_value, add);
+ strcpy (new_value + add_len, orig_value);
+ }
+ }
+ else
+ {
+ new_value = xstrdup (add);
+ }
+ return new_value;
+}
+
+void
+lt_update_exe_path (const char *name, const char *value)
+{
+ lt_debugprintf (__FILE__, __LINE__,
+ "(lt_update_exe_path) modifying '%s' by prepending '%s'\n",
+ nonnull (name), nonnull (value));
+
+ if (name && *name && value && *value)
+ {
+ char *new_value = lt_extend_str (getenv (name), value, 0);
+ /* some systems can't cope with a ':'-terminated path #' */
+ int len = strlen (new_value);
+ while (((len = strlen (new_value)) > 0) && IS_PATH_SEPARATOR (new_value[len-1]))
+ {
+ new_value[len-1] = '\0';
+ }
+ lt_setenv (name, new_value);
+ XFREE (new_value);
+ }
+}
+
+void
+lt_update_lib_path (const char *name, const char *value)
+{
+ lt_debugprintf (__FILE__, __LINE__,
+ "(lt_update_lib_path) modifying '%s' by prepending '%s'\n",
+ nonnull (name), nonnull (value));
+
+ if (name && *name && value && *value)
+ {
+ char *new_value = lt_extend_str (getenv (name), value, 0);
+ lt_setenv (name, new_value);
+ XFREE (new_value);
+ }
+}
+
+EOF
+ case $host_os in
+ mingw*)
+ cat <<"EOF"
+
+/* Prepares an argument vector before calling spawn().
+ Note that spawn() does not by itself call the command interpreter
+ (getenv ("COMSPEC") != NULL ? getenv ("COMSPEC") :
+ ({ OSVERSIONINFO v; v.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+ GetVersionEx(&v);
+ v.dwPlatformId == VER_PLATFORM_WIN32_NT;
+ }) ? "cmd.exe" : "command.com").
+ Instead it simply concatenates the arguments, separated by ' ', and calls
+ CreateProcess(). We must quote the arguments since Win32 CreateProcess()
+ interprets characters like ' ', '\t', '\\', '"' (but not '<' and '>') in a
+ special way:
+ - Space and tab are interpreted as delimiters. They are not treated as
+ delimiters if they are surrounded by double quotes: "...".
+ - Unescaped double quotes are removed from the input. Their only effect is
+ that within double quotes, space and tab are treated like normal
+ characters.
+ - Backslashes not followed by double quotes are not special.
+ - But 2*n+1 backslashes followed by a double quote become
+ n backslashes followed by a double quote (n >= 0):
+ \" -> "
+ \\\" -> \"
+ \\\\\" -> \\"
+ */
+#define SHELL_SPECIAL_CHARS "\"\\ \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037"
+#define SHELL_SPACE_CHARS " \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037"
+char **
+prepare_spawn (char **argv)
+{
+ size_t argc;
+ char **new_argv;
+ size_t i;
+
+ /* Count number of arguments. */
+ for (argc = 0; argv[argc] != NULL; argc++)
+ ;
+
+ /* Allocate new argument vector. */
+ new_argv = XMALLOC (char *, argc + 1);
+
+ /* Put quoted arguments into the new argument vector. */
+ for (i = 0; i < argc; i++)
+ {
+ const char *string = argv[i];
+
+ if (string[0] == '\0')
+ new_argv[i] = xstrdup ("\"\"");
+ else if (strpbrk (string, SHELL_SPECIAL_CHARS) != NULL)
+ {
+ int quote_around = (strpbrk (string, SHELL_SPACE_CHARS) != NULL);
+ size_t length;
+ unsigned int backslashes;
+ const char *s;
+ char *quoted_string;
+ char *p;
+
+ length = 0;
+ backslashes = 0;
+ if (quote_around)
+ length++;
+ for (s = string; *s != '\0'; s++)
+ {
+ char c = *s;
+ if (c == '"')
+ length += backslashes + 1;
+ length++;
+ if (c == '\\')
+ backslashes++;
+ else
+ backslashes = 0;
+ }
+ if (quote_around)
+ length += backslashes + 1;
+
+ quoted_string = XMALLOC (char, length + 1);
+
+ p = quoted_string;
+ backslashes = 0;
+ if (quote_around)
+ *p++ = '"';
+ for (s = string; *s != '\0'; s++)
+ {
+ char c = *s;
+ if (c == '"')
+ {
+ unsigned int j;
+ for (j = backslashes + 1; j > 0; j--)
+ *p++ = '\\';
+ }
+ *p++ = c;
+ if (c == '\\')
+ backslashes++;
+ else
+ backslashes = 0;
+ }
+ if (quote_around)
+ {
+ unsigned int j;
+ for (j = backslashes; j > 0; j--)
+ *p++ = '\\';
+ *p++ = '"';
+ }
+ *p = '\0';
+
+ new_argv[i] = quoted_string;
+ }
+ else
+ new_argv[i] = (char *) string;
+ }
+ new_argv[argc] = NULL;
+
+ return new_argv;
+}
+EOF
+ ;;
+ esac
+
+ cat <<"EOF"
+void lt_dump_script (FILE* f)
+{
+EOF
+ func_emit_wrapper yes |
+ $SED -n -e '
+s/^\(.\{79\}\)\(..*\)/\1\
+\2/
+h
+s/\([\\"]\)/\\\1/g
+s/$/\\n/
+s/\([^\n]*\).*/ fputs ("\1", f);/p
+g
+D'
+ cat <<"EOF"
+}
+EOF
+}
+# end: func_emit_cwrapperexe_src
+
+# func_win32_import_lib_p ARG
+# True if ARG is an import lib, as indicated by $file_magic_cmd
+func_win32_import_lib_p ()
+{
+ $opt_debug
+ case `eval $file_magic_cmd \"\$1\" 2>/dev/null | $SED -e 10q` in
+ *import*) : ;;
+ *) false ;;
+ esac
+}
+
+# func_mode_link arg...
+func_mode_link ()
+{
+ $opt_debug
+ case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
+ # It is impossible to link a dll without this setting, and
+ # we shouldn't force the makefile maintainer to figure out
+ # which system we are compiling for in order to pass an extra
+ # flag for every libtool invocation.
+ # allow_undefined=no
+
+ # FIXME: Unfortunately, there are problems with the above when trying
+ # to make a dll which has undefined symbols, in which case not
+ # even a static library is built. For now, we need to specify
+ # -no-undefined on the libtool link line when we can be certain
+ # that all symbols are satisfied, otherwise we get a static library.
+ allow_undefined=yes
+ ;;
+ *)
+ allow_undefined=yes
+ ;;
+ esac
+ libtool_args=$nonopt
+ base_compile="$nonopt $@"
+ compile_command=$nonopt
+ finalize_command=$nonopt
+
+ compile_rpath=
+ finalize_rpath=
+ compile_shlibpath=
+ finalize_shlibpath=
+ convenience=
+ old_convenience=
+ deplibs=
+ old_deplibs=
+ compiler_flags=
+ linker_flags=
+ dllsearchpath=
+ lib_search_path=`pwd`
+ inst_prefix_dir=
+ new_inherited_linker_flags=
+
+ avoid_version=no
+ bindir=
+ dlfiles=
+ dlprefiles=
+ dlself=no
+ export_dynamic=no
+ export_symbols=
+ export_symbols_regex=
+ generated=
+ libobjs=
+ ltlibs=
+ module=no
+ no_install=no
+ objs=
+ non_pic_objects=
+ precious_files_regex=
+ prefer_static_libs=no
+ preload=no
+ prev=
+ prevarg=
+ release=
+ rpath=
+ xrpath=
+ perm_rpath=
+ temp_rpath=
+ thread_safe=no
+ vinfo=
+ vinfo_number=no
+ weak_libs=
+ single_module="${wl}-single_module"
+ func_infer_tag $base_compile
+
+ # We need to know -static, to get the right output filenames.
+ for arg
+ do
+ case $arg in
+ -shared)
+ test "$build_libtool_libs" != yes && \
+ func_fatal_configuration "can not build a shared library"
+ build_old_libs=no
+ break
+ ;;
+ -all-static | -static | -static-libtool-libs)
+ case $arg in
+ -all-static)
+ if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then
+ func_warning "complete static linking is impossible in this configuration"
+ fi
+ if test -n "$link_static_flag"; then
+ dlopen_self=$dlopen_self_static
+ fi
+ prefer_static_libs=yes
+ ;;
+ -static)
+ if test -z "$pic_flag" && test -n "$link_static_flag"; then
+ dlopen_self=$dlopen_self_static
+ fi
+ prefer_static_libs=built
+ ;;
+ -static-libtool-libs)
+ if test -z "$pic_flag" && test -n "$link_static_flag"; then
+ dlopen_self=$dlopen_self_static
+ fi
+ prefer_static_libs=yes
+ ;;
+ esac
+ build_libtool_libs=no
+ build_old_libs=yes
+ break
+ ;;
+ esac
+ done
+
+ # See if our shared archives depend on static archives.
+ test -n "$old_archive_from_new_cmds" && build_old_libs=yes
+
+ # Go through the arguments, transforming them on the way.
+ while test "$#" -gt 0; do
+ arg="$1"
+ shift
+ func_quote_for_eval "$arg"
+ qarg=$func_quote_for_eval_unquoted_result
+ func_append libtool_args " $func_quote_for_eval_result"
+
+ # If the previous option needs an argument, assign it.
+ if test -n "$prev"; then
+ case $prev in
+ output)
+ func_append compile_command " @OUTPUT@"
+ func_append finalize_command " @OUTPUT@"
+ ;;
+ esac
+
+ case $prev in
+ bindir)
+ bindir="$arg"
+ prev=
+ continue
+ ;;
+ dlfiles|dlprefiles)
+ if test "$preload" = no; then
+ # Add the symbol object into the linking commands.
+ func_append compile_command " @SYMFILE@"
+ func_append finalize_command " @SYMFILE@"
+ preload=yes
+ fi
+ case $arg in
+ *.la | *.lo) ;; # We handle these cases below.
+ force)
+ if test "$dlself" = no; then
+ dlself=needless
+ export_dynamic=yes
+ fi
+ prev=
+ continue
+ ;;
+ self)
+ if test "$prev" = dlprefiles; then
+ dlself=yes
+ elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then
+ dlself=yes
+ else
+ dlself=needless
+ export_dynamic=yes
+ fi
+ prev=
+ continue
+ ;;
+ *)
+ if test "$prev" = dlfiles; then
+ func_append dlfiles " $arg"
+ else
+ func_append dlprefiles " $arg"
+ fi
+ prev=
+ continue
+ ;;
+ esac
+ ;;
+ expsyms)
+ export_symbols="$arg"
+ test -f "$arg" \
+ || func_fatal_error "symbol file \`$arg' does not exist"
+ prev=
+ continue
+ ;;
+ expsyms_regex)
+ export_symbols_regex="$arg"
+ prev=
+ continue
+ ;;
+ framework)
+ case $host in
+ *-*-darwin*)
+ case "$deplibs " in
+ *" $qarg.ltframework "*) ;;
+ *) func_append deplibs " $qarg.ltframework" # this is fixed later
+ ;;
+ esac
+ ;;
+ esac
+ prev=
+ continue
+ ;;
+ inst_prefix)
+ inst_prefix_dir="$arg"
+ prev=
+ continue
+ ;;
+ objectlist)
+ if test -f "$arg"; then
+ save_arg=$arg
+ moreargs=
+ for fil in `cat "$save_arg"`
+ do
+# func_append moreargs " $fil"
+ arg=$fil
+ # A libtool-controlled object.
+
+ # Check to see that this really is a libtool object.
+ if func_lalib_unsafe_p "$arg"; then
+ pic_object=
+ non_pic_object=
+
+ # Read the .lo file
+ func_source "$arg"
+
+ if test -z "$pic_object" ||
+ test -z "$non_pic_object" ||
+ test "$pic_object" = none &&
+ test "$non_pic_object" = none; then
+ func_fatal_error "cannot find name of object for \`$arg'"
+ fi
+
+ # Extract subdirectory from the argument.
+ func_dirname "$arg" "/" ""
+ xdir="$func_dirname_result"
+
+ if test "$pic_object" != none; then
+ # Prepend the subdirectory the object is found in.
+ pic_object="$xdir$pic_object"
+
+ if test "$prev" = dlfiles; then
+ if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then
+ func_append dlfiles " $pic_object"
+ prev=
+ continue
+ else
+ # If libtool objects are unsupported, then we need to preload.
+ prev=dlprefiles
+ fi
+ fi
+
+ # CHECK ME: I think I busted this. -Ossama
+ if test "$prev" = dlprefiles; then
+ # Preload the old-style object.
+ func_append dlprefiles " $pic_object"
+ prev=
+ fi
+
+ # A PIC object.
+ func_append libobjs " $pic_object"
+ arg="$pic_object"
+ fi
+
+ # Non-PIC object.
+ if test "$non_pic_object" != none; then
+ # Prepend the subdirectory the object is found in.
+ non_pic_object="$xdir$non_pic_object"
+
+ # A standard non-PIC object
+ func_append non_pic_objects " $non_pic_object"
+ if test -z "$pic_object" || test "$pic_object" = none ; then
+ arg="$non_pic_object"
+ fi
+ else
+ # If the PIC object exists, use it instead.
+ # $xdir was prepended to $pic_object above.
+ non_pic_object="$pic_object"
+ func_append non_pic_objects " $non_pic_object"
+ fi
+ else
+ # Only an error if not doing a dry-run.
+ if $opt_dry_run; then
+ # Extract subdirectory from the argument.
+ func_dirname "$arg" "/" ""
+ xdir="$func_dirname_result"
+
+ func_lo2o "$arg"
+ pic_object=$xdir$objdir/$func_lo2o_result
+ non_pic_object=$xdir$func_lo2o_result
+ func_append libobjs " $pic_object"
+ func_append non_pic_objects " $non_pic_object"
+ else
+ func_fatal_error "\`$arg' is not a valid libtool object"
+ fi
+ fi
+ done
+ else
+ func_fatal_error "link input file \`$arg' does not exist"
+ fi
+ arg=$save_arg
+ prev=
+ continue
+ ;;
+ precious_regex)
+ precious_files_regex="$arg"
+ prev=
+ continue
+ ;;
+ release)
+ release="-$arg"
+ prev=
+ continue
+ ;;
+ rpath | xrpath)
+ # We need an absolute path.
+ case $arg in
+ [\\/]* | [A-Za-z]:[\\/]*) ;;
+ *)
+ func_fatal_error "only absolute run-paths are allowed"
+ ;;
+ esac
+ if test "$prev" = rpath; then
+ case "$rpath " in
+ *" $arg "*) ;;
+ *) func_append rpath " $arg" ;;
+ esac
+ else
+ case "$xrpath " in
+ *" $arg "*) ;;
+ *) func_append xrpath " $arg" ;;
+ esac
+ fi
+ prev=
+ continue
+ ;;
+ shrext)
+ shrext_cmds="$arg"
+ prev=
+ continue
+ ;;
+ weak)
+ func_append weak_libs " $arg"
+ prev=
+ continue
+ ;;
+ xcclinker)
+ func_append linker_flags " $qarg"
+ func_append compiler_flags " $qarg"
+ prev=
+ func_append compile_command " $qarg"
+ func_append finalize_command " $qarg"
+ continue
+ ;;
+ xcompiler)
+ func_append compiler_flags " $qarg"
+ prev=
+ func_append compile_command " $qarg"
+ func_append finalize_command " $qarg"
+ continue
+ ;;
+ xlinker)
+ func_append linker_flags " $qarg"
+ func_append compiler_flags " $wl$qarg"
+ prev=
+ func_append compile_command " $wl$qarg"
+ func_append finalize_command " $wl$qarg"
+ continue
+ ;;
+ *)
+ eval "$prev=\"\$arg\""
+ prev=
+ continue
+ ;;
+ esac
+ fi # test -n "$prev"
+
+ prevarg="$arg"
+
+ case $arg in
+ -all-static)
+ if test -n "$link_static_flag"; then
+ # See comment for -static flag below, for more details.
+ func_append compile_command " $link_static_flag"
+ func_append finalize_command " $link_static_flag"
+ fi
+ continue
+ ;;
+
+ -allow-undefined)
+ # FIXME: remove this flag sometime in the future.
+ func_fatal_error "\`-allow-undefined' must not be used because it is the default"
+ ;;
+
+ -avoid-version)
+ avoid_version=yes
+ continue
+ ;;
+
+ -bindir)
+ prev=bindir
+ continue
+ ;;
+
+ -dlopen)
+ prev=dlfiles
+ continue
+ ;;
+
+ -dlpreopen)
+ prev=dlprefiles
+ continue
+ ;;
+
+ -export-dynamic)
+ export_dynamic=yes
+ continue
+ ;;
+
+ -export-symbols | -export-symbols-regex)
+ if test -n "$export_symbols" || test -n "$export_symbols_regex"; then
+ func_fatal_error "more than one -exported-symbols argument is not allowed"
+ fi
+ if test "X$arg" = "X-export-symbols"; then
+ prev=expsyms
+ else
+ prev=expsyms_regex
+ fi
+ continue
+ ;;
+
+ -framework)
+ prev=framework
+ continue
+ ;;
+
+ -inst-prefix-dir)
+ prev=inst_prefix
+ continue
+ ;;
+
+ # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:*
+ # so, if we see these flags be careful not to treat them like -L
+ -L[A-Z][A-Z]*:*)
+ case $with_gcc/$host in
+ no/*-*-irix* | /*-*-irix*)
+ func_append compile_command " $arg"
+ func_append finalize_command " $arg"
+ ;;
+ esac
+ continue
+ ;;
+
+ -L*)
+ func_stripname "-L" '' "$arg"
+ if test -z "$func_stripname_result"; then
+ if test "$#" -gt 0; then
+ func_fatal_error "require no space between \`-L' and \`$1'"
+ else
+ func_fatal_error "need path for \`-L' option"
+ fi
+ fi
+ func_resolve_sysroot "$func_stripname_result"
+ dir=$func_resolve_sysroot_result
+ # We need an absolute path.
+ case $dir in
+ [\\/]* | [A-Za-z]:[\\/]*) ;;
+ *)
+ absdir=`cd "$dir" && pwd`
+ test -z "$absdir" && \
+ func_fatal_error "cannot determine absolute directory name of \`$dir'"
+ dir="$absdir"
+ ;;
+ esac
+ case "$deplibs " in
+ *" -L$dir "* | *" $arg "*)
+ # Will only happen for absolute or sysroot arguments
+ ;;
+ *)
+ # Preserve sysroot, but never include relative directories
+ case $dir in
+ [\\/]* | [A-Za-z]:[\\/]* | =*) func_append deplibs " $arg" ;;
+ *) func_append deplibs " -L$dir" ;;
+ esac
+ func_append lib_search_path " $dir"
+ ;;
+ esac
+ case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
+ testbindir=`$ECHO "$dir" | $SED 's*/lib$*/bin*'`
+ case :$dllsearchpath: in
+ *":$dir:"*) ;;
+ ::) dllsearchpath=$dir;;
+ *) func_append dllsearchpath ":$dir";;
+ esac
+ case :$dllsearchpath: in
+ *":$testbindir:"*) ;;
+ ::) dllsearchpath=$testbindir;;
+ *) func_append dllsearchpath ":$testbindir";;
+ esac
+ ;;
+ esac
+ continue
+ ;;
+
+ -l*)
+ if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then
+ case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc* | *-*-haiku*)
+ # These systems don't actually have a C or math library (as such)
+ continue
+ ;;
+ *-*-os2*)
+ # These systems don't actually have a C library (as such)
+ test "X$arg" = "X-lc" && continue
+ ;;
+ *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)
+ # Do not include libc due to us having libc/libc_r.
+ test "X$arg" = "X-lc" && continue
+ ;;
+ *-*-rhapsody* | *-*-darwin1.[012])
+ # Rhapsody C and math libraries are in the System framework
+ func_append deplibs " System.ltframework"
+ continue
+ ;;
+ *-*-sco3.2v5* | *-*-sco5v6*)
+ # Causes problems with __ctype
+ test "X$arg" = "X-lc" && continue
+ ;;
+ *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*)
+ # Compiler inserts libc in the correct place for threads to work
+ test "X$arg" = "X-lc" && continue
+ ;;
+ esac
+ elif test "X$arg" = "X-lc_r"; then
+ case $host in
+ *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)
+ # Do not include libc_r directly, use -pthread flag.
+ continue
+ ;;
+ esac
+ fi
+ func_append deplibs " $arg"
+ continue
+ ;;
+
+ -module)
+ module=yes
+ continue
+ ;;
+
+ # Tru64 UNIX uses -model [arg] to determine the layout of C++
+ # classes, name mangling, and exception handling.
+ # Darwin uses the -arch flag to determine output architecture.
+ -model|-arch|-isysroot|--sysroot)
+ func_append compiler_flags " $arg"
+ func_append compile_command " $arg"
+ func_append finalize_command " $arg"
+ prev=xcompiler
+ continue
+ ;;
+
+ -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \
+ |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*)
+ func_append compiler_flags " $arg"
+ func_append compile_command " $arg"
+ func_append finalize_command " $arg"
+ case "$new_inherited_linker_flags " in
+ *" $arg "*) ;;
+ * ) func_append new_inherited_linker_flags " $arg" ;;
+ esac
+ continue
+ ;;
+
+ -multi_module)
+ single_module="${wl}-multi_module"
+ continue
+ ;;
+
+ -no-fast-install)
+ fast_install=no
+ continue
+ ;;
+
+ -no-install)
+ case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*)
+ # The PATH hackery in wrapper scripts is required on Windows
+ # and Darwin in order for the loader to find any dlls it needs.
+ func_warning "\`-no-install' is ignored for $host"
+ func_warning "assuming \`-no-fast-install' instead"
+ fast_install=no
+ ;;
+ *) no_install=yes ;;
+ esac
+ continue
+ ;;
+
+ -no-undefined)
+ allow_undefined=no
+ continue
+ ;;
+
+ -objectlist)
+ prev=objectlist
+ continue
+ ;;
+
+ -o) prev=output ;;
+
+ -precious-files-regex)
+ prev=precious_regex
+ continue
+ ;;
+
+ -release)
+ prev=release
+ continue
+ ;;
+
+ -rpath)
+ prev=rpath
+ continue
+ ;;
+
+ -R)
+ prev=xrpath
+ continue
+ ;;
+
+ -R*)
+ func_stripname '-R' '' "$arg"
+ dir=$func_stripname_result
+ # We need an absolute path.
+ case $dir in
+ [\\/]* | [A-Za-z]:[\\/]*) ;;
+ =*)
+ func_stripname '=' '' "$dir"
+ dir=$lt_sysroot$func_stripname_result
+ ;;
+ *)
+ func_fatal_error "only absolute run-paths are allowed"
+ ;;
+ esac
+ case "$xrpath " in
+ *" $dir "*) ;;
+ *) func_append xrpath " $dir" ;;
+ esac
+ continue
+ ;;
+
+ -shared)
+ # The effects of -shared are defined in a previous loop.
+ continue
+ ;;
+
+ -shrext)
+ prev=shrext
+ continue
+ ;;
+
+ -static | -static-libtool-libs)
+ # The effects of -static are defined in a previous loop.
+ # We used to do the same as -all-static on platforms that
+ # didn't have a PIC flag, but the assumption that the effects
+ # would be equivalent was wrong. It would break on at least
+ # Digital Unix and AIX.
+ continue
+ ;;
+
+ -thread-safe)
+ thread_safe=yes
+ continue
+ ;;
+
+ -version-info)
+ prev=vinfo
+ continue
+ ;;
+
+ -version-number)
+ prev=vinfo
+ vinfo_number=yes
+ continue
+ ;;
+
+ -weak)
+ prev=weak
+ continue
+ ;;
+
+ -Wc,*)
+ func_stripname '-Wc,' '' "$arg"
+ args=$func_stripname_result
+ arg=
+ save_ifs="$IFS"; IFS=','
+ for flag in $args; do
+ IFS="$save_ifs"
+ func_quote_for_eval "$flag"
+ func_append arg " $func_quote_for_eval_result"
+ func_append compiler_flags " $func_quote_for_eval_result"
+ done
+ IFS="$save_ifs"
+ func_stripname ' ' '' "$arg"
+ arg=$func_stripname_result
+ ;;
+
+ -Wl,*)
+ func_stripname '-Wl,' '' "$arg"
+ args=$func_stripname_result
+ arg=
+ save_ifs="$IFS"; IFS=','
+ for flag in $args; do
+ IFS="$save_ifs"
+ func_quote_for_eval "$flag"
+ func_append arg " $wl$func_quote_for_eval_result"
+ func_append compiler_flags " $wl$func_quote_for_eval_result"
+ func_append linker_flags " $func_quote_for_eval_result"
+ done
+ IFS="$save_ifs"
+ func_stripname ' ' '' "$arg"
+ arg=$func_stripname_result
+ ;;
+
+ -Xcompiler)
+ prev=xcompiler
+ continue
+ ;;
+
+ -Xlinker)
+ prev=xlinker
+ continue
+ ;;
+
+ -XCClinker)
+ prev=xcclinker
+ continue
+ ;;
+
+ # -msg_* for osf cc
+ -msg_*)
+ func_quote_for_eval "$arg"
+ arg="$func_quote_for_eval_result"
+ ;;
+
+ # Flags to be passed through unchanged, with rationale:
+ # -64, -mips[0-9] enable 64-bit mode for the SGI compiler
+ # -r[0-9][0-9]* specify processor for the SGI compiler
+ # -xarch=*, -xtarget=* enable 64-bit mode for the Sun compiler
+ # +DA*, +DD* enable 64-bit mode for the HP compiler
+ # -q* compiler args for the IBM compiler
+ # -m*, -t[45]*, -txscale* architecture-specific flags for GCC
+ # -F/path path to uninstalled frameworks, gcc on darwin
+ # -p, -pg, --coverage, -fprofile-* profiling flags for GCC
+ # @file GCC response files
+ # -tp=* Portland pgcc target processor selection
+ # --sysroot=* for sysroot support
+ # -O*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization
+ -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \
+ -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \
+ -O*|-flto*|-fwhopr*|-fuse-linker-plugin)
+ func_quote_for_eval "$arg"
+ arg="$func_quote_for_eval_result"
+ func_append compile_command " $arg"
+ func_append finalize_command " $arg"
+ func_append compiler_flags " $arg"
+ continue
+ ;;
+
+ # Some other compiler flag.
+ -* | +*)
+ func_quote_for_eval "$arg"
+ arg="$func_quote_for_eval_result"
+ ;;
+
+ *.$objext)
+ # A standard object.
+ func_append objs " $arg"
+ ;;
+
+ *.lo)
+ # A libtool-controlled object.
+
+ # Check to see that this really is a libtool object.
+ if func_lalib_unsafe_p "$arg"; then
+ pic_object=
+ non_pic_object=
+
+ # Read the .lo file
+ func_source "$arg"
+
+ if test -z "$pic_object" ||
+ test -z "$non_pic_object" ||
+ test "$pic_object" = none &&
+ test "$non_pic_object" = none; then
+ func_fatal_error "cannot find name of object for \`$arg'"
+ fi
+
+ # Extract subdirectory from the argument.
+ func_dirname "$arg" "/" ""
+ xdir="$func_dirname_result"
+
+ if test "$pic_object" != none; then
+ # Prepend the subdirectory the object is found in.
+ pic_object="$xdir$pic_object"
+
+ if test "$prev" = dlfiles; then
+ if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then
+ func_append dlfiles " $pic_object"
+ prev=
+ continue
+ else
+ # If libtool objects are unsupported, then we need to preload.
+ prev=dlprefiles
+ fi
+ fi
+
+ # CHECK ME: I think I busted this. -Ossama
+ if test "$prev" = dlprefiles; then
+ # Preload the old-style object.
+ func_append dlprefiles " $pic_object"
+ prev=
+ fi
+
+ # A PIC object.
+ func_append libobjs " $pic_object"
+ arg="$pic_object"
+ fi
+
+ # Non-PIC object.
+ if test "$non_pic_object" != none; then
+ # Prepend the subdirectory the object is found in.
+ non_pic_object="$xdir$non_pic_object"
+
+ # A standard non-PIC object
+ func_append non_pic_objects " $non_pic_object"
+ if test -z "$pic_object" || test "$pic_object" = none ; then
+ arg="$non_pic_object"
+ fi
+ else
+ # If the PIC object exists, use it instead.
+ # $xdir was prepended to $pic_object above.
+ non_pic_object="$pic_object"
+ func_append non_pic_objects " $non_pic_object"
+ fi
+ else
+ # Only an error if not doing a dry-run.
+ if $opt_dry_run; then
+ # Extract subdirectory from the argument.
+ func_dirname "$arg" "/" ""
+ xdir="$func_dirname_result"
+
+ func_lo2o "$arg"
+ pic_object=$xdir$objdir/$func_lo2o_result
+ non_pic_object=$xdir$func_lo2o_result
+ func_append libobjs " $pic_object"
+ func_append non_pic_objects " $non_pic_object"
+ else
+ func_fatal_error "\`$arg' is not a valid libtool object"
+ fi
+ fi
+ ;;
+
+ *.$libext)
+ # An archive.
+ func_append deplibs " $arg"
+ func_append old_deplibs " $arg"
+ continue
+ ;;
+
+ *.la)
+ # A libtool-controlled library.
+
+ func_resolve_sysroot "$arg"
+ if test "$prev" = dlfiles; then
+ # This library was specified with -dlopen.
+ func_append dlfiles " $func_resolve_sysroot_result"
+ prev=
+ elif test "$prev" = dlprefiles; then
+ # The library was specified with -dlpreopen.
+ func_append dlprefiles " $func_resolve_sysroot_result"
+ prev=
+ else
+ func_append deplibs " $func_resolve_sysroot_result"
+ fi
+ continue
+ ;;
+
+ # Some other compiler argument.
+ *)
+ # Unknown arguments in both finalize_command and compile_command need
+ # to be aesthetically quoted because they are evaled later.
+ func_quote_for_eval "$arg"
+ arg="$func_quote_for_eval_result"
+ ;;
+ esac # arg
+
+ # Now actually substitute the argument into the commands.
+ if test -n "$arg"; then
+ func_append compile_command " $arg"
+ func_append finalize_command " $arg"
+ fi
+ done # argument parsing loop
+
+ test -n "$prev" && \
+ func_fatal_help "the \`$prevarg' option requires an argument"
+
+ if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then
+ eval arg=\"$export_dynamic_flag_spec\"
+ func_append compile_command " $arg"
+ func_append finalize_command " $arg"
+ fi
+
+ oldlibs=
+ # calculate the name of the file, without its directory
+ func_basename "$output"
+ outputname="$func_basename_result"
+ libobjs_save="$libobjs"
+
+ if test -n "$shlibpath_var"; then
+ # get the directories listed in $shlibpath_var
+ eval shlib_search_path=\`\$ECHO \"\${$shlibpath_var}\" \| \$SED \'s/:/ /g\'\`
+ else
+ shlib_search_path=
+ fi
+ eval sys_lib_search_path=\"$sys_lib_search_path_spec\"
+ eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\"
+
+ func_dirname "$output" "/" ""
+ output_objdir="$func_dirname_result$objdir"
+ func_to_tool_file "$output_objdir/"
+ tool_output_objdir=$func_to_tool_file_result
+ # Create the object directory.
+ func_mkdir_p "$output_objdir"
+
+ # Determine the type of output
+ case $output in
+ "")
+ func_fatal_help "you must specify an output file"
+ ;;
+ *.$libext) linkmode=oldlib ;;
+ *.lo | *.$objext) linkmode=obj ;;
+ *.la) linkmode=lib ;;
+ *) linkmode=prog ;; # Anything else should be a program.
+ esac
+
+ specialdeplibs=
+
+ libs=
+ # Find all interdependent deplibs by searching for libraries
+ # that are linked more than once (e.g. -la -lb -la)
+ for deplib in $deplibs; do
+ if $opt_preserve_dup_deps ; then
+ case "$libs " in
+ *" $deplib "*) func_append specialdeplibs " $deplib" ;;
+ esac
+ fi
+ func_append libs " $deplib"
+ done
+
+ if test "$linkmode" = lib; then
+ libs="$predeps $libs $compiler_lib_search_path $postdeps"
+
+ # Compute libraries that are listed more than once in $predeps
+ # $postdeps and mark them as special (i.e., whose duplicates are
+ # not to be eliminated).
+ pre_post_deps=
+ if $opt_duplicate_compiler_generated_deps; then
+ for pre_post_dep in $predeps $postdeps; do
+ case "$pre_post_deps " in
+ *" $pre_post_dep "*) func_append specialdeplibs " $pre_post_deps" ;;
+ esac
+ func_append pre_post_deps " $pre_post_dep"
+ done
+ fi
+ pre_post_deps=
+ fi
+
+ deplibs=
+ newdependency_libs=
+ newlib_search_path=
+ need_relink=no # whether we're linking any uninstalled libtool libraries
+ notinst_deplibs= # not-installed libtool libraries
+ notinst_path= # paths that contain not-installed libtool libraries
+
+ case $linkmode in
+ lib)
+ passes="conv dlpreopen link"
+ for file in $dlfiles $dlprefiles; do
+ case $file in
+ *.la) ;;
+ *)
+ func_fatal_help "libraries can \`-dlopen' only libtool libraries: $file"
+ ;;
+ esac
+ done
+ ;;
+ prog)
+ compile_deplibs=
+ finalize_deplibs=
+ alldeplibs=no
+ newdlfiles=
+ newdlprefiles=
+ passes="conv scan dlopen dlpreopen link"
+ ;;
+ *) passes="conv"
+ ;;
+ esac
+
+ for pass in $passes; do
+ # The preopen pass in lib mode reverses $deplibs; put it back here
+ # so that -L comes before libs that need it for instance...
+ if test "$linkmode,$pass" = "lib,link"; then
+ ## FIXME: Find the place where the list is rebuilt in the wrong
+ ## order, and fix it there properly
+ tmp_deplibs=
+ for deplib in $deplibs; do
+ tmp_deplibs="$deplib $tmp_deplibs"
+ done
+ deplibs="$tmp_deplibs"
+ fi
+
+ if test "$linkmode,$pass" = "lib,link" ||
+ test "$linkmode,$pass" = "prog,scan"; then
+ libs="$deplibs"
+ deplibs=
+ fi
+ if test "$linkmode" = prog; then
+ case $pass in
+ dlopen) libs="$dlfiles" ;;
+ dlpreopen) libs="$dlprefiles" ;;
+ link) libs="$deplibs %DEPLIBS% $dependency_libs" ;;
+ esac
+ fi
+ if test "$linkmode,$pass" = "lib,dlpreopen"; then
+ # Collect and forward deplibs of preopened libtool libs
+ for lib in $dlprefiles; do
+ # Ignore non-libtool-libs
+ dependency_libs=
+ func_resolve_sysroot "$lib"
+ case $lib in
+ *.la) func_source "$func_resolve_sysroot_result" ;;
+ esac
+
+ # Collect preopened libtool deplibs, except any this library
+ # has declared as weak libs
+ for deplib in $dependency_libs; do
+ func_basename "$deplib"
+ deplib_base=$func_basename_result
+ case " $weak_libs " in
+ *" $deplib_base "*) ;;
+ *) func_append deplibs " $deplib" ;;
+ esac
+ done
+ done
+ libs="$dlprefiles"
+ fi
+ if test "$pass" = dlopen; then
+ # Collect dlpreopened libraries
+ save_deplibs="$deplibs"
+ deplibs=
+ fi
+
+ for deplib in $libs; do
+ lib=
+ found=no
+ case $deplib in
+ -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \
+ |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*)
+ if test "$linkmode,$pass" = "prog,link"; then
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ else
+ func_append compiler_flags " $deplib"
+ if test "$linkmode" = lib ; then
+ case "$new_inherited_linker_flags " in
+ *" $deplib "*) ;;
+ * ) func_append new_inherited_linker_flags " $deplib" ;;
+ esac
+ fi
+ fi
+ continue
+ ;;
+ -l*)
+ if test "$linkmode" != lib && test "$linkmode" != prog; then
+ func_warning "\`-l' is ignored for archives/objects"
+ continue
+ fi
+ func_stripname '-l' '' "$deplib"
+ name=$func_stripname_result
+ if test "$linkmode" = lib; then
+ searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path"
+ else
+ searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path"
+ fi
+ for searchdir in $searchdirs; do
+ for search_ext in .la $std_shrext .so .a; do
+ # Search the libtool library
+ lib="$searchdir/lib${name}${search_ext}"
+ if test -f "$lib"; then
+ if test "$search_ext" = ".la"; then
+ found=yes
+ else
+ found=no
+ fi
+ break 2
+ fi
+ done
+ done
+ if test "$found" != yes; then
+ # deplib doesn't seem to be a libtool library
+ if test "$linkmode,$pass" = "prog,link"; then
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ else
+ deplibs="$deplib $deplibs"
+ test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs"
+ fi
+ continue
+ else # deplib is a libtool library
+ # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib,
+ # We need to do some special things here, and not later.
+ if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+ case " $predeps $postdeps " in
+ *" $deplib "*)
+ if func_lalib_p "$lib"; then
+ library_names=
+ old_library=
+ func_source "$lib"
+ for l in $old_library $library_names; do
+ ll="$l"
+ done
+ if test "X$ll" = "X$old_library" ; then # only static version available
+ found=no
+ func_dirname "$lib" "" "."
+ ladir="$func_dirname_result"
+ lib=$ladir/$old_library
+ if test "$linkmode,$pass" = "prog,link"; then
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ else
+ deplibs="$deplib $deplibs"
+ test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs"
+ fi
+ continue
+ fi
+ fi
+ ;;
+ *) ;;
+ esac
+ fi
+ fi
+ ;; # -l
+ *.ltframework)
+ if test "$linkmode,$pass" = "prog,link"; then
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ else
+ deplibs="$deplib $deplibs"
+ if test "$linkmode" = lib ; then
+ case "$new_inherited_linker_flags " in
+ *" $deplib "*) ;;
+ * ) func_append new_inherited_linker_flags " $deplib" ;;
+ esac
+ fi
+ fi
+ continue
+ ;;
+ -L*)
+ case $linkmode in
+ lib)
+ deplibs="$deplib $deplibs"
+ test "$pass" = conv && continue
+ newdependency_libs="$deplib $newdependency_libs"
+ func_stripname '-L' '' "$deplib"
+ func_resolve_sysroot "$func_stripname_result"
+ func_append newlib_search_path " $func_resolve_sysroot_result"
+ ;;
+ prog)
+ if test "$pass" = conv; then
+ deplibs="$deplib $deplibs"
+ continue
+ fi
+ if test "$pass" = scan; then
+ deplibs="$deplib $deplibs"
+ else
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ fi
+ func_stripname '-L' '' "$deplib"
+ func_resolve_sysroot "$func_stripname_result"
+ func_append newlib_search_path " $func_resolve_sysroot_result"
+ ;;
+ *)
+ func_warning "\`-L' is ignored for archives/objects"
+ ;;
+ esac # linkmode
+ continue
+ ;; # -L
+ -R*)
+ if test "$pass" = link; then
+ func_stripname '-R' '' "$deplib"
+ func_resolve_sysroot "$func_stripname_result"
+ dir=$func_resolve_sysroot_result
+ # Make sure the xrpath contains only unique directories.
+ case "$xrpath " in
+ *" $dir "*) ;;
+ *) func_append xrpath " $dir" ;;
+ esac
+ fi
+ deplibs="$deplib $deplibs"
+ continue
+ ;;
+ *.la)
+ func_resolve_sysroot "$deplib"
+ lib=$func_resolve_sysroot_result
+ ;;
+ *.$libext)
+ if test "$pass" = conv; then
+ deplibs="$deplib $deplibs"
+ continue
+ fi
+ case $linkmode in
+ lib)
+ # Linking convenience modules into shared libraries is allowed,
+ # but linking other static libraries is non-portable.
+ case " $dlpreconveniencelibs " in
+ *" $deplib "*) ;;
+ *)
+ valid_a_lib=no
+ case $deplibs_check_method in
+ match_pattern*)
+ set dummy $deplibs_check_method; shift
+ match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"`
+ if eval "\$ECHO \"$deplib\"" 2>/dev/null | $SED 10q \
+ | $EGREP "$match_pattern_regex" > /dev/null; then
+ valid_a_lib=yes
+ fi
+ ;;
+ pass_all)
+ valid_a_lib=yes
+ ;;
+ esac
+ if test "$valid_a_lib" != yes; then
+ echo
+ $ECHO "*** Warning: Trying to link with static lib archive $deplib."
+ echo "*** I have the capability to make that library automatically link in when"
+ echo "*** you link to this library. But I can only do this if you have a"
+ echo "*** shared version of the library, which you do not appear to have"
+ echo "*** because the file extensions .$libext of this argument makes me believe"
+ echo "*** that it is just a static archive that I should not use here."
+ else
+ echo
+ $ECHO "*** Warning: Linking the shared library $output against the"
+ $ECHO "*** static library $deplib is not portable!"
+ deplibs="$deplib $deplibs"
+ fi
+ ;;
+ esac
+ continue
+ ;;
+ prog)
+ if test "$pass" != link; then
+ deplibs="$deplib $deplibs"
+ else
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ fi
+ continue
+ ;;
+ esac # linkmode
+ ;; # *.$libext
+ *.lo | *.$objext)
+ if test "$pass" = conv; then
+ deplibs="$deplib $deplibs"
+ elif test "$linkmode" = prog; then
+ if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then
+ # If there is no dlopen support or we're linking statically,
+ # we need to preload.
+ func_append newdlprefiles " $deplib"
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ else
+ func_append newdlfiles " $deplib"
+ fi
+ fi
+ continue
+ ;;
+ %DEPLIBS%)
+ alldeplibs=yes
+ continue
+ ;;
+ esac # case $deplib
+
+ if test "$found" = yes || test -f "$lib"; then :
+ else
+ func_fatal_error "cannot find the library \`$lib' or unhandled argument \`$deplib'"
+ fi
+
+ # Check to see that this really is a libtool archive.
+ func_lalib_unsafe_p "$lib" \
+ || func_fatal_error "\`$lib' is not a valid libtool archive"
+
+ func_dirname "$lib" "" "."
+ ladir="$func_dirname_result"
+
+ dlname=
+ dlopen=
+ dlpreopen=
+ libdir=
+ library_names=
+ old_library=
+ inherited_linker_flags=
+ # If the library was installed with an old release of libtool,
+ # it will not redefine variables installed, or shouldnotlink
+ installed=yes
+ shouldnotlink=no
+ avoidtemprpath=
+
+
+ # Read the .la file
+ func_source "$lib"
+
+ # Convert "-framework foo" to "foo.ltframework"
+ if test -n "$inherited_linker_flags"; then
+ tmp_inherited_linker_flags=`$ECHO "$inherited_linker_flags" | $SED 's/-framework \([^ $]*\)/\1.ltframework/g'`
+ for tmp_inherited_linker_flag in $tmp_inherited_linker_flags; do
+ case " $new_inherited_linker_flags " in
+ *" $tmp_inherited_linker_flag "*) ;;
+ *) func_append new_inherited_linker_flags " $tmp_inherited_linker_flag";;
+ esac
+ done
+ fi
+ dependency_libs=`$ECHO " $dependency_libs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+ if test "$linkmode,$pass" = "lib,link" ||
+ test "$linkmode,$pass" = "prog,scan" ||
+ { test "$linkmode" != prog && test "$linkmode" != lib; }; then
+ test -n "$dlopen" && func_append dlfiles " $dlopen"
+ test -n "$dlpreopen" && func_append dlprefiles " $dlpreopen"
+ fi
+
+ if test "$pass" = conv; then
+ # Only check for convenience libraries
+ deplibs="$lib $deplibs"
+ if test -z "$libdir"; then
+ if test -z "$old_library"; then
+ func_fatal_error "cannot find name of link library for \`$lib'"
+ fi
+ # It is a libtool convenience library, so add in its objects.
+ func_append convenience " $ladir/$objdir/$old_library"
+ func_append old_convenience " $ladir/$objdir/$old_library"
+ elif test "$linkmode" != prog && test "$linkmode" != lib; then
+ func_fatal_error "\`$lib' is not a convenience library"
+ fi
+ tmp_libs=
+ for deplib in $dependency_libs; do
+ deplibs="$deplib $deplibs"
+ if $opt_preserve_dup_deps ; then
+ case "$tmp_libs " in
+ *" $deplib "*) func_append specialdeplibs " $deplib" ;;
+ esac
+ fi
+ func_append tmp_libs " $deplib"
+ done
+ continue
+ fi # $pass = conv
+
+
+ # Get the name of the library we link against.
+ linklib=
+ if test -n "$old_library" &&
+ { test "$prefer_static_libs" = yes ||
+ test "$prefer_static_libs,$installed" = "built,no"; }; then
+ linklib=$old_library
+ else
+ for l in $old_library $library_names; do
+ linklib="$l"
+ done
+ fi
+ if test -z "$linklib"; then
+ func_fatal_error "cannot find name of link library for \`$lib'"
+ fi
+
+ # This library was specified with -dlopen.
+ if test "$pass" = dlopen; then
+ if test -z "$libdir"; then
+ func_fatal_error "cannot -dlopen a convenience library: \`$lib'"
+ fi
+ if test -z "$dlname" ||
+ test "$dlopen_support" != yes ||
+ test "$build_libtool_libs" = no; then
+ # If there is no dlname, no dlopen support or we're linking
+ # statically, we need to preload. We also need to preload any
+ # dependent libraries so libltdl's deplib preloader doesn't
+ # bomb out in the load deplibs phase.
+ func_append dlprefiles " $lib $dependency_libs"
+ else
+ func_append newdlfiles " $lib"
+ fi
+ continue
+ fi # $pass = dlopen
+
+ # We need an absolute path.
+ case $ladir in
+ [\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;;
+ *)
+ abs_ladir=`cd "$ladir" && pwd`
+ if test -z "$abs_ladir"; then
+ func_warning "cannot determine absolute directory name of \`$ladir'"
+ func_warning "passing it literally to the linker, although it might fail"
+ abs_ladir="$ladir"
+ fi
+ ;;
+ esac
+ func_basename "$lib"
+ laname="$func_basename_result"
+
+ # Find the relevant object directory and library name.
+ if test "X$installed" = Xyes; then
+ if test ! -f "$lt_sysroot$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then
+ func_warning "library \`$lib' was moved."
+ dir="$ladir"
+ absdir="$abs_ladir"
+ libdir="$abs_ladir"
+ else
+ dir="$lt_sysroot$libdir"
+ absdir="$lt_sysroot$libdir"
+ fi
+ test "X$hardcode_automatic" = Xyes && avoidtemprpath=yes
+ else
+ if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then
+ dir="$ladir"
+ absdir="$abs_ladir"
+ # Remove this search path later
+ func_append notinst_path " $abs_ladir"
+ else
+ dir="$ladir/$objdir"
+ absdir="$abs_ladir/$objdir"
+ # Remove this search path later
+ func_append notinst_path " $abs_ladir"
+ fi
+ fi # $installed = yes
+ func_stripname 'lib' '.la' "$laname"
+ name=$func_stripname_result
+
+ # This library was specified with -dlpreopen.
+ if test "$pass" = dlpreopen; then
+ if test -z "$libdir" && test "$linkmode" = prog; then
+ func_fatal_error "only libraries may -dlpreopen a convenience library: \`$lib'"
+ fi
+ case "$host" in
+ # special handling for platforms with PE-DLLs.
+ *cygwin* | *mingw* | *cegcc* )
+ # Linker will automatically link against shared library if both
+ # static and shared are present. Therefore, ensure we extract
+ # symbols from the import library if a shared library is present
+ # (otherwise, the dlopen module name will be incorrect). We do
+ # this by putting the import library name into $newdlprefiles.
+ # We recover the dlopen module name by 'saving' the la file
+ # name in a special purpose variable, and (later) extracting the
+ # dlname from the la file.
+ if test -n "$dlname"; then
+ func_tr_sh "$dir/$linklib"
+ eval "libfile_$func_tr_sh_result=\$abs_ladir/\$laname"
+ func_append newdlprefiles " $dir/$linklib"
+ else
+ func_append newdlprefiles " $dir/$old_library"
+ # Keep a list of preopened convenience libraries to check
+ # that they are being used correctly in the link pass.
+ test -z "$libdir" && \
+ func_append dlpreconveniencelibs " $dir/$old_library"
+ fi
+ ;;
+ * )
+ # Prefer using a static library (so that no silly _DYNAMIC symbols
+ # are required to link).
+ if test -n "$old_library"; then
+ func_append newdlprefiles " $dir/$old_library"
+ # Keep a list of preopened convenience libraries to check
+ # that they are being used correctly in the link pass.
+ test -z "$libdir" && \
+ func_append dlpreconveniencelibs " $dir/$old_library"
+ # Otherwise, use the dlname, so that lt_dlopen finds it.
+ elif test -n "$dlname"; then
+ func_append newdlprefiles " $dir/$dlname"
+ else
+ func_append newdlprefiles " $dir/$linklib"
+ fi
+ ;;
+ esac
+ fi # $pass = dlpreopen
+
+ if test -z "$libdir"; then
+ # Link the convenience library
+ if test "$linkmode" = lib; then
+ deplibs="$dir/$old_library $deplibs"
+ elif test "$linkmode,$pass" = "prog,link"; then
+ compile_deplibs="$dir/$old_library $compile_deplibs"
+ finalize_deplibs="$dir/$old_library $finalize_deplibs"
+ else
+ deplibs="$lib $deplibs" # used for prog,scan pass
+ fi
+ continue
+ fi
+
+
+ if test "$linkmode" = prog && test "$pass" != link; then
+ func_append newlib_search_path " $ladir"
+ deplibs="$lib $deplibs"
+
+ linkalldeplibs=no
+ if test "$link_all_deplibs" != no || test -z "$library_names" ||
+ test "$build_libtool_libs" = no; then
+ linkalldeplibs=yes
+ fi
+
+ tmp_libs=
+ for deplib in $dependency_libs; do
+ case $deplib in
+ -L*) func_stripname '-L' '' "$deplib"
+ func_resolve_sysroot "$func_stripname_result"
+ func_append newlib_search_path " $func_resolve_sysroot_result"
+ ;;
+ esac
+ # Need to link against all dependency_libs?
+ if test "$linkalldeplibs" = yes; then
+ deplibs="$deplib $deplibs"
+ else
+ # Need to hardcode shared library paths
+ # or/and link against static libraries
+ newdependency_libs="$deplib $newdependency_libs"
+ fi
+ if $opt_preserve_dup_deps ; then
+ case "$tmp_libs " in
+ *" $deplib "*) func_append specialdeplibs " $deplib" ;;
+ esac
+ fi
+ func_append tmp_libs " $deplib"
+ done # for deplib
+ continue
+ fi # $linkmode = prog...
+
+ if test "$linkmode,$pass" = "prog,link"; then
+ if test -n "$library_names" &&
+ { { test "$prefer_static_libs" = no ||
+ test "$prefer_static_libs,$installed" = "built,yes"; } ||
+ test -z "$old_library"; }; then
+ # We need to hardcode the library path
+ if test -n "$shlibpath_var" && test -z "$avoidtemprpath" ; then
+ # Make sure the rpath contains only unique directories.
+ case "$temp_rpath:" in
+ *"$absdir:"*) ;;
+ *) func_append temp_rpath "$absdir:" ;;
+ esac
+ fi
+
+ # Hardcode the library path.
+ # Skip directories that are in the system default run-time
+ # search path.
+ case " $sys_lib_dlsearch_path " in
+ *" $absdir "*) ;;
+ *)
+ case "$compile_rpath " in
+ *" $absdir "*) ;;
+ *) func_append compile_rpath " $absdir" ;;
+ esac
+ ;;
+ esac
+ case " $sys_lib_dlsearch_path " in
+ *" $libdir "*) ;;
+ *)
+ case "$finalize_rpath " in
+ *" $libdir "*) ;;
+ *) func_append finalize_rpath " $libdir" ;;
+ esac
+ ;;
+ esac
+ fi # $linkmode,$pass = prog,link...
+
+ if test "$alldeplibs" = yes &&
+ { test "$deplibs_check_method" = pass_all ||
+ { test "$build_libtool_libs" = yes &&
+ test -n "$library_names"; }; }; then
+ # We only need to search for static libraries
+ continue
+ fi
+ fi
+
+ link_static=no # Whether the deplib will be linked statically
+ use_static_libs=$prefer_static_libs
+ if test "$use_static_libs" = built && test "$installed" = yes; then
+ use_static_libs=no
+ fi
+ if test -n "$library_names" &&
+ { test "$use_static_libs" = no || test -z "$old_library"; }; then
+ case $host in
+ *cygwin* | *mingw* | *cegcc*)
+ # No point in relinking DLLs because paths are not encoded
+ func_append notinst_deplibs " $lib"
+ need_relink=no
+ ;;
+ *)
+ if test "$installed" = no; then
+ func_append notinst_deplibs " $lib"
+ need_relink=yes
+ fi
+ ;;
+ esac
+ # This is a shared library
+
+ # Warn about portability, can't link against -module's on some
+ # systems (darwin). Don't bleat about dlopened modules though!
+ dlopenmodule=""
+ for dlpremoduletest in $dlprefiles; do
+ if test "X$dlpremoduletest" = "X$lib"; then
+ dlopenmodule="$dlpremoduletest"
+ break
+ fi
+ done
+ if test -z "$dlopenmodule" && test "$shouldnotlink" = yes && test "$pass" = link; then
+ echo
+ if test "$linkmode" = prog; then
+ $ECHO "*** Warning: Linking the executable $output against the loadable module"
+ else
+ $ECHO "*** Warning: Linking the shared library $output against the loadable module"
+ fi
+ $ECHO "*** $linklib is not portable!"
+ fi
+ if test "$linkmode" = lib &&
+ test "$hardcode_into_libs" = yes; then
+ # Hardcode the library path.
+ # Skip directories that are in the system default run-time
+ # search path.
+ case " $sys_lib_dlsearch_path " in
+ *" $absdir "*) ;;
+ *)
+ case "$compile_rpath " in
+ *" $absdir "*) ;;
+ *) func_append compile_rpath " $absdir" ;;
+ esac
+ ;;
+ esac
+ case " $sys_lib_dlsearch_path " in
+ *" $libdir "*) ;;
+ *)
+ case "$finalize_rpath " in
+ *" $libdir "*) ;;
+ *) func_append finalize_rpath " $libdir" ;;
+ esac
+ ;;
+ esac
+ fi
+
+ if test -n "$old_archive_from_expsyms_cmds"; then
+ # figure out the soname
+ set dummy $library_names
+ shift
+ realname="$1"
+ shift
+ libname=`eval "\\$ECHO \"$libname_spec\""`
+ # use dlname if we got it. it's perfectly good, no?
+ if test -n "$dlname"; then
+ soname="$dlname"
+ elif test -n "$soname_spec"; then
+ # bleh windows
+ case $host in
+ *cygwin* | mingw* | *cegcc*)
+ func_arith $current - $age
+ major=$func_arith_result
+ versuffix="-$major"
+ ;;
+ esac
+ eval soname=\"$soname_spec\"
+ else
+ soname="$realname"
+ fi
+
+ # Make a new name for the extract_expsyms_cmds to use
+ soroot="$soname"
+ func_basename "$soroot"
+ soname="$func_basename_result"
+ func_stripname 'lib' '.dll' "$soname"
+ newlib=libimp-$func_stripname_result.a
+
+ # If the library has no export list, then create one now
+ if test -f "$output_objdir/$soname-def"; then :
+ else
+ func_verbose "extracting exported symbol list from \`$soname'"
+ func_execute_cmds "$extract_expsyms_cmds" 'exit $?'
+ fi
+
+ # Create $newlib
+ if test -f "$output_objdir/$newlib"; then :; else
+ func_verbose "generating import library for \`$soname'"
+ func_execute_cmds "$old_archive_from_expsyms_cmds" 'exit $?'
+ fi
+ # make sure the library variables are pointing to the new library
+ dir=$output_objdir
+ linklib=$newlib
+ fi # test -n "$old_archive_from_expsyms_cmds"
+
+ if test "$linkmode" = prog || test "$opt_mode" != relink; then
+ add_shlibpath=
+ add_dir=
+ add=
+ lib_linked=yes
+ case $hardcode_action in
+ immediate | unsupported)
+ if test "$hardcode_direct" = no; then
+ add="$dir/$linklib"
+ case $host in
+ *-*-sco3.2v5.0.[024]*) add_dir="-L$dir" ;;
+ *-*-sysv4*uw2*) add_dir="-L$dir" ;;
+ *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \
+ *-*-unixware7*) add_dir="-L$dir" ;;
+ *-*-darwin* )
+ # if the lib is a (non-dlopened) module then we can not
+ # link against it, someone is ignoring the earlier warnings
+ if /usr/bin/file -L $add 2> /dev/null |
+ $GREP ": [^:]* bundle" >/dev/null ; then
+ if test "X$dlopenmodule" != "X$lib"; then
+ $ECHO "*** Warning: lib $linklib is a module, not a shared library"
+ if test -z "$old_library" ; then
+ echo
+ echo "*** And there doesn't seem to be a static archive available"
+ echo "*** The link will probably fail, sorry"
+ else
+ add="$dir/$old_library"
+ fi
+ elif test -n "$old_library"; then
+ add="$dir/$old_library"
+ fi
+ fi
+ esac
+ elif test "$hardcode_minus_L" = no; then
+ case $host in
+ *-*-sunos*) add_shlibpath="$dir" ;;
+ esac
+ add_dir="-L$dir"
+ add="-l$name"
+ elif test "$hardcode_shlibpath_var" = no; then
+ add_shlibpath="$dir"
+ add="-l$name"
+ else
+ lib_linked=no
+ fi
+ ;;
+ relink)
+ if test "$hardcode_direct" = yes &&
+ test "$hardcode_direct_absolute" = no; then
+ add="$dir/$linklib"
+ elif test "$hardcode_minus_L" = yes; then
+ add_dir="-L$absdir"
+ # Try looking first in the location we're being installed to.
+ if test -n "$inst_prefix_dir"; then
+ case $libdir in
+ [\\/]*)
+ func_append add_dir " -L$inst_prefix_dir$libdir"
+ ;;
+ esac
+ fi
+ add="-l$name"
+ elif test "$hardcode_shlibpath_var" = yes; then
+ add_shlibpath="$dir"
+ add="-l$name"
+ else
+ lib_linked=no
+ fi
+ ;;
+ *) lib_linked=no ;;
+ esac
+
+ if test "$lib_linked" != yes; then
+ func_fatal_configuration "unsupported hardcode properties"
+ fi
+
+ if test -n "$add_shlibpath"; then
+ case :$compile_shlibpath: in
+ *":$add_shlibpath:"*) ;;
+ *) func_append compile_shlibpath "$add_shlibpath:" ;;
+ esac
+ fi
+ if test "$linkmode" = prog; then
+ test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs"
+ test -n "$add" && compile_deplibs="$add $compile_deplibs"
+ else
+ test -n "$add_dir" && deplibs="$add_dir $deplibs"
+ test -n "$add" && deplibs="$add $deplibs"
+ if test "$hardcode_direct" != yes &&
+ test "$hardcode_minus_L" != yes &&
+ test "$hardcode_shlibpath_var" = yes; then
+ case :$finalize_shlibpath: in
+ *":$libdir:"*) ;;
+ *) func_append finalize_shlibpath "$libdir:" ;;
+ esac
+ fi
+ fi
+ fi
+
+ if test "$linkmode" = prog || test "$opt_mode" = relink; then
+ add_shlibpath=
+ add_dir=
+ add=
+ # Finalize command for both is simple: just hardcode it.
+ if test "$hardcode_direct" = yes &&
+ test "$hardcode_direct_absolute" = no; then
+ add="$libdir/$linklib"
+ elif test "$hardcode_minus_L" = yes; then
+ add_dir="-L$libdir"
+ add="-l$name"
+ elif test "$hardcode_shlibpath_var" = yes; then
+ case :$finalize_shlibpath: in
+ *":$libdir:"*) ;;
+ *) func_append finalize_shlibpath "$libdir:" ;;
+ esac
+ add="-l$name"
+ elif test "$hardcode_automatic" = yes; then
+ if test -n "$inst_prefix_dir" &&
+ test -f "$inst_prefix_dir$libdir/$linklib" ; then
+ add="$inst_prefix_dir$libdir/$linklib"
+ else
+ add="$libdir/$linklib"
+ fi
+ else
+ # We cannot seem to hardcode it, guess we'll fake it.
+ add_dir="-L$libdir"
+ # Try looking first in the location we're being installed to.
+ if test -n "$inst_prefix_dir"; then
+ case $libdir in
+ [\\/]*)
+ func_append add_dir " -L$inst_prefix_dir$libdir"
+ ;;
+ esac
+ fi
+ add="-l$name"
+ fi
+
+ if test "$linkmode" = prog; then
+ test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs"
+ test -n "$add" && finalize_deplibs="$add $finalize_deplibs"
+ else
+ test -n "$add_dir" && deplibs="$add_dir $deplibs"
+ test -n "$add" && deplibs="$add $deplibs"
+ fi
+ fi
+ elif test "$linkmode" = prog; then
+ # Here we assume that one of hardcode_direct or hardcode_minus_L
+ # is not unsupported. This is valid on all known static and
+ # shared platforms.
+ if test "$hardcode_direct" != unsupported; then
+ test -n "$old_library" && linklib="$old_library"
+ compile_deplibs="$dir/$linklib $compile_deplibs"
+ finalize_deplibs="$dir/$linklib $finalize_deplibs"
+ else
+ compile_deplibs="-l$name -L$dir $compile_deplibs"
+ finalize_deplibs="-l$name -L$dir $finalize_deplibs"
+ fi
+ elif test "$build_libtool_libs" = yes; then
+ # Not a shared library
+ if test "$deplibs_check_method" != pass_all; then
+ # We're trying link a shared library against a static one
+ # but the system doesn't support it.
+
+ # Just print a warning and add the library to dependency_libs so
+ # that the program can be linked against the static library.
+ echo
+ $ECHO "*** Warning: This system can not link to static lib archive $lib."
+ echo "*** I have the capability to make that library automatically link in when"
+ echo "*** you link to this library. But I can only do this if you have a"
+ echo "*** shared version of the library, which you do not appear to have."
+ if test "$module" = yes; then
+ echo "*** But as you try to build a module library, libtool will still create "
+ echo "*** a static module, that should work as long as the dlopening application"
+ echo "*** is linked with the -dlopen flag to resolve symbols at runtime."
+ if test -z "$global_symbol_pipe"; then
+ echo
+ echo "*** However, this would only work if libtool was able to extract symbol"
+ echo "*** lists from a program, using \`nm' or equivalent, but libtool could"
+ echo "*** not find such a program. So, this module is probably useless."
+ echo "*** \`nm' from GNU binutils and a full rebuild may help."
+ fi
+ if test "$build_old_libs" = no; then
+ build_libtool_libs=module
+ build_old_libs=yes
+ else
+ build_libtool_libs=no
+ fi
+ fi
+ else
+ deplibs="$dir/$old_library $deplibs"
+ link_static=yes
+ fi
+ fi # link shared/static library?
+
+ if test "$linkmode" = lib; then
+ if test -n "$dependency_libs" &&
+ { test "$hardcode_into_libs" != yes ||
+ test "$build_old_libs" = yes ||
+ test "$link_static" = yes; }; then
+ # Extract -R from dependency_libs
+ temp_deplibs=
+ for libdir in $dependency_libs; do
+ case $libdir in
+ -R*) func_stripname '-R' '' "$libdir"
+ temp_xrpath=$func_stripname_result
+ case " $xrpath " in
+ *" $temp_xrpath "*) ;;
+ *) func_append xrpath " $temp_xrpath";;
+ esac;;
+ *) func_append temp_deplibs " $libdir";;
+ esac
+ done
+ dependency_libs="$temp_deplibs"
+ fi
+
+ func_append newlib_search_path " $absdir"
+ # Link against this library
+ test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs"
+ # ... and its dependency_libs
+ tmp_libs=
+ for deplib in $dependency_libs; do
+ newdependency_libs="$deplib $newdependency_libs"
+ case $deplib in
+ -L*) func_stripname '-L' '' "$deplib"
+ func_resolve_sysroot "$func_stripname_result";;
+ *) func_resolve_sysroot "$deplib" ;;
+ esac
+ if $opt_preserve_dup_deps ; then
+ case "$tmp_libs " in
+ *" $func_resolve_sysroot_result "*)
+ func_append specialdeplibs " $func_resolve_sysroot_result" ;;
+ esac
+ fi
+ func_append tmp_libs " $func_resolve_sysroot_result"
+ done
+
+ if test "$link_all_deplibs" != no; then
+ # Add the search paths of all dependency libraries
+ for deplib in $dependency_libs; do
+ path=
+ case $deplib in
+ -L*) path="$deplib" ;;
+ *.la)
+ func_resolve_sysroot "$deplib"
+ deplib=$func_resolve_sysroot_result
+ func_dirname "$deplib" "" "."
+ dir=$func_dirname_result
+ # We need an absolute path.
+ case $dir in
+ [\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;;
+ *)
+ absdir=`cd "$dir" && pwd`
+ if test -z "$absdir"; then
+ func_warning "cannot determine absolute directory name of \`$dir'"
+ absdir="$dir"
+ fi
+ ;;
+ esac
+ if $GREP "^installed=no" $deplib > /dev/null; then
+ case $host in
+ *-*-darwin*)
+ depdepl=
+ eval deplibrary_names=`${SED} -n -e 's/^library_names=\(.*\)$/\1/p' $deplib`
+ if test -n "$deplibrary_names" ; then
+ for tmp in $deplibrary_names ; do
+ depdepl=$tmp
+ done
+ if test -f "$absdir/$objdir/$depdepl" ; then
+ depdepl="$absdir/$objdir/$depdepl"
+ darwin_install_name=`${OTOOL} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'`
+ if test -z "$darwin_install_name"; then
+ darwin_install_name=`${OTOOL64} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'`
+ fi
+ func_append compiler_flags " ${wl}-dylib_file ${wl}${darwin_install_name}:${depdepl}"
+ func_append linker_flags " -dylib_file ${darwin_install_name}:${depdepl}"
+ path=
+ fi
+ fi
+ ;;
+ *)
+ path="-L$absdir/$objdir"
+ ;;
+ esac
+ else
+ eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib`
+ test -z "$libdir" && \
+ func_fatal_error "\`$deplib' is not a valid libtool archive"
+ test "$absdir" != "$libdir" && \
+ func_warning "\`$deplib' seems to be moved"
+
+ path="-L$absdir"
+ fi
+ ;;
+ esac
+ case " $deplibs " in
+ *" $path "*) ;;
+ *) deplibs="$path $deplibs" ;;
+ esac
+ done
+ fi # link_all_deplibs != no
+ fi # linkmode = lib
+ done # for deplib in $libs
+ if test "$pass" = link; then
+ if test "$linkmode" = "prog"; then
+ compile_deplibs="$new_inherited_linker_flags $compile_deplibs"
+ finalize_deplibs="$new_inherited_linker_flags $finalize_deplibs"
+ else
+ compiler_flags="$compiler_flags "`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+ fi
+ fi
+ dependency_libs="$newdependency_libs"
+ if test "$pass" = dlpreopen; then
+ # Link the dlpreopened libraries before other libraries
+ for deplib in $save_deplibs; do
+ deplibs="$deplib $deplibs"
+ done
+ fi
+ if test "$pass" != dlopen; then
+ if test "$pass" != conv; then
+ # Make sure lib_search_path contains only unique directories.
+ lib_search_path=
+ for dir in $newlib_search_path; do
+ case "$lib_search_path " in
+ *" $dir "*) ;;
+ *) func_append lib_search_path " $dir" ;;
+ esac
+ done
+ newlib_search_path=
+ fi
+
+ if test "$linkmode,$pass" != "prog,link"; then
+ vars="deplibs"
+ else
+ vars="compile_deplibs finalize_deplibs"
+ fi
+ for var in $vars dependency_libs; do
+ # Add libraries to $var in reverse order
+ eval tmp_libs=\"\$$var\"
+ new_libs=
+ for deplib in $tmp_libs; do
+ # FIXME: Pedantically, this is the right thing to do, so
+ # that some nasty dependency loop isn't accidentally
+ # broken:
+ #new_libs="$deplib $new_libs"
+ # Pragmatically, this seems to cause very few problems in
+ # practice:
+ case $deplib in
+ -L*) new_libs="$deplib $new_libs" ;;
+ -R*) ;;
+ *)
+ # And here is the reason: when a library appears more
+ # than once as an explicit dependence of a library, or
+ # is implicitly linked in more than once by the
+ # compiler, it is considered special, and multiple
+ # occurrences thereof are not removed. Compare this
+ # with having the same library being listed as a
+ # dependency of multiple other libraries: in this case,
+ # we know (pedantically, we assume) the library does not
+ # need to be listed more than once, so we keep only the
+ # last copy. This is not always right, but it is rare
+ # enough that we require users that really mean to play
+ # such unportable linking tricks to link the library
+ # using -Wl,-lname, so that libtool does not consider it
+ # for duplicate removal.
+ case " $specialdeplibs " in
+ *" $deplib "*) new_libs="$deplib $new_libs" ;;
+ *)
+ case " $new_libs " in
+ *" $deplib "*) ;;
+ *) new_libs="$deplib $new_libs" ;;
+ esac
+ ;;
+ esac
+ ;;
+ esac
+ done
+ tmp_libs=
+ for deplib in $new_libs; do
+ case $deplib in
+ -L*)
+ case " $tmp_libs " in
+ *" $deplib "*) ;;
+ *) func_append tmp_libs " $deplib" ;;
+ esac
+ ;;
+ *) func_append tmp_libs " $deplib" ;;
+ esac
+ done
+ eval $var=\"$tmp_libs\"
+ done # for var
+ fi
+ # Last step: remove runtime libs from dependency_libs
+ # (they stay in deplibs)
+ tmp_libs=
+ for i in $dependency_libs ; do
+ case " $predeps $postdeps $compiler_lib_search_path " in
+ *" $i "*)
+ i=""
+ ;;
+ esac
+ if test -n "$i" ; then
+ func_append tmp_libs " $i"
+ fi
+ done
+ dependency_libs=$tmp_libs
+ done # for pass
+ if test "$linkmode" = prog; then
+ dlfiles="$newdlfiles"
+ fi
+ if test "$linkmode" = prog || test "$linkmode" = lib; then
+ dlprefiles="$newdlprefiles"
+ fi
+
+ case $linkmode in
+ oldlib)
+ if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+ func_warning "\`-dlopen' is ignored for archives"
+ fi
+
+ case " $deplibs" in
+ *\ -l* | *\ -L*)
+ func_warning "\`-l' and \`-L' are ignored for archives" ;;
+ esac
+
+ test -n "$rpath" && \
+ func_warning "\`-rpath' is ignored for archives"
+
+ test -n "$xrpath" && \
+ func_warning "\`-R' is ignored for archives"
+
+ test -n "$vinfo" && \
+ func_warning "\`-version-info/-version-number' is ignored for archives"
+
+ test -n "$release" && \
+ func_warning "\`-release' is ignored for archives"
+
+ test -n "$export_symbols$export_symbols_regex" && \
+ func_warning "\`-export-symbols' is ignored for archives"
+
+ # Now set the variables for building old libraries.
+ build_libtool_libs=no
+ oldlibs="$output"
+ func_append objs "$old_deplibs"
+ ;;
+
+ lib)
+ # Make sure we only generate libraries of the form `libNAME.la'.
+ case $outputname in
+ lib*)
+ func_stripname 'lib' '.la' "$outputname"
+ name=$func_stripname_result
+ eval shared_ext=\"$shrext_cmds\"
+ eval libname=\"$libname_spec\"
+ ;;
+ *)
+ test "$module" = no && \
+ func_fatal_help "libtool library \`$output' must begin with \`lib'"
+
+ if test "$need_lib_prefix" != no; then
+ # Add the "lib" prefix for modules if required
+ func_stripname '' '.la' "$outputname"
+ name=$func_stripname_result
+ eval shared_ext=\"$shrext_cmds\"
+ eval libname=\"$libname_spec\"
+ else
+ func_stripname '' '.la' "$outputname"
+ libname=$func_stripname_result
+ fi
+ ;;
+ esac
+
+ if test -n "$objs"; then
+ if test "$deplibs_check_method" != pass_all; then
+ func_fatal_error "cannot build libtool library \`$output' from non-libtool objects on this host:$objs"
+ else
+ echo
+ $ECHO "*** Warning: Linking the shared library $output against the non-libtool"
+ $ECHO "*** objects $objs is not portable!"
+ func_append libobjs " $objs"
+ fi
+ fi
+
+ test "$dlself" != no && \
+ func_warning "\`-dlopen self' is ignored for libtool libraries"
+
+ set dummy $rpath
+ shift
+ test "$#" -gt 1 && \
+ func_warning "ignoring multiple \`-rpath's for a libtool library"
+
+ install_libdir="$1"
+
+ oldlibs=
+ if test -z "$rpath"; then
+ if test "$build_libtool_libs" = yes; then
+ # Building a libtool convenience library.
+ # Some compilers have problems with a `.al' extension so
+ # convenience libraries should have the same extension an
+ # archive normally would.
+ oldlibs="$output_objdir/$libname.$libext $oldlibs"
+ build_libtool_libs=convenience
+ build_old_libs=yes
+ fi
+
+ test -n "$vinfo" && \
+ func_warning "\`-version-info/-version-number' is ignored for convenience libraries"
+
+ test -n "$release" && \
+ func_warning "\`-release' is ignored for convenience libraries"
+ else
+
+ # Parse the version information argument.
+ save_ifs="$IFS"; IFS=':'
+ set dummy $vinfo 0 0 0
+ shift
+ IFS="$save_ifs"
+
+ test -n "$7" && \
+ func_fatal_help "too many parameters to \`-version-info'"
+
+ # convert absolute version numbers to libtool ages
+ # this retains compatibility with .la files and attempts
+ # to make the code below a bit more comprehensible
+
+ case $vinfo_number in
+ yes)
+ number_major="$1"
+ number_minor="$2"
+ number_revision="$3"
+ #
+ # There are really only two kinds -- those that
+ # use the current revision as the major version
+ # and those that subtract age and use age as
+ # a minor version. But, then there is irix
+ # which has an extra 1 added just for fun
+ #
+ case $version_type in
+ # correct linux to gnu/linux during the next big refactor
+ darwin|linux|osf|windows|none)
+ func_arith $number_major + $number_minor
+ current=$func_arith_result
+ age="$number_minor"
+ revision="$number_revision"
+ ;;
+ freebsd-aout|freebsd-elf|qnx|sunos)
+ current="$number_major"
+ revision="$number_minor"
+ age="0"
+ ;;
+ irix|nonstopux)
+ func_arith $number_major + $number_minor
+ current=$func_arith_result
+ age="$number_minor"
+ revision="$number_minor"
+ lt_irix_increment=no
+ ;;
+ esac
+ ;;
+ no)
+ current="$1"
+ revision="$2"
+ age="$3"
+ ;;
+ esac
+
+ # Check that each of the things are valid numbers.
+ case $current in
+ 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
+ *)
+ func_error "CURRENT \`$current' must be a nonnegative integer"
+ func_fatal_error "\`$vinfo' is not valid version information"
+ ;;
+ esac
+
+ case $revision in
+ 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
+ *)
+ func_error "REVISION \`$revision' must be a nonnegative integer"
+ func_fatal_error "\`$vinfo' is not valid version information"
+ ;;
+ esac
+
+ case $age in
+ 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
+ *)
+ func_error "AGE \`$age' must be a nonnegative integer"
+ func_fatal_error "\`$vinfo' is not valid version information"
+ ;;
+ esac
+
+ if test "$age" -gt "$current"; then
+ func_error "AGE \`$age' is greater than the current interface number \`$current'"
+ func_fatal_error "\`$vinfo' is not valid version information"
+ fi
+
+ # Calculate the version variables.
+ major=
+ versuffix=
+ verstring=
+ case $version_type in
+ none) ;;
+
+ darwin)
+ # Like Linux, but with the current version available in
+ # verstring for coding it into the library header
+ func_arith $current - $age
+ major=.$func_arith_result
+ versuffix="$major.$age.$revision"
+ # Darwin ld doesn't like 0 for these options...
+ func_arith $current + 1
+ minor_current=$func_arith_result
+ xlcverstring="${wl}-compatibility_version ${wl}$minor_current ${wl}-current_version ${wl}$minor_current.$revision"
+ verstring="-compatibility_version $minor_current -current_version $minor_current.$revision"
+ ;;
+
+ freebsd-aout)
+ major=".$current"
+ versuffix=".$current.$revision";
+ ;;
+
+ freebsd-elf)
+ major=".$current"
+ versuffix=".$current"
+ ;;
+
+ irix | nonstopux)
+ if test "X$lt_irix_increment" = "Xno"; then
+ func_arith $current - $age
+ else
+ func_arith $current - $age + 1
+ fi
+ major=$func_arith_result
+
+ case $version_type in
+ nonstopux) verstring_prefix=nonstopux ;;
+ *) verstring_prefix=sgi ;;
+ esac
+ verstring="$verstring_prefix$major.$revision"
+
+ # Add in all the interfaces that we are compatible with.
+ loop=$revision
+ while test "$loop" -ne 0; do
+ func_arith $revision - $loop
+ iface=$func_arith_result
+ func_arith $loop - 1
+ loop=$func_arith_result
+ verstring="$verstring_prefix$major.$iface:$verstring"
+ done
+
+ # Before this point, $major must not contain `.'.
+ major=.$major
+ versuffix="$major.$revision"
+ ;;
+
+ linux) # correct to gnu/linux during the next big refactor
+ func_arith $current - $age
+ major=.$func_arith_result
+ versuffix="$major.$age.$revision"
+ ;;
+
+ osf)
+ func_arith $current - $age
+ major=.$func_arith_result
+ versuffix=".$current.$age.$revision"
+ verstring="$current.$age.$revision"
+
+ # Add in all the interfaces that we are compatible with.
+ loop=$age
+ while test "$loop" -ne 0; do
+ func_arith $current - $loop
+ iface=$func_arith_result
+ func_arith $loop - 1
+ loop=$func_arith_result
+ verstring="$verstring:${iface}.0"
+ done
+
+ # Make executables depend on our current version.
+ func_append verstring ":${current}.0"
+ ;;
+
+ qnx)
+ major=".$current"
+ versuffix=".$current"
+ ;;
+
+ sunos)
+ major=".$current"
+ versuffix=".$current.$revision"
+ ;;
+
+ windows)
+ # Use '-' rather than '.', since we only want one
+ # extension on DOS 8.3 filesystems.
+ func_arith $current - $age
+ major=$func_arith_result
+ versuffix="-$major"
+ ;;
+
+ *)
+ func_fatal_configuration "unknown library version type \`$version_type'"
+ ;;
+ esac
+
+ # Clear the version info if we defaulted, and they specified a release.
+ if test -z "$vinfo" && test -n "$release"; then
+ major=
+ case $version_type in
+ darwin)
+ # we can't check for "0.0" in archive_cmds due to quoting
+ # problems, so we reset it completely
+ verstring=
+ ;;
+ *)
+ verstring="0.0"
+ ;;
+ esac
+ if test "$need_version" = no; then
+ versuffix=
+ else
+ versuffix=".0.0"
+ fi
+ fi
+
+ # Remove version info from name if versioning should be avoided
+ if test "$avoid_version" = yes && test "$need_version" = no; then
+ major=
+ versuffix=
+ verstring=""
+ fi
+
+ # Check to see if the archive will have undefined symbols.
+ if test "$allow_undefined" = yes; then
+ if test "$allow_undefined_flag" = unsupported; then
+ func_warning "undefined symbols not allowed in $host shared libraries"
+ build_libtool_libs=no
+ build_old_libs=yes
+ fi
+ else
+ # Don't allow undefined symbols.
+ allow_undefined_flag="$no_undefined_flag"
+ fi
+
+ fi
+
+ func_generate_dlsyms "$libname" "$libname" "yes"
+ func_append libobjs " $symfileobj"
+ test "X$libobjs" = "X " && libobjs=
+
+ if test "$opt_mode" != relink; then
+ # Remove our outputs, but don't remove object files since they
+ # may have been created when compiling PIC objects.
+ removelist=
+ tempremovelist=`$ECHO "$output_objdir/*"`
+ for p in $tempremovelist; do
+ case $p in
+ *.$objext | *.gcno)
+ ;;
+ $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*)
+ if test "X$precious_files_regex" != "X"; then
+ if $ECHO "$p" | $EGREP -e "$precious_files_regex" >/dev/null 2>&1
+ then
+ continue
+ fi
+ fi
+ func_append removelist " $p"
+ ;;
+ *) ;;
+ esac
+ done
+ test -n "$removelist" && \
+ func_show_eval "${RM}r \$removelist"
+ fi
+
+ # Now set the variables for building old libraries.
+ if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then
+ func_append oldlibs " $output_objdir/$libname.$libext"
+
+ # Transform .lo files to .o files.
+ oldobjs="$objs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.${libext}$/d; $lo2o" | $NL2SP`
+ fi
+
+ # Eliminate all temporary directories.
+ #for path in $notinst_path; do
+ # lib_search_path=`$ECHO "$lib_search_path " | $SED "s% $path % %g"`
+ # deplibs=`$ECHO "$deplibs " | $SED "s% -L$path % %g"`
+ # dependency_libs=`$ECHO "$dependency_libs " | $SED "s% -L$path % %g"`
+ #done
+
+ if test -n "$xrpath"; then
+ # If the user specified any rpath flags, then add them.
+ temp_xrpath=
+ for libdir in $xrpath; do
+ func_replace_sysroot "$libdir"
+ func_append temp_xrpath " -R$func_replace_sysroot_result"
+ case "$finalize_rpath " in
+ *" $libdir "*) ;;
+ *) func_append finalize_rpath " $libdir" ;;
+ esac
+ done
+ if test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes; then
+ dependency_libs="$temp_xrpath $dependency_libs"
+ fi
+ fi
+
+ # Make sure dlfiles contains only unique files that won't be dlpreopened
+ old_dlfiles="$dlfiles"
+ dlfiles=
+ for lib in $old_dlfiles; do
+ case " $dlprefiles $dlfiles " in
+ *" $lib "*) ;;
+ *) func_append dlfiles " $lib" ;;
+ esac
+ done
+
+ # Make sure dlprefiles contains only unique files
+ old_dlprefiles="$dlprefiles"
+ dlprefiles=
+ for lib in $old_dlprefiles; do
+ case "$dlprefiles " in
+ *" $lib "*) ;;
+ *) func_append dlprefiles " $lib" ;;
+ esac
+ done
+
+ if test "$build_libtool_libs" = yes; then
+ if test -n "$rpath"; then
+ case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc* | *-*-haiku*)
+ # these systems don't actually have a c library (as such)!
+ ;;
+ *-*-rhapsody* | *-*-darwin1.[012])
+ # Rhapsody C library is in the System framework
+ func_append deplibs " System.ltframework"
+ ;;
+ *-*-netbsd*)
+ # Don't link with libc until the a.out ld.so is fixed.
+ ;;
+ *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)
+ # Do not include libc due to us having libc/libc_r.
+ ;;
+ *-*-sco3.2v5* | *-*-sco5v6*)
+ # Causes problems with __ctype
+ ;;
+ *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*)
+ # Compiler inserts libc in the correct place for threads to work
+ ;;
+ *)
+ # Add libc to deplibs on all other systems if necessary.
+ if test "$build_libtool_need_lc" = "yes"; then
+ func_append deplibs " -lc"
+ fi
+ ;;
+ esac
+ fi
+
+ # Transform deplibs into only deplibs that can be linked in shared.
+ name_save=$name
+ libname_save=$libname
+ release_save=$release
+ versuffix_save=$versuffix
+ major_save=$major
+ # I'm not sure if I'm treating the release correctly. I think
+ # release should show up in the -l (ie -lgmp5) so we don't want to
+ # add it in twice. Is that correct?
+ release=""
+ versuffix=""
+ major=""
+ newdeplibs=
+ droppeddeps=no
+ case $deplibs_check_method in
+ pass_all)
+ # Don't check for shared/static. Everything works.
+ # This might be a little naive. We might want to check
+ # whether the library exists or not. But this is on
+ # osf3 & osf4 and I'm not really sure... Just
+ # implementing what was already the behavior.
+ newdeplibs=$deplibs
+ ;;
+ test_compile)
+ # This code stresses the "libraries are programs" paradigm to its
+ # limits. Maybe even breaks it. We compile a program, linking it
+ # against the deplibs as a proxy for the library. Then we can check
+ # whether they linked in statically or dynamically with ldd.
+ $opt_dry_run || $RM conftest.c
+ cat > conftest.c <<EOF
+ int main() { return 0; }
+EOF
+ $opt_dry_run || $RM conftest
+ if $LTCC $LTCFLAGS -o conftest conftest.c $deplibs; then
+ ldd_output=`ldd conftest`
+ for i in $deplibs; do
+ case $i in
+ -l*)
+ func_stripname -l '' "$i"
+ name=$func_stripname_result
+ if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+ case " $predeps $postdeps " in
+ *" $i "*)
+ func_append newdeplibs " $i"
+ i=""
+ ;;
+ esac
+ fi
+ if test -n "$i" ; then
+ libname=`eval "\\$ECHO \"$libname_spec\""`
+ deplib_matches=`eval "\\$ECHO \"$library_names_spec\""`
+ set dummy $deplib_matches; shift
+ deplib_match=$1
+ if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then
+ func_append newdeplibs " $i"
+ else
+ droppeddeps=yes
+ echo
+ $ECHO "*** Warning: dynamic linker does not accept needed library $i."
+ echo "*** I have the capability to make that library automatically link in when"
+ echo "*** you link to this library. But I can only do this if you have a"
+ echo "*** shared version of the library, which I believe you do not have"
+ echo "*** because a test_compile did reveal that the linker did not use it for"
+ echo "*** its dynamic dependency list that programs get resolved with at runtime."
+ fi
+ fi
+ ;;
+ *)
+ func_append newdeplibs " $i"
+ ;;
+ esac
+ done
+ else
+ # Error occurred in the first compile. Let's try to salvage
+ # the situation: Compile a separate program for each library.
+ for i in $deplibs; do
+ case $i in
+ -l*)
+ func_stripname -l '' "$i"
+ name=$func_stripname_result
+ $opt_dry_run || $RM conftest
+ if $LTCC $LTCFLAGS -o conftest conftest.c $i; then
+ ldd_output=`ldd conftest`
+ if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+ case " $predeps $postdeps " in
+ *" $i "*)
+ func_append newdeplibs " $i"
+ i=""
+ ;;
+ esac
+ fi
+ if test -n "$i" ; then
+ libname=`eval "\\$ECHO \"$libname_spec\""`
+ deplib_matches=`eval "\\$ECHO \"$library_names_spec\""`
+ set dummy $deplib_matches; shift
+ deplib_match=$1
+ if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then
+ func_append newdeplibs " $i"
+ else
+ droppeddeps=yes
+ echo
+ $ECHO "*** Warning: dynamic linker does not accept needed library $i."
+ echo "*** I have the capability to make that library automatically link in when"
+ echo "*** you link to this library. But I can only do this if you have a"
+ echo "*** shared version of the library, which you do not appear to have"
+ echo "*** because a test_compile did reveal that the linker did not use this one"
+ echo "*** as a dynamic dependency that programs can get resolved with at runtime."
+ fi
+ fi
+ else
+ droppeddeps=yes
+ echo
+ $ECHO "*** Warning! Library $i is needed by this library but I was not able to"
+ echo "*** make it link in! You will probably need to install it or some"
+ echo "*** library that it depends on before this library will be fully"
+ echo "*** functional. Installing it before continuing would be even better."
+ fi
+ ;;
+ *)
+ func_append newdeplibs " $i"
+ ;;
+ esac
+ done
+ fi
+ ;;
+ file_magic*)
+ set dummy $deplibs_check_method; shift
+ file_magic_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"`
+ for a_deplib in $deplibs; do
+ case $a_deplib in
+ -l*)
+ func_stripname -l '' "$a_deplib"
+ name=$func_stripname_result
+ if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+ case " $predeps $postdeps " in
+ *" $a_deplib "*)
+ func_append newdeplibs " $a_deplib"
+ a_deplib=""
+ ;;
+ esac
+ fi
+ if test -n "$a_deplib" ; then
+ libname=`eval "\\$ECHO \"$libname_spec\""`
+ if test -n "$file_magic_glob"; then
+ libnameglob=`func_echo_all "$libname" | $SED -e $file_magic_glob`
+ else
+ libnameglob=$libname
+ fi
+ test "$want_nocaseglob" = yes && nocaseglob=`shopt -p nocaseglob`
+ for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do
+ if test "$want_nocaseglob" = yes; then
+ shopt -s nocaseglob
+ potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null`
+ $nocaseglob
+ else
+ potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null`
+ fi
+ for potent_lib in $potential_libs; do
+ # Follow soft links.
+ if ls -lLd "$potent_lib" 2>/dev/null |
+ $GREP " -> " >/dev/null; then
+ continue
+ fi
+ # The statement above tries to avoid entering an
+ # endless loop below, in case of cyclic links.
+ # We might still enter an endless loop, since a link
+ # loop can be closed while we follow links,
+ # but so what?
+ potlib="$potent_lib"
+ while test -h "$potlib" 2>/dev/null; do
+ potliblink=`ls -ld $potlib | ${SED} 's/.* -> //'`
+ case $potliblink in
+ [\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";;
+ *) potlib=`$ECHO "$potlib" | $SED 's,[^/]*$,,'`"$potliblink";;
+ esac
+ done
+ if eval $file_magic_cmd \"\$potlib\" 2>/dev/null |
+ $SED -e 10q |
+ $EGREP "$file_magic_regex" > /dev/null; then
+ func_append newdeplibs " $a_deplib"
+ a_deplib=""
+ break 2
+ fi
+ done
+ done
+ fi
+ if test -n "$a_deplib" ; then
+ droppeddeps=yes
+ echo
+ $ECHO "*** Warning: linker path does not have real file for library $a_deplib."
+ echo "*** I have the capability to make that library automatically link in when"
+ echo "*** you link to this library. But I can only do this if you have a"
+ echo "*** shared version of the library, which you do not appear to have"
+ echo "*** because I did check the linker path looking for a file starting"
+ if test -z "$potlib" ; then
+ $ECHO "*** with $libname but no candidates were found. (...for file magic test)"
+ else
+ $ECHO "*** with $libname and none of the candidates passed a file format test"
+ $ECHO "*** using a file magic. Last file checked: $potlib"
+ fi
+ fi
+ ;;
+ *)
+ # Add a -L argument.
+ func_append newdeplibs " $a_deplib"
+ ;;
+ esac
+ done # Gone through all deplibs.
+ ;;
+ match_pattern*)
+ set dummy $deplibs_check_method; shift
+ match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"`
+ for a_deplib in $deplibs; do
+ case $a_deplib in
+ -l*)
+ func_stripname -l '' "$a_deplib"
+ name=$func_stripname_result
+ if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+ case " $predeps $postdeps " in
+ *" $a_deplib "*)
+ func_append newdeplibs " $a_deplib"
+ a_deplib=""
+ ;;
+ esac
+ fi
+ if test -n "$a_deplib" ; then
+ libname=`eval "\\$ECHO \"$libname_spec\""`
+ for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do
+ potential_libs=`ls $i/$libname[.-]* 2>/dev/null`
+ for potent_lib in $potential_libs; do
+ potlib="$potent_lib" # see symlink-check above in file_magic test
+ if eval "\$ECHO \"$potent_lib\"" 2>/dev/null | $SED 10q | \
+ $EGREP "$match_pattern_regex" > /dev/null; then
+ func_append newdeplibs " $a_deplib"
+ a_deplib=""
+ break 2
+ fi
+ done
+ done
+ fi
+ if test -n "$a_deplib" ; then
+ droppeddeps=yes
+ echo
+ $ECHO "*** Warning: linker path does not have real file for library $a_deplib."
+ echo "*** I have the capability to make that library automatically link in when"
+ echo "*** you link to this library. But I can only do this if you have a"
+ echo "*** shared version of the library, which you do not appear to have"
+ echo "*** because I did check the linker path looking for a file starting"
+ if test -z "$potlib" ; then
+ $ECHO "*** with $libname but no candidates were found. (...for regex pattern test)"
+ else
+ $ECHO "*** with $libname and none of the candidates passed a file format test"
+ $ECHO "*** using a regex pattern. Last file checked: $potlib"
+ fi
+ fi
+ ;;
+ *)
+ # Add a -L argument.
+ func_append newdeplibs " $a_deplib"
+ ;;
+ esac
+ done # Gone through all deplibs.
+ ;;
+ none | unknown | *)
+ newdeplibs=""
+ tmp_deplibs=`$ECHO " $deplibs" | $SED 's/ -lc$//; s/ -[LR][^ ]*//g'`
+ if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+ for i in $predeps $postdeps ; do
+ # can't use Xsed below, because $i might contain '/'
+ tmp_deplibs=`$ECHO " $tmp_deplibs" | $SED "s,$i,,"`
+ done
+ fi
+ case $tmp_deplibs in
+ *[!\ \ ]*)
+ echo
+ if test "X$deplibs_check_method" = "Xnone"; then
+ echo "*** Warning: inter-library dependencies are not supported in this platform."
+ else
+ echo "*** Warning: inter-library dependencies are not known to be supported."
+ fi
+ echo "*** All declared inter-library dependencies are being dropped."
+ droppeddeps=yes
+ ;;
+ esac
+ ;;
+ esac
+ versuffix=$versuffix_save
+ major=$major_save
+ release=$release_save
+ libname=$libname_save
+ name=$name_save
+
+ case $host in
+ *-*-rhapsody* | *-*-darwin1.[012])
+ # On Rhapsody replace the C library with the System framework
+ newdeplibs=`$ECHO " $newdeplibs" | $SED 's/ -lc / System.ltframework /'`
+ ;;
+ esac
+
+ if test "$droppeddeps" = yes; then
+ if test "$module" = yes; then
+ echo
+ echo "*** Warning: libtool could not satisfy all declared inter-library"
+ $ECHO "*** dependencies of module $libname. Therefore, libtool will create"
+ echo "*** a static module, that should work as long as the dlopening"
+ echo "*** application is linked with the -dlopen flag."
+ if test -z "$global_symbol_pipe"; then
+ echo
+ echo "*** However, this would only work if libtool was able to extract symbol"
+ echo "*** lists from a program, using \`nm' or equivalent, but libtool could"
+ echo "*** not find such a program. So, this module is probably useless."
+ echo "*** \`nm' from GNU binutils and a full rebuild may help."
+ fi
+ if test "$build_old_libs" = no; then
+ oldlibs="$output_objdir/$libname.$libext"
+ build_libtool_libs=module
+ build_old_libs=yes
+ else
+ build_libtool_libs=no
+ fi
+ else
+ echo "*** The inter-library dependencies that have been dropped here will be"
+ echo "*** automatically added whenever a program is linked with this library"
+ echo "*** or is declared to -dlopen it."
+
+ if test "$allow_undefined" = no; then
+ echo
+ echo "*** Since this library must not contain undefined symbols,"
+ echo "*** because either the platform does not support them or"
+ echo "*** it was explicitly requested with -no-undefined,"
+ echo "*** libtool will only create a static version of it."
+ if test "$build_old_libs" = no; then
+ oldlibs="$output_objdir/$libname.$libext"
+ build_libtool_libs=module
+ build_old_libs=yes
+ else
+ build_libtool_libs=no
+ fi
+ fi
+ fi
+ fi
+ # Done checking deplibs!
+ deplibs=$newdeplibs
+ fi
+ # Time to change all our "foo.ltframework" stuff back to "-framework foo"
+ case $host in
+ *-*-darwin*)
+ newdeplibs=`$ECHO " $newdeplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+ new_inherited_linker_flags=`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+ deplibs=`$ECHO " $deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+ ;;
+ esac
+
+ # move library search paths that coincide with paths to not yet
+ # installed libraries to the beginning of the library search list
+ new_libs=
+ for path in $notinst_path; do
+ case " $new_libs " in
+ *" -L$path/$objdir "*) ;;
+ *)
+ case " $deplibs " in
+ *" -L$path/$objdir "*)
+ func_append new_libs " -L$path/$objdir" ;;
+ esac
+ ;;
+ esac
+ done
+ for deplib in $deplibs; do
+ case $deplib in
+ -L*)
+ case " $new_libs " in
+ *" $deplib "*) ;;
+ *) func_append new_libs " $deplib" ;;
+ esac
+ ;;
+ *) func_append new_libs " $deplib" ;;
+ esac
+ done
+ deplibs="$new_libs"
+
+ # All the library-specific variables (install_libdir is set above).
+ library_names=
+ old_library=
+ dlname=
+
+ # Test again, we may have decided not to build it any more
+ if test "$build_libtool_libs" = yes; then
+ # Remove ${wl} instances when linking with ld.
+ # FIXME: should test the right _cmds variable.
+ case $archive_cmds in
+ *\$LD\ *) wl= ;;
+ esac
+ if test "$hardcode_into_libs" = yes; then
+ # Hardcode the library paths
+ hardcode_libdirs=
+ dep_rpath=
+ rpath="$finalize_rpath"
+ test "$opt_mode" != relink && rpath="$compile_rpath$rpath"
+ for libdir in $rpath; do
+ if test -n "$hardcode_libdir_flag_spec"; then
+ if test -n "$hardcode_libdir_separator"; then
+ func_replace_sysroot "$libdir"
+ libdir=$func_replace_sysroot_result
+ if test -z "$hardcode_libdirs"; then
+ hardcode_libdirs="$libdir"
+ else
+ # Just accumulate the unique libdirs.
+ case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
+ *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+ ;;
+ *)
+ func_append hardcode_libdirs "$hardcode_libdir_separator$libdir"
+ ;;
+ esac
+ fi
+ else
+ eval flag=\"$hardcode_libdir_flag_spec\"
+ func_append dep_rpath " $flag"
+ fi
+ elif test -n "$runpath_var"; then
+ case "$perm_rpath " in
+ *" $libdir "*) ;;
+ *) func_append perm_rpath " $libdir" ;;
+ esac
+ fi
+ done
+ # Substitute the hardcoded libdirs into the rpath.
+ if test -n "$hardcode_libdir_separator" &&
+ test -n "$hardcode_libdirs"; then
+ libdir="$hardcode_libdirs"
+ eval "dep_rpath=\"$hardcode_libdir_flag_spec\""
+ fi
+ if test -n "$runpath_var" && test -n "$perm_rpath"; then
+ # We should set the runpath_var.
+ rpath=
+ for dir in $perm_rpath; do
+ func_append rpath "$dir:"
+ done
+ eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var"
+ fi
+ test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs"
+ fi
+
+ shlibpath="$finalize_shlibpath"
+ test "$opt_mode" != relink && shlibpath="$compile_shlibpath$shlibpath"
+ if test -n "$shlibpath"; then
+ eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var"
+ fi
+
+ # Get the real and link names of the library.
+ eval shared_ext=\"$shrext_cmds\"
+ eval library_names=\"$library_names_spec\"
+ set dummy $library_names
+ shift
+ realname="$1"
+ shift
+
+ if test -n "$soname_spec"; then
+ eval soname=\"$soname_spec\"
+ else
+ soname="$realname"
+ fi
+ if test -z "$dlname"; then
+ dlname=$soname
+ fi
+
+ lib="$output_objdir/$realname"
+ linknames=
+ for link
+ do
+ func_append linknames " $link"
+ done
+
+ # Use standard objects if they are pic
+ test -z "$pic_flag" && libobjs=`$ECHO "$libobjs" | $SP2NL | $SED "$lo2o" | $NL2SP`
+ test "X$libobjs" = "X " && libobjs=
+
+ delfiles=
+ if test -n "$export_symbols" && test -n "$include_expsyms"; then
+ $opt_dry_run || cp "$export_symbols" "$output_objdir/$libname.uexp"
+ export_symbols="$output_objdir/$libname.uexp"
+ func_append delfiles " $export_symbols"
+ fi
+
+ orig_export_symbols=
+ case $host_os in
+ cygwin* | mingw* | cegcc*)
+ if test -n "$export_symbols" && test -z "$export_symbols_regex"; then
+ # exporting using user supplied symfile
+ if test "x`$SED 1q $export_symbols`" != xEXPORTS; then
+ # and it's NOT already a .def file. Must figure out
+ # which of the given symbols are data symbols and tag
+ # them as such. So, trigger use of export_symbols_cmds.
+ # export_symbols gets reassigned inside the "prepare
+ # the list of exported symbols" if statement, so the
+ # include_expsyms logic still works.
+ orig_export_symbols="$export_symbols"
+ export_symbols=
+ always_export_symbols=yes
+ fi
+ fi
+ ;;
+ esac
+
+ # Prepare the list of exported symbols
+ if test -z "$export_symbols"; then
+ if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then
+ func_verbose "generating symbol list for \`$libname.la'"
+ export_symbols="$output_objdir/$libname.exp"
+ $opt_dry_run || $RM $export_symbols
+ cmds=$export_symbols_cmds
+ save_ifs="$IFS"; IFS='~'
+ for cmd1 in $cmds; do
+ IFS="$save_ifs"
+ # Take the normal branch if the nm_file_list_spec branch
+ # doesn't work or if tool conversion is not needed.
+ case $nm_file_list_spec~$to_tool_file_cmd in
+ *~func_convert_file_noop | *~func_convert_file_msys_to_w32 | ~*)
+ try_normal_branch=yes
+ eval cmd=\"$cmd1\"
+ func_len " $cmd"
+ len=$func_len_result
+ ;;
+ *)
+ try_normal_branch=no
+ ;;
+ esac
+ if test "$try_normal_branch" = yes \
+ && { test "$len" -lt "$max_cmd_len" \
+ || test "$max_cmd_len" -le -1; }
+ then
+ func_show_eval "$cmd" 'exit $?'
+ skipped_export=false
+ elif test -n "$nm_file_list_spec"; then
+ func_basename "$output"
+ output_la=$func_basename_result
+ save_libobjs=$libobjs
+ save_output=$output
+ output=${output_objdir}/${output_la}.nm
+ func_to_tool_file "$output"
+ libobjs=$nm_file_list_spec$func_to_tool_file_result
+ func_append delfiles " $output"
+ func_verbose "creating $NM input file list: $output"
+ for obj in $save_libobjs; do
+ func_to_tool_file "$obj"
+ $ECHO "$func_to_tool_file_result"
+ done > "$output"
+ eval cmd=\"$cmd1\"
+ func_show_eval "$cmd" 'exit $?'
+ output=$save_output
+ libobjs=$save_libobjs
+ skipped_export=false
+ else
+ # The command line is too long to execute in one step.
+ func_verbose "using reloadable object file for export list..."
+ skipped_export=:
+ # Break out early, otherwise skipped_export may be
+ # set to false by a later but shorter cmd.
+ break
+ fi
+ done
+ IFS="$save_ifs"
+ if test -n "$export_symbols_regex" && test "X$skipped_export" != "X:"; then
+ func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"'
+ func_show_eval '$MV "${export_symbols}T" "$export_symbols"'
+ fi
+ fi
+ fi
+
+ if test -n "$export_symbols" && test -n "$include_expsyms"; then
+ tmp_export_symbols="$export_symbols"
+ test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols"
+ $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"'
+ fi
+
+ if test "X$skipped_export" != "X:" && test -n "$orig_export_symbols"; then
+ # The given exports_symbols file has to be filtered, so filter it.
+ func_verbose "filter symbol list for \`$libname.la' to tag DATA exports"
+ # FIXME: $output_objdir/$libname.filter potentially contains lots of
+ # 's' commands which not all seds can handle. GNU sed should be fine
+ # though. Also, the filter scales superlinearly with the number of
+ # global variables. join(1) would be nice here, but unfortunately
+ # isn't a blessed tool.
+ $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter
+ func_append delfiles " $export_symbols $output_objdir/$libname.filter"
+ export_symbols=$output_objdir/$libname.def
+ $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols
+ fi
+
+ tmp_deplibs=
+ for test_deplib in $deplibs; do
+ case " $convenience " in
+ *" $test_deplib "*) ;;
+ *)
+ func_append tmp_deplibs " $test_deplib"
+ ;;
+ esac
+ done
+ deplibs="$tmp_deplibs"
+
+ if test -n "$convenience"; then
+ if test -n "$whole_archive_flag_spec" &&
+ test "$compiler_needs_object" = yes &&
+ test -z "$libobjs"; then
+ # extract the archives, so we have objects to list.
+ # TODO: could optimize this to just extract one archive.
+ whole_archive_flag_spec=
+ fi
+ if test -n "$whole_archive_flag_spec"; then
+ save_libobjs=$libobjs
+ eval libobjs=\"\$libobjs $whole_archive_flag_spec\"
+ test "X$libobjs" = "X " && libobjs=
+ else
+ gentop="$output_objdir/${outputname}x"
+ func_append generated " $gentop"
+
+ func_extract_archives $gentop $convenience
+ func_append libobjs " $func_extract_archives_result"
+ test "X$libobjs" = "X " && libobjs=
+ fi
+ fi
+
+ if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then
+ eval flag=\"$thread_safe_flag_spec\"
+ func_append linker_flags " $flag"
+ fi
+
+ # Make a backup of the uninstalled library when relinking
+ if test "$opt_mode" = relink; then
+ $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U)' || exit $?
+ fi
+
+ # Do each of the archive commands.
+ if test "$module" = yes && test -n "$module_cmds" ; then
+ if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then
+ eval test_cmds=\"$module_expsym_cmds\"
+ cmds=$module_expsym_cmds
+ else
+ eval test_cmds=\"$module_cmds\"
+ cmds=$module_cmds
+ fi
+ else
+ if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then
+ eval test_cmds=\"$archive_expsym_cmds\"
+ cmds=$archive_expsym_cmds
+ else
+ eval test_cmds=\"$archive_cmds\"
+ cmds=$archive_cmds
+ fi
+ fi
+
+ if test "X$skipped_export" != "X:" &&
+ func_len " $test_cmds" &&
+ len=$func_len_result &&
+ test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then
+ :
+ else
+ # The command line is too long to link in one step, link piecewise
+ # or, if using GNU ld and skipped_export is not :, use a linker
+ # script.
+
+ # Save the value of $output and $libobjs because we want to
+ # use them later. If we have whole_archive_flag_spec, we
+ # want to use save_libobjs as it was before
+ # whole_archive_flag_spec was expanded, because we can't
+ # assume the linker understands whole_archive_flag_spec.
+ # This may have to be revisited, in case too many
+ # convenience libraries get linked in and end up exceeding
+ # the spec.
+ if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then
+ save_libobjs=$libobjs
+ fi
+ save_output=$output
+ func_basename "$output"
+ output_la=$func_basename_result
+
+ # Clear the reloadable object creation command queue and
+ # initialize k to one.
+ test_cmds=
+ concat_cmds=
+ objlist=
+ last_robj=
+ k=1
+
+ if test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "$with_gnu_ld" = yes; then
+ output=${output_objdir}/${output_la}.lnkscript
+ func_verbose "creating GNU ld script: $output"
+ echo 'INPUT (' > $output
+ for obj in $save_libobjs
+ do
+ func_to_tool_file "$obj"
+ $ECHO "$func_to_tool_file_result" >> $output
+ done
+ echo ')' >> $output
+ func_append delfiles " $output"
+ func_to_tool_file "$output"
+ output=$func_to_tool_file_result
+ elif test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "X$file_list_spec" != X; then
+ output=${output_objdir}/${output_la}.lnk
+ func_verbose "creating linker input file list: $output"
+ : > $output
+ set x $save_libobjs
+ shift
+ firstobj=
+ if test "$compiler_needs_object" = yes; then
+ firstobj="$1 "
+ shift
+ fi
+ for obj
+ do
+ func_to_tool_file "$obj"
+ $ECHO "$func_to_tool_file_result" >> $output
+ done
+ func_append delfiles " $output"
+ func_to_tool_file "$output"
+ output=$firstobj\"$file_list_spec$func_to_tool_file_result\"
+ else
+ if test -n "$save_libobjs"; then
+ func_verbose "creating reloadable object files..."
+ output=$output_objdir/$output_la-${k}.$objext
+ eval test_cmds=\"$reload_cmds\"
+ func_len " $test_cmds"
+ len0=$func_len_result
+ len=$len0
+
+ # Loop over the list of objects to be linked.
+ for obj in $save_libobjs
+ do
+ func_len " $obj"
+ func_arith $len + $func_len_result
+ len=$func_arith_result
+ if test "X$objlist" = X ||
+ test "$len" -lt "$max_cmd_len"; then
+ func_append objlist " $obj"
+ else
+ # The command $test_cmds is almost too long, add a
+ # command to the queue.
+ if test "$k" -eq 1 ; then
+ # The first file doesn't have a previous command to add.
+ reload_objs=$objlist
+ eval concat_cmds=\"$reload_cmds\"
+ else
+ # All subsequent reloadable object files will link in
+ # the last one created.
+ reload_objs="$objlist $last_robj"
+ eval concat_cmds=\"\$concat_cmds~$reload_cmds~\$RM $last_robj\"
+ fi
+ last_robj=$output_objdir/$output_la-${k}.$objext
+ func_arith $k + 1
+ k=$func_arith_result
+ output=$output_objdir/$output_la-${k}.$objext
+ objlist=" $obj"
+ func_len " $last_robj"
+ func_arith $len0 + $func_len_result
+ len=$func_arith_result
+ fi
+ done
+ # Handle the remaining objects by creating one last
+ # reloadable object file. All subsequent reloadable object
+ # files will link in the last one created.
+ test -z "$concat_cmds" || concat_cmds=$concat_cmds~
+ reload_objs="$objlist $last_robj"
+ eval concat_cmds=\"\${concat_cmds}$reload_cmds\"
+ if test -n "$last_robj"; then
+ eval concat_cmds=\"\${concat_cmds}~\$RM $last_robj\"
+ fi
+ func_append delfiles " $output"
+
+ else
+ output=
+ fi
+
+ if ${skipped_export-false}; then
+ func_verbose "generating symbol list for \`$libname.la'"
+ export_symbols="$output_objdir/$libname.exp"
+ $opt_dry_run || $RM $export_symbols
+ libobjs=$output
+ # Append the command to create the export file.
+ test -z "$concat_cmds" || concat_cmds=$concat_cmds~
+ eval concat_cmds=\"\$concat_cmds$export_symbols_cmds\"
+ if test -n "$last_robj"; then
+ eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\"
+ fi
+ fi
+
+ test -n "$save_libobjs" &&
+ func_verbose "creating a temporary reloadable object file: $output"
+
+ # Loop through the commands generated above and execute them.
+ save_ifs="$IFS"; IFS='~'
+ for cmd in $concat_cmds; do
+ IFS="$save_ifs"
+ $opt_silent || {
+ func_quote_for_expand "$cmd"
+ eval "func_echo $func_quote_for_expand_result"
+ }
+ $opt_dry_run || eval "$cmd" || {
+ lt_exit=$?
+
+ # Restore the uninstalled library and exit
+ if test "$opt_mode" = relink; then
+ ( cd "$output_objdir" && \
+ $RM "${realname}T" && \
+ $MV "${realname}U" "$realname" )
+ fi
+
+ exit $lt_exit
+ }
+ done
+ IFS="$save_ifs"
+
+ if test -n "$export_symbols_regex" && ${skipped_export-false}; then
+ func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"'
+ func_show_eval '$MV "${export_symbols}T" "$export_symbols"'
+ fi
+ fi
+
+ if ${skipped_export-false}; then
+ if test -n "$export_symbols" && test -n "$include_expsyms"; then
+ tmp_export_symbols="$export_symbols"
+ test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols"
+ $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"'
+ fi
+
+ if test -n "$orig_export_symbols"; then
+ # The given exports_symbols file has to be filtered, so filter it.
+ func_verbose "filter symbol list for \`$libname.la' to tag DATA exports"
+ # FIXME: $output_objdir/$libname.filter potentially contains lots of
+ # 's' commands which not all seds can handle. GNU sed should be fine
+ # though. Also, the filter scales superlinearly with the number of
+ # global variables. join(1) would be nice here, but unfortunately
+ # isn't a blessed tool.
+ $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter
+ func_append delfiles " $export_symbols $output_objdir/$libname.filter"
+ export_symbols=$output_objdir/$libname.def
+ $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols
+ fi
+ fi
+
+ libobjs=$output
+ # Restore the value of output.
+ output=$save_output
+
+ if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then
+ eval libobjs=\"\$libobjs $whole_archive_flag_spec\"
+ test "X$libobjs" = "X " && libobjs=
+ fi
+ # Expand the library linking commands again to reset the
+ # value of $libobjs for piecewise linking.
+
+ # Do each of the archive commands.
+ if test "$module" = yes && test -n "$module_cmds" ; then
+ if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then
+ cmds=$module_expsym_cmds
+ else
+ cmds=$module_cmds
+ fi
+ else
+ if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then
+ cmds=$archive_expsym_cmds
+ else
+ cmds=$archive_cmds
+ fi
+ fi
+ fi
+
+ if test -n "$delfiles"; then
+ # Append the command to remove temporary files to $cmds.
+ eval cmds=\"\$cmds~\$RM $delfiles\"
+ fi
+
+ # Add any objects from preloaded convenience libraries
+ if test -n "$dlprefiles"; then
+ gentop="$output_objdir/${outputname}x"
+ func_append generated " $gentop"
+
+ func_extract_archives $gentop $dlprefiles
+ func_append libobjs " $func_extract_archives_result"
+ test "X$libobjs" = "X " && libobjs=
+ fi
+
+ save_ifs="$IFS"; IFS='~'
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ eval cmd=\"$cmd\"
+ $opt_silent || {
+ func_quote_for_expand "$cmd"
+ eval "func_echo $func_quote_for_expand_result"
+ }
+ $opt_dry_run || eval "$cmd" || {
+ lt_exit=$?
+
+ # Restore the uninstalled library and exit
+ if test "$opt_mode" = relink; then
+ ( cd "$output_objdir" && \
+ $RM "${realname}T" && \
+ $MV "${realname}U" "$realname" )
+ fi
+
+ exit $lt_exit
+ }
+ done
+ IFS="$save_ifs"
+
+ # Restore the uninstalled library and exit
+ if test "$opt_mode" = relink; then
+ $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}T && $MV $realname ${realname}T && $MV ${realname}U $realname)' || exit $?
+
+ if test -n "$convenience"; then
+ if test -z "$whole_archive_flag_spec"; then
+ func_show_eval '${RM}r "$gentop"'
+ fi
+ fi
+
+ exit $EXIT_SUCCESS
+ fi
+
+ # Create links to the real library.
+ for linkname in $linknames; do
+ if test "$realname" != "$linkname"; then
+ func_show_eval '(cd "$output_objdir" && $RM "$linkname" && $LN_S "$realname" "$linkname")' 'exit $?'
+ fi
+ done
+
+ # If -module or -export-dynamic was specified, set the dlname.
+ if test "$module" = yes || test "$export_dynamic" = yes; then
+ # On all known operating systems, these are identical.
+ dlname="$soname"
+ fi
+ fi
+ ;;
+
+ obj)
+ if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+ func_warning "\`-dlopen' is ignored for objects"
+ fi
+
+ case " $deplibs" in
+ *\ -l* | *\ -L*)
+ func_warning "\`-l' and \`-L' are ignored for objects" ;;
+ esac
+
+ test -n "$rpath" && \
+ func_warning "\`-rpath' is ignored for objects"
+
+ test -n "$xrpath" && \
+ func_warning "\`-R' is ignored for objects"
+
+ test -n "$vinfo" && \
+ func_warning "\`-version-info' is ignored for objects"
+
+ test -n "$release" && \
+ func_warning "\`-release' is ignored for objects"
+
+ case $output in
+ *.lo)
+ test -n "$objs$old_deplibs" && \
+ func_fatal_error "cannot build library object \`$output' from non-libtool objects"
+
+ libobj=$output
+ func_lo2o "$libobj"
+ obj=$func_lo2o_result
+ ;;
+ *)
+ libobj=
+ obj="$output"
+ ;;
+ esac
+
+ # Delete the old objects.
+ $opt_dry_run || $RM $obj $libobj
+
+ # Objects from convenience libraries. This assumes
+ # single-version convenience libraries. Whenever we create
+ # different ones for PIC/non-PIC, this we'll have to duplicate
+ # the extraction.
+ reload_conv_objs=
+ gentop=
+ # reload_cmds runs $LD directly, so let us get rid of
+ # -Wl from whole_archive_flag_spec and hope we can get by with
+ # turning comma into space..
+ wl=
+
+ if test -n "$convenience"; then
+ if test -n "$whole_archive_flag_spec"; then
+ eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\"
+ reload_conv_objs=$reload_objs\ `$ECHO "$tmp_whole_archive_flags" | $SED 's|,| |g'`
+ else
+ gentop="$output_objdir/${obj}x"
+ func_append generated " $gentop"
+
+ func_extract_archives $gentop $convenience
+ reload_conv_objs="$reload_objs $func_extract_archives_result"
+ fi
+ fi
+
+ # If we're not building shared, we need to use non_pic_objs
+ test "$build_libtool_libs" != yes && libobjs="$non_pic_objects"
+
+ # Create the old-style object.
+ reload_objs="$objs$old_deplibs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.${libext}$/d; /\.lib$/d; $lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test
+
+ output="$obj"
+ func_execute_cmds "$reload_cmds" 'exit $?'
+
+ # Exit if we aren't doing a library object file.
+ if test -z "$libobj"; then
+ if test -n "$gentop"; then
+ func_show_eval '${RM}r "$gentop"'
+ fi
+
+ exit $EXIT_SUCCESS
+ fi
+
+ if test "$build_libtool_libs" != yes; then
+ if test -n "$gentop"; then
+ func_show_eval '${RM}r "$gentop"'
+ fi
+
+ # Create an invalid libtool object if no PIC, so that we don't
+ # accidentally link it into a program.
+ # $show "echo timestamp > $libobj"
+ # $opt_dry_run || eval "echo timestamp > $libobj" || exit $?
+ exit $EXIT_SUCCESS
+ fi
+
+ if test -n "$pic_flag" || test "$pic_mode" != default; then
+ # Only do commands if we really have different PIC objects.
+ reload_objs="$libobjs $reload_conv_objs"
+ output="$libobj"
+ func_execute_cmds "$reload_cmds" 'exit $?'
+ fi
+
+ if test -n "$gentop"; then
+ func_show_eval '${RM}r "$gentop"'
+ fi
+
+ exit $EXIT_SUCCESS
+ ;;
+
+ prog)
+ case $host in
+ *cygwin*) func_stripname '' '.exe' "$output"
+ output=$func_stripname_result.exe;;
+ esac
+ test -n "$vinfo" && \
+ func_warning "\`-version-info' is ignored for programs"
+
+ test -n "$release" && \
+ func_warning "\`-release' is ignored for programs"
+
+ test "$preload" = yes \
+ && test "$dlopen_support" = unknown \
+ && test "$dlopen_self" = unknown \
+ && test "$dlopen_self_static" = unknown && \
+ func_warning "\`LT_INIT([dlopen])' not used. Assuming no dlopen support."
+
+ case $host in
+ *-*-rhapsody* | *-*-darwin1.[012])
+ # On Rhapsody replace the C library is the System framework
+ compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's/ -lc / System.ltframework /'`
+ finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's/ -lc / System.ltframework /'`
+ ;;
+ esac
+
+ case $host in
+ *-*-darwin*)
+ # Don't allow lazy linking, it breaks C++ global constructors
+ # But is supposedly fixed on 10.4 or later (yay!).
+ if test "$tagname" = CXX ; then
+ case ${MACOSX_DEPLOYMENT_TARGET-10.0} in
+ 10.[0123])
+ func_append compile_command " ${wl}-bind_at_load"
+ func_append finalize_command " ${wl}-bind_at_load"
+ ;;
+ esac
+ fi
+ # Time to change all our "foo.ltframework" stuff back to "-framework foo"
+ compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+ finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+ ;;
+ esac
+
+
+ # move library search paths that coincide with paths to not yet
+ # installed libraries to the beginning of the library search list
+ new_libs=
+ for path in $notinst_path; do
+ case " $new_libs " in
+ *" -L$path/$objdir "*) ;;
+ *)
+ case " $compile_deplibs " in
+ *" -L$path/$objdir "*)
+ func_append new_libs " -L$path/$objdir" ;;
+ esac
+ ;;
+ esac
+ done
+ for deplib in $compile_deplibs; do
+ case $deplib in
+ -L*)
+ case " $new_libs " in
+ *" $deplib "*) ;;
+ *) func_append new_libs " $deplib" ;;
+ esac
+ ;;
+ *) func_append new_libs " $deplib" ;;
+ esac
+ done
+ compile_deplibs="$new_libs"
+
+
+ func_append compile_command " $compile_deplibs"
+ func_append finalize_command " $finalize_deplibs"
+
+ if test -n "$rpath$xrpath"; then
+ # If the user specified any rpath flags, then add them.
+ for libdir in $rpath $xrpath; do
+ # This is the magic to use -rpath.
+ case "$finalize_rpath " in
+ *" $libdir "*) ;;
+ *) func_append finalize_rpath " $libdir" ;;
+ esac
+ done
+ fi
+
+ # Now hardcode the library paths
+ rpath=
+ hardcode_libdirs=
+ for libdir in $compile_rpath $finalize_rpath; do
+ if test -n "$hardcode_libdir_flag_spec"; then
+ if test -n "$hardcode_libdir_separator"; then
+ if test -z "$hardcode_libdirs"; then
+ hardcode_libdirs="$libdir"
+ else
+ # Just accumulate the unique libdirs.
+ case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
+ *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+ ;;
+ *)
+ func_append hardcode_libdirs "$hardcode_libdir_separator$libdir"
+ ;;
+ esac
+ fi
+ else
+ eval flag=\"$hardcode_libdir_flag_spec\"
+ func_append rpath " $flag"
+ fi
+ elif test -n "$runpath_var"; then
+ case "$perm_rpath " in
+ *" $libdir "*) ;;
+ *) func_append perm_rpath " $libdir" ;;
+ esac
+ fi
+ case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
+ testbindir=`${ECHO} "$libdir" | ${SED} -e 's*/lib$*/bin*'`
+ case :$dllsearchpath: in
+ *":$libdir:"*) ;;
+ ::) dllsearchpath=$libdir;;
+ *) func_append dllsearchpath ":$libdir";;
+ esac
+ case :$dllsearchpath: in
+ *":$testbindir:"*) ;;
+ ::) dllsearchpath=$testbindir;;
+ *) func_append dllsearchpath ":$testbindir";;
+ esac
+ ;;
+ esac
+ done
+ # Substitute the hardcoded libdirs into the rpath.
+ if test -n "$hardcode_libdir_separator" &&
+ test -n "$hardcode_libdirs"; then
+ libdir="$hardcode_libdirs"
+ eval rpath=\" $hardcode_libdir_flag_spec\"
+ fi
+ compile_rpath="$rpath"
+
+ rpath=
+ hardcode_libdirs=
+ for libdir in $finalize_rpath; do
+ if test -n "$hardcode_libdir_flag_spec"; then
+ if test -n "$hardcode_libdir_separator"; then
+ if test -z "$hardcode_libdirs"; then
+ hardcode_libdirs="$libdir"
+ else
+ # Just accumulate the unique libdirs.
+ case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
+ *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+ ;;
+ *)
+ func_append hardcode_libdirs "$hardcode_libdir_separator$libdir"
+ ;;
+ esac
+ fi
+ else
+ eval flag=\"$hardcode_libdir_flag_spec\"
+ func_append rpath " $flag"
+ fi
+ elif test -n "$runpath_var"; then
+ case "$finalize_perm_rpath " in
+ *" $libdir "*) ;;
+ *) func_append finalize_perm_rpath " $libdir" ;;
+ esac
+ fi
+ done
+ # Substitute the hardcoded libdirs into the rpath.
+ if test -n "$hardcode_libdir_separator" &&
+ test -n "$hardcode_libdirs"; then
+ libdir="$hardcode_libdirs"
+ eval rpath=\" $hardcode_libdir_flag_spec\"
+ fi
+ finalize_rpath="$rpath"
+
+ if test -n "$libobjs" && test "$build_old_libs" = yes; then
+ # Transform all the library objects into standard objects.
+ compile_command=`$ECHO "$compile_command" | $SP2NL | $SED "$lo2o" | $NL2SP`
+ finalize_command=`$ECHO "$finalize_command" | $SP2NL | $SED "$lo2o" | $NL2SP`
+ fi
+
+ func_generate_dlsyms "$outputname" "@PROGRAM@" "no"
+
+ # template prelinking step
+ if test -n "$prelink_cmds"; then
+ func_execute_cmds "$prelink_cmds" 'exit $?'
+ fi
+
+ wrappers_required=yes
+ case $host in
+ *cegcc* | *mingw32ce*)
+ # Disable wrappers for cegcc and mingw32ce hosts, we are cross compiling anyway.
+ wrappers_required=no
+ ;;
+ *cygwin* | *mingw* )
+ if test "$build_libtool_libs" != yes; then
+ wrappers_required=no
+ fi
+ ;;
+ *)
+ if test "$need_relink" = no || test "$build_libtool_libs" != yes; then
+ wrappers_required=no
+ fi
+ ;;
+ esac
+ if test "$wrappers_required" = no; then
+ # Replace the output file specification.
+ compile_command=`$ECHO "$compile_command" | $SED 's%@OUTPUT@%'"$output"'%g'`
+ link_command="$compile_command$compile_rpath"
+
+ # We have no uninstalled library dependencies, so finalize right now.
+ exit_status=0
+ func_show_eval "$link_command" 'exit_status=$?'
+
+ if test -n "$postlink_cmds"; then
+ func_to_tool_file "$output"
+ postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'`
+ func_execute_cmds "$postlink_cmds" 'exit $?'
+ fi
+
+ # Delete the generated files.
+ if test -f "$output_objdir/${outputname}S.${objext}"; then
+ func_show_eval '$RM "$output_objdir/${outputname}S.${objext}"'
+ fi
+
+ exit $exit_status
+ fi
+
+ if test -n "$compile_shlibpath$finalize_shlibpath"; then
+ compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command"
+ fi
+ if test -n "$finalize_shlibpath"; then
+ finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command"
+ fi
+
+ compile_var=
+ finalize_var=
+ if test -n "$runpath_var"; then
+ if test -n "$perm_rpath"; then
+ # We should set the runpath_var.
+ rpath=
+ for dir in $perm_rpath; do
+ func_append rpath "$dir:"
+ done
+ compile_var="$runpath_var=\"$rpath\$$runpath_var\" "
+ fi
+ if test -n "$finalize_perm_rpath"; then
+ # We should set the runpath_var.
+ rpath=
+ for dir in $finalize_perm_rpath; do
+ func_append rpath "$dir:"
+ done
+ finalize_var="$runpath_var=\"$rpath\$$runpath_var\" "
+ fi
+ fi
+
+ if test "$no_install" = yes; then
+ # We don't need to create a wrapper script.
+ link_command="$compile_var$compile_command$compile_rpath"
+ # Replace the output file specification.
+ link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output"'%g'`
+ # Delete the old output file.
+ $opt_dry_run || $RM $output
+ # Link the executable and exit
+ func_show_eval "$link_command" 'exit $?'
+
+ if test -n "$postlink_cmds"; then
+ func_to_tool_file "$output"
+ postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'`
+ func_execute_cmds "$postlink_cmds" 'exit $?'
+ fi
+
+ exit $EXIT_SUCCESS
+ fi
+
+ if test "$hardcode_action" = relink; then
+ # Fast installation is not supported
+ link_command="$compile_var$compile_command$compile_rpath"
+ relink_command="$finalize_var$finalize_command$finalize_rpath"
+
+ func_warning "this platform does not like uninstalled shared libraries"
+ func_warning "\`$output' will be relinked during installation"
+ else
+ if test "$fast_install" != no; then
+ link_command="$finalize_var$compile_command$finalize_rpath"
+ if test "$fast_install" = yes; then
+ relink_command=`$ECHO "$compile_var$compile_command$compile_rpath" | $SED 's%@OUTPUT@%\$progdir/\$file%g'`
+ else
+ # fast_install is set to needless
+ relink_command=
+ fi
+ else
+ link_command="$compile_var$compile_command$compile_rpath"
+ relink_command="$finalize_var$finalize_command$finalize_rpath"
+ fi
+ fi
+
+ # Replace the output file specification.
+ link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'`
+
+ # Delete the old output files.
+ $opt_dry_run || $RM $output $output_objdir/$outputname $output_objdir/lt-$outputname
+
+ func_show_eval "$link_command" 'exit $?'
+
+ if test -n "$postlink_cmds"; then
+ func_to_tool_file "$output_objdir/$outputname"
+ postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'`
+ func_execute_cmds "$postlink_cmds" 'exit $?'
+ fi
+
+ # Now create the wrapper script.
+ func_verbose "creating $output"
+
+ # Quote the relink command for shipping.
+ if test -n "$relink_command"; then
+ # Preserve any variables that may affect compiler behavior
+ for var in $variables_saved_for_relink; do
+ if eval test -z \"\${$var+set}\"; then
+ relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command"
+ elif eval var_value=\$$var; test -z "$var_value"; then
+ relink_command="$var=; export $var; $relink_command"
+ else
+ func_quote_for_eval "$var_value"
+ relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command"
+ fi
+ done
+ relink_command="(cd `pwd`; $relink_command)"
+ relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"`
+ fi
+
+ # Only actually do things if not in dry run mode.
+ $opt_dry_run || {
+ # win32 will think the script is a binary if it has
+ # a .exe suffix, so we strip it off here.
+ case $output in
+ *.exe) func_stripname '' '.exe' "$output"
+ output=$func_stripname_result ;;
+ esac
+ # test for cygwin because mv fails w/o .exe extensions
+ case $host in
+ *cygwin*)
+ exeext=.exe
+ func_stripname '' '.exe' "$outputname"
+ outputname=$func_stripname_result ;;
+ *) exeext= ;;
+ esac
+ case $host in
+ *cygwin* | *mingw* )
+ func_dirname_and_basename "$output" "" "."
+ output_name=$func_basename_result
+ output_path=$func_dirname_result
+ cwrappersource="$output_path/$objdir/lt-$output_name.c"
+ cwrapper="$output_path/$output_name.exe"
+ $RM $cwrappersource $cwrapper
+ trap "$RM $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15
+
+ func_emit_cwrapperexe_src > $cwrappersource
+
+ # The wrapper executable is built using the $host compiler,
+ # because it contains $host paths and files. If cross-
+ # compiling, it, like the target executable, must be
+ # executed on the $host or under an emulation environment.
+ $opt_dry_run || {
+ $LTCC $LTCFLAGS -o $cwrapper $cwrappersource
+ $STRIP $cwrapper
+ }
+
+ # Now, create the wrapper script for func_source use:
+ func_ltwrapper_scriptname $cwrapper
+ $RM $func_ltwrapper_scriptname_result
+ trap "$RM $func_ltwrapper_scriptname_result; exit $EXIT_FAILURE" 1 2 15
+ $opt_dry_run || {
+ # note: this script will not be executed, so do not chmod.
+ if test "x$build" = "x$host" ; then
+ $cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result
+ else
+ func_emit_wrapper no > $func_ltwrapper_scriptname_result
+ fi
+ }
+ ;;
+ * )
+ $RM $output
+ trap "$RM $output; exit $EXIT_FAILURE" 1 2 15
+
+ func_emit_wrapper no > $output
+ chmod +x $output
+ ;;
+ esac
+ }
+ exit $EXIT_SUCCESS
+ ;;
+ esac
+
+ # See if we need to build an old-fashioned archive.
+ for oldlib in $oldlibs; do
+
+ if test "$build_libtool_libs" = convenience; then
+ oldobjs="$libobjs_save $symfileobj"
+ addlibs="$convenience"
+ build_libtool_libs=no
+ else
+ if test "$build_libtool_libs" = module; then
+ oldobjs="$libobjs_save"
+ build_libtool_libs=no
+ else
+ oldobjs="$old_deplibs $non_pic_objects"
+ if test "$preload" = yes && test -f "$symfileobj"; then
+ func_append oldobjs " $symfileobj"
+ fi
+ fi
+ addlibs="$old_convenience"
+ fi
+
+ if test -n "$addlibs"; then
+ gentop="$output_objdir/${outputname}x"
+ func_append generated " $gentop"
+
+ func_extract_archives $gentop $addlibs
+ func_append oldobjs " $func_extract_archives_result"
+ fi
+
+ # Do each command in the archive commands.
+ if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then
+ cmds=$old_archive_from_new_cmds
+ else
+
+ # Add any objects from preloaded convenience libraries
+ if test -n "$dlprefiles"; then
+ gentop="$output_objdir/${outputname}x"
+ func_append generated " $gentop"
+
+ func_extract_archives $gentop $dlprefiles
+ func_append oldobjs " $func_extract_archives_result"
+ fi
+
+ # POSIX demands no paths to be encoded in archives. We have
+ # to avoid creating archives with duplicate basenames if we
+ # might have to extract them afterwards, e.g., when creating a
+ # static archive out of a convenience library, or when linking
+ # the entirety of a libtool archive into another (currently
+ # not supported by libtool).
+ if (for obj in $oldobjs
+ do
+ func_basename "$obj"
+ $ECHO "$func_basename_result"
+ done | sort | sort -uc >/dev/null 2>&1); then
+ :
+ else
+ echo "copying selected object files to avoid basename conflicts..."
+ gentop="$output_objdir/${outputname}x"
+ func_append generated " $gentop"
+ func_mkdir_p "$gentop"
+ save_oldobjs=$oldobjs
+ oldobjs=
+ counter=1
+ for obj in $save_oldobjs
+ do
+ func_basename "$obj"
+ objbase="$func_basename_result"
+ case " $oldobjs " in
+ " ") oldobjs=$obj ;;
+ *[\ /]"$objbase "*)
+ while :; do
+ # Make sure we don't pick an alternate name that also
+ # overlaps.
+ newobj=lt$counter-$objbase
+ func_arith $counter + 1
+ counter=$func_arith_result
+ case " $oldobjs " in
+ *[\ /]"$newobj "*) ;;
+ *) if test ! -f "$gentop/$newobj"; then break; fi ;;
+ esac
+ done
+ func_show_eval "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj"
+ func_append oldobjs " $gentop/$newobj"
+ ;;
+ *) func_append oldobjs " $obj" ;;
+ esac
+ done
+ fi
+ func_to_tool_file "$oldlib" func_convert_file_msys_to_w32
+ tool_oldlib=$func_to_tool_file_result
+ eval cmds=\"$old_archive_cmds\"
+
+ func_len " $cmds"
+ len=$func_len_result
+ if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then
+ cmds=$old_archive_cmds
+ elif test -n "$archiver_list_spec"; then
+ func_verbose "using command file archive linking..."
+ for obj in $oldobjs
+ do
+ func_to_tool_file "$obj"
+ $ECHO "$func_to_tool_file_result"
+ done > $output_objdir/$libname.libcmd
+ func_to_tool_file "$output_objdir/$libname.libcmd"
+ oldobjs=" $archiver_list_spec$func_to_tool_file_result"
+ cmds=$old_archive_cmds
+ else
+ # the command line is too long to link in one step, link in parts
+ func_verbose "using piecewise archive linking..."
+ save_RANLIB=$RANLIB
+ RANLIB=:
+ objlist=
+ concat_cmds=
+ save_oldobjs=$oldobjs
+ oldobjs=
+ # Is there a better way of finding the last object in the list?
+ for obj in $save_oldobjs
+ do
+ last_oldobj=$obj
+ done
+ eval test_cmds=\"$old_archive_cmds\"
+ func_len " $test_cmds"
+ len0=$func_len_result
+ len=$len0
+ for obj in $save_oldobjs
+ do
+ func_len " $obj"
+ func_arith $len + $func_len_result
+ len=$func_arith_result
+ func_append objlist " $obj"
+ if test "$len" -lt "$max_cmd_len"; then
+ :
+ else
+ # the above command should be used before it gets too long
+ oldobjs=$objlist
+ if test "$obj" = "$last_oldobj" ; then
+ RANLIB=$save_RANLIB
+ fi
+ test -z "$concat_cmds" || concat_cmds=$concat_cmds~
+ eval concat_cmds=\"\${concat_cmds}$old_archive_cmds\"
+ objlist=
+ len=$len0
+ fi
+ done
+ RANLIB=$save_RANLIB
+ oldobjs=$objlist
+ if test "X$oldobjs" = "X" ; then
+ eval cmds=\"\$concat_cmds\"
+ else
+ eval cmds=\"\$concat_cmds~\$old_archive_cmds\"
+ fi
+ fi
+ fi
+ func_execute_cmds "$cmds" 'exit $?'
+ done
+
+ test -n "$generated" && \
+ func_show_eval "${RM}r$generated"
+
+ # Now create the libtool archive.
+ case $output in
+ *.la)
+ old_library=
+ test "$build_old_libs" = yes && old_library="$libname.$libext"
+ func_verbose "creating $output"
+
+ # Preserve any variables that may affect compiler behavior
+ for var in $variables_saved_for_relink; do
+ if eval test -z \"\${$var+set}\"; then
+ relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command"
+ elif eval var_value=\$$var; test -z "$var_value"; then
+ relink_command="$var=; export $var; $relink_command"
+ else
+ func_quote_for_eval "$var_value"
+ relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command"
+ fi
+ done
+ # Quote the link command for shipping.
+ relink_command="(cd `pwd`; $SHELL $progpath $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)"
+ relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"`
+ if test "$hardcode_automatic" = yes ; then
+ relink_command=
+ fi
+
+ # Only create the output if not a dry run.
+ $opt_dry_run || {
+ for installed in no yes; do
+ if test "$installed" = yes; then
+ if test -z "$install_libdir"; then
+ break
+ fi
+ output="$output_objdir/$outputname"i
+ # Replace all uninstalled libtool libraries with the installed ones
+ newdependency_libs=
+ for deplib in $dependency_libs; do
+ case $deplib in
+ *.la)
+ func_basename "$deplib"
+ name="$func_basename_result"
+ func_resolve_sysroot "$deplib"
+ eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $func_resolve_sysroot_result`
+ test -z "$libdir" && \
+ func_fatal_error "\`$deplib' is not a valid libtool archive"
+ func_append newdependency_libs " ${lt_sysroot:+=}$libdir/$name"
+ ;;
+ -L*)
+ func_stripname -L '' "$deplib"
+ func_replace_sysroot "$func_stripname_result"
+ func_append newdependency_libs " -L$func_replace_sysroot_result"
+ ;;
+ -R*)
+ func_stripname -R '' "$deplib"
+ func_replace_sysroot "$func_stripname_result"
+ func_append newdependency_libs " -R$func_replace_sysroot_result"
+ ;;
+ *) func_append newdependency_libs " $deplib" ;;
+ esac
+ done
+ dependency_libs="$newdependency_libs"
+ newdlfiles=
+
+ for lib in $dlfiles; do
+ case $lib in
+ *.la)
+ func_basename "$lib"
+ name="$func_basename_result"
+ eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
+ test -z "$libdir" && \
+ func_fatal_error "\`$lib' is not a valid libtool archive"
+ func_append newdlfiles " ${lt_sysroot:+=}$libdir/$name"
+ ;;
+ *) func_append newdlfiles " $lib" ;;
+ esac
+ done
+ dlfiles="$newdlfiles"
+ newdlprefiles=
+ for lib in $dlprefiles; do
+ case $lib in
+ *.la)
+ # Only pass preopened files to the pseudo-archive (for
+ # eventual linking with the app. that links it) if we
+ # didn't already link the preopened objects directly into
+ # the library:
+ func_basename "$lib"
+ name="$func_basename_result"
+ eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
+ test -z "$libdir" && \
+ func_fatal_error "\`$lib' is not a valid libtool archive"
+ func_append newdlprefiles " ${lt_sysroot:+=}$libdir/$name"
+ ;;
+ esac
+ done
+ dlprefiles="$newdlprefiles"
+ else
+ newdlfiles=
+ for lib in $dlfiles; do
+ case $lib in
+ [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;;
+ *) abs=`pwd`"/$lib" ;;
+ esac
+ func_append newdlfiles " $abs"
+ done
+ dlfiles="$newdlfiles"
+ newdlprefiles=
+ for lib in $dlprefiles; do
+ case $lib in
+ [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;;
+ *) abs=`pwd`"/$lib" ;;
+ esac
+ func_append newdlprefiles " $abs"
+ done
+ dlprefiles="$newdlprefiles"
+ fi
+ $RM $output
+ # place dlname in correct position for cygwin
+ # In fact, it would be nice if we could use this code for all target
+ # systems that can't hard-code library paths into their executables
+ # and that have no shared library path variable independent of PATH,
+ # but it turns out we can't easily determine that from inspecting
+ # libtool variables, so we have to hard-code the OSs to which it
+ # applies here; at the moment, that means platforms that use the PE
+ # object format with DLL files. See the long comment at the top of
+ # tests/bindir.at for full details.
+ tdlname=$dlname
+ case $host,$output,$installed,$module,$dlname in
+ *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll)
+ # If a -bindir argument was supplied, place the dll there.
+ if test "x$bindir" != x ;
+ then
+ func_relative_path "$install_libdir" "$bindir"
+ tdlname=$func_relative_path_result$dlname
+ else
+ # Otherwise fall back on heuristic.
+ tdlname=../bin/$dlname
+ fi
+ ;;
+ esac
+ $ECHO > $output "\
+# $outputname - a libtool library file
+# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION
+#
+# Please DO NOT delete this file!
+# It is necessary for linking the library.
+
+# The name that we can dlopen(3).
+dlname='$tdlname'
+
+# Names of this library.
+library_names='$library_names'
+
+# The name of the static archive.
+old_library='$old_library'
+
+# Linker flags that can not go in dependency_libs.
+inherited_linker_flags='$new_inherited_linker_flags'
+
+# Libraries that this one depends upon.
+dependency_libs='$dependency_libs'
+
+# Names of additional weak libraries provided by this library
+weak_library_names='$weak_libs'
+
+# Version information for $libname.
+current=$current
+age=$age
+revision=$revision
+
+# Is this an already installed library?
+installed=$installed
+
+# Should we warn about portability when linking against -modules?
+shouldnotlink=$module
+
+# Files to dlopen/dlpreopen
+dlopen='$dlfiles'
+dlpreopen='$dlprefiles'
+
+# Directory that this library needs to be installed in:
+libdir='$install_libdir'"
+ if test "$installed" = no && test "$need_relink" = yes; then
+ $ECHO >> $output "\
+relink_command=\"$relink_command\""
+ fi
+ done
+ }
+
+ # Do a symbolic link so that the libtool archive can be found in
+ # LD_LIBRARY_PATH before the program is installed.
+ func_show_eval '( cd "$output_objdir" && $RM "$outputname" && $LN_S "../$outputname" "$outputname" )' 'exit $?'
+ ;;
+ esac
+ exit $EXIT_SUCCESS
+}
+
+{ test "$opt_mode" = link || test "$opt_mode" = relink; } &&
+ func_mode_link ${1+"$@"}
+
+
+# func_mode_uninstall arg...
+func_mode_uninstall ()
+{
+ $opt_debug
+ RM="$nonopt"
+ files=
+ rmforce=
+ exit_status=0
+
+ # This variable tells wrapper scripts just to set variables rather
+ # than running their programs.
+ libtool_install_magic="$magic"
+
+ for arg
+ do
+ case $arg in
+ -f) func_append RM " $arg"; rmforce=yes ;;
+ -*) func_append RM " $arg" ;;
+ *) func_append files " $arg" ;;
+ esac
+ done
+
+ test -z "$RM" && \
+ func_fatal_help "you must specify an RM program"
+
+ rmdirs=
+
+ for file in $files; do
+ func_dirname "$file" "" "."
+ dir="$func_dirname_result"
+ if test "X$dir" = X.; then
+ odir="$objdir"
+ else
+ odir="$dir/$objdir"
+ fi
+ func_basename "$file"
+ name="$func_basename_result"
+ test "$opt_mode" = uninstall && odir="$dir"
+
+ # Remember odir for removal later, being careful to avoid duplicates
+ if test "$opt_mode" = clean; then
+ case " $rmdirs " in
+ *" $odir "*) ;;
+ *) func_append rmdirs " $odir" ;;
+ esac
+ fi
+
+ # Don't error if the file doesn't exist and rm -f was used.
+ if { test -L "$file"; } >/dev/null 2>&1 ||
+ { test -h "$file"; } >/dev/null 2>&1 ||
+ test -f "$file"; then
+ :
+ elif test -d "$file"; then
+ exit_status=1
+ continue
+ elif test "$rmforce" = yes; then
+ continue
+ fi
+
+ rmfiles="$file"
+
+ case $name in
+ *.la)
+ # Possibly a libtool archive, so verify it.
+ if func_lalib_p "$file"; then
+ func_source $dir/$name
+
+ # Delete the libtool libraries and symlinks.
+ for n in $library_names; do
+ func_append rmfiles " $odir/$n"
+ done
+ test -n "$old_library" && func_append rmfiles " $odir/$old_library"
+
+ case "$opt_mode" in
+ clean)
+ case " $library_names " in
+ *" $dlname "*) ;;
+ *) test -n "$dlname" && func_append rmfiles " $odir/$dlname" ;;
+ esac
+ test -n "$libdir" && func_append rmfiles " $odir/$name $odir/${name}i"
+ ;;
+ uninstall)
+ if test -n "$library_names"; then
+ # Do each command in the postuninstall commands.
+ func_execute_cmds "$postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1'
+ fi
+
+ if test -n "$old_library"; then
+ # Do each command in the old_postuninstall commands.
+ func_execute_cmds "$old_postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1'
+ fi
+ # FIXME: should reinstall the best remaining shared library.
+ ;;
+ esac
+ fi
+ ;;
+
+ *.lo)
+ # Possibly a libtool object, so verify it.
+ if func_lalib_p "$file"; then
+
+ # Read the .lo file
+ func_source $dir/$name
+
+ # Add PIC object to the list of files to remove.
+ if test -n "$pic_object" &&
+ test "$pic_object" != none; then
+ func_append rmfiles " $dir/$pic_object"
+ fi
+
+ # Add non-PIC object to the list of files to remove.
+ if test -n "$non_pic_object" &&
+ test "$non_pic_object" != none; then
+ func_append rmfiles " $dir/$non_pic_object"
+ fi
+ fi
+ ;;
+
+ *)
+ if test "$opt_mode" = clean ; then
+ noexename=$name
+ case $file in
+ *.exe)
+ func_stripname '' '.exe' "$file"
+ file=$func_stripname_result
+ func_stripname '' '.exe' "$name"
+ noexename=$func_stripname_result
+ # $file with .exe has already been added to rmfiles,
+ # add $file without .exe
+ func_append rmfiles " $file"
+ ;;
+ esac
+ # Do a test to see if this is a libtool program.
+ if func_ltwrapper_p "$file"; then
+ if func_ltwrapper_executable_p "$file"; then
+ func_ltwrapper_scriptname "$file"
+ relink_command=
+ func_source $func_ltwrapper_scriptname_result
+ func_append rmfiles " $func_ltwrapper_scriptname_result"
+ else
+ relink_command=
+ func_source $dir/$noexename
+ fi
+
+ # note $name still contains .exe if it was in $file originally
+ # as does the version of $file that was added into $rmfiles
+ func_append rmfiles " $odir/$name $odir/${name}S.${objext}"
+ if test "$fast_install" = yes && test -n "$relink_command"; then
+ func_append rmfiles " $odir/lt-$name"
+ fi
+ if test "X$noexename" != "X$name" ; then
+ func_append rmfiles " $odir/lt-${noexename}.c"
+ fi
+ fi
+ fi
+ ;;
+ esac
+ func_show_eval "$RM $rmfiles" 'exit_status=1'
+ done
+
+ # Try to remove the ${objdir}s in the directories where we deleted files
+ for dir in $rmdirs; do
+ if test -d "$dir"; then
+ func_show_eval "rmdir $dir >/dev/null 2>&1"
+ fi
+ done
+
+ exit $exit_status
+}
+
+{ test "$opt_mode" = uninstall || test "$opt_mode" = clean; } &&
+ func_mode_uninstall ${1+"$@"}
+
+test -z "$opt_mode" && {
+ help="$generic_help"
+ func_fatal_help "you must specify a MODE"
+}
+
+test -z "$exec_cmd" && \
+ func_fatal_help "invalid operation mode \`$opt_mode'"
+
+if test -n "$exec_cmd"; then
+ eval exec "$exec_cmd"
+ exit $EXIT_FAILURE
+fi
+
+exit $exit_status
+
+
+# The TAGs below are defined such that we never get into a situation
+# in which we disable both kinds of libraries. Given conflicting
+# choices, we go for a static library, that is the most portable,
+# since we can't tell whether shared libraries were disabled because
+# the user asked for that or because the platform doesn't support
+# them. This is particularly important on AIX, because we don't
+# support having both static and shared libraries enabled at the same
+# time on that platform, so we default to a shared-only configuration.
+# If a disable-shared tag is given, we'll fallback to a static-only
+# configuration. But we'll never go from static-only to shared-only.
+
+# ### BEGIN LIBTOOL TAG CONFIG: disable-shared
+build_libtool_libs=no
+build_old_libs=yes
+# ### END LIBTOOL TAG CONFIG: disable-shared
+
+# ### BEGIN LIBTOOL TAG CONFIG: disable-static
+build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac`
+# ### END LIBTOOL TAG CONFIG: disable-static
+
+# Local Variables:
+# mode:shell-script
+# sh-indentation:2
+# End:
+# vi:sw=2
+
diff --git a/m4/libtool.m4 b/m4/libtool.m4
new file mode 100644
index 0000000..56666f0
--- /dev/null
+++ b/m4/libtool.m4
@@ -0,0 +1,7986 @@
+# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*-
+#
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005,
+# 2006, 2007, 2008, 2009, 2010, 2011 Free Software
+# Foundation, Inc.
+# Written by Gordon Matzigkeit, 1996
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+
+m4_define([_LT_COPYING], [dnl
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005,
+# 2006, 2007, 2008, 2009, 2010, 2011 Free Software
+# Foundation, Inc.
+# Written by Gordon Matzigkeit, 1996
+#
+# This file is part of GNU Libtool.
+#
+# GNU Libtool 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.
+#
+# As a special exception to the GNU General Public License,
+# if you distribute this file as part of a program or library that
+# is built using GNU Libtool, you may include this file under the
+# same distribution terms that you use for the rest of that program.
+#
+# GNU Libtool 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 GNU Libtool; see the file COPYING. If not, a copy
+# can be downloaded from http://www.gnu.org/licenses/gpl.html, or
+# obtained by writing to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+])
+
+# serial 57 LT_INIT
+
+
+# LT_PREREQ(VERSION)
+# ------------------
+# Complain and exit if this libtool version is less that VERSION.
+m4_defun([LT_PREREQ],
+[m4_if(m4_version_compare(m4_defn([LT_PACKAGE_VERSION]), [$1]), -1,
+ [m4_default([$3],
+ [m4_fatal([Libtool version $1 or higher is required],
+ 63)])],
+ [$2])])
+
+
+# _LT_CHECK_BUILDDIR
+# ------------------
+# Complain if the absolute build directory name contains unusual characters
+m4_defun([_LT_CHECK_BUILDDIR],
+[case `pwd` in
+ *\ * | *\ *)
+ AC_MSG_WARN([Libtool does not cope well with whitespace in `pwd`]) ;;
+esac
+])
+
+
+# LT_INIT([OPTIONS])
+# ------------------
+AC_DEFUN([LT_INIT],
+[AC_PREREQ([2.58])dnl We use AC_INCLUDES_DEFAULT
+AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl
+AC_BEFORE([$0], [LT_LANG])dnl
+AC_BEFORE([$0], [LT_OUTPUT])dnl
+AC_BEFORE([$0], [LTDL_INIT])dnl
+m4_require([_LT_CHECK_BUILDDIR])dnl
+
+dnl Autoconf doesn't catch unexpanded LT_ macros by default:
+m4_pattern_forbid([^_?LT_[A-Z_]+$])dnl
+m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$])dnl
+dnl aclocal doesn't pull ltoptions.m4, ltsugar.m4, or ltversion.m4
+dnl unless we require an AC_DEFUNed macro:
+AC_REQUIRE([LTOPTIONS_VERSION])dnl
+AC_REQUIRE([LTSUGAR_VERSION])dnl
+AC_REQUIRE([LTVERSION_VERSION])dnl
+AC_REQUIRE([LTOBSOLETE_VERSION])dnl
+m4_require([_LT_PROG_LTMAIN])dnl
+
+_LT_SHELL_INIT([SHELL=${CONFIG_SHELL-/bin/sh}])
+
+dnl Parse OPTIONS
+_LT_SET_OPTIONS([$0], [$1])
+
+# This can be used to rebuild libtool when needed
+LIBTOOL_DEPS="$ltmain"
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+AC_SUBST(LIBTOOL)dnl
+
+_LT_SETUP
+
+# Only expand once:
+m4_define([LT_INIT])
+])# LT_INIT
+
+# Old names:
+AU_ALIAS([AC_PROG_LIBTOOL], [LT_INIT])
+AU_ALIAS([AM_PROG_LIBTOOL], [LT_INIT])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_PROG_LIBTOOL], [])
+dnl AC_DEFUN([AM_PROG_LIBTOOL], [])
+
+
+# _LT_CC_BASENAME(CC)
+# -------------------
+# Calculate cc_basename. Skip known compiler wrappers and cross-prefix.
+m4_defun([_LT_CC_BASENAME],
+[for cc_temp in $1""; do
+ case $cc_temp in
+ compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;;
+ distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;;
+ \-*) ;;
+ *) break;;
+ esac
+done
+cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"`
+])
+
+
+# _LT_FILEUTILS_DEFAULTS
+# ----------------------
+# It is okay to use these file commands and assume they have been set
+# sensibly after `m4_require([_LT_FILEUTILS_DEFAULTS])'.
+m4_defun([_LT_FILEUTILS_DEFAULTS],
+[: ${CP="cp -f"}
+: ${MV="mv -f"}
+: ${RM="rm -f"}
+])# _LT_FILEUTILS_DEFAULTS
+
+
+# _LT_SETUP
+# ---------
+m4_defun([_LT_SETUP],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+AC_REQUIRE([_LT_PREPARE_SED_QUOTE_VARS])dnl
+AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl
+
+_LT_DECL([], [PATH_SEPARATOR], [1], [The PATH separator for the build system])dnl
+dnl
+_LT_DECL([], [host_alias], [0], [The host system])dnl
+_LT_DECL([], [host], [0])dnl
+_LT_DECL([], [host_os], [0])dnl
+dnl
+_LT_DECL([], [build_alias], [0], [The build system])dnl
+_LT_DECL([], [build], [0])dnl
+_LT_DECL([], [build_os], [0])dnl
+dnl
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([LT_PATH_LD])dnl
+AC_REQUIRE([LT_PATH_NM])dnl
+dnl
+AC_REQUIRE([AC_PROG_LN_S])dnl
+test -z "$LN_S" && LN_S="ln -s"
+_LT_DECL([], [LN_S], [1], [Whether we need soft or hard links])dnl
+dnl
+AC_REQUIRE([LT_CMD_MAX_LEN])dnl
+_LT_DECL([objext], [ac_objext], [0], [Object file suffix (normally "o")])dnl
+_LT_DECL([], [exeext], [0], [Executable file suffix (normally "")])dnl
+dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_CHECK_SHELL_FEATURES])dnl
+m4_require([_LT_PATH_CONVERSION_FUNCTIONS])dnl
+m4_require([_LT_CMD_RELOAD])dnl
+m4_require([_LT_CHECK_MAGIC_METHOD])dnl
+m4_require([_LT_CHECK_SHAREDLIB_FROM_LINKLIB])dnl
+m4_require([_LT_CMD_OLD_ARCHIVE])dnl
+m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl
+m4_require([_LT_WITH_SYSROOT])dnl
+
+_LT_CONFIG_LIBTOOL_INIT([
+# See if we are running on zsh, and set the options which allow our
+# commands through without removal of \ escapes INIT.
+if test -n "\${ZSH_VERSION+set}" ; then
+ setopt NO_GLOB_SUBST
+fi
+])
+if test -n "${ZSH_VERSION+set}" ; then
+ setopt NO_GLOB_SUBST
+fi
+
+_LT_CHECK_OBJDIR
+
+m4_require([_LT_TAG_COMPILER])dnl
+
+case $host_os in
+aix3*)
+ # AIX sometimes has problems with the GCC collect2 program. For some
+ # reason, if we set the COLLECT_NAMES environment variable, the problems
+ # vanish in a puff of smoke.
+ if test "X${COLLECT_NAMES+set}" != Xset; then
+ COLLECT_NAMES=
+ export COLLECT_NAMES
+ fi
+ ;;
+esac
+
+# Global variables:
+ofile=libtool
+can_build_shared=yes
+
+# All known linkers require a `.a' archive for static linking (except MSVC,
+# which needs '.lib').
+libext=a
+
+with_gnu_ld="$lt_cv_prog_gnu_ld"
+
+old_CC="$CC"
+old_CFLAGS="$CFLAGS"
+
+# Set sane defaults for various variables
+test -z "$CC" && CC=cc
+test -z "$LTCC" && LTCC=$CC
+test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS
+test -z "$LD" && LD=ld
+test -z "$ac_objext" && ac_objext=o
+
+_LT_CC_BASENAME([$compiler])
+
+# Only perform the check for file, if the check method requires it
+test -z "$MAGIC_CMD" && MAGIC_CMD=file
+case $deplibs_check_method in
+file_magic*)
+ if test "$file_magic_cmd" = '$MAGIC_CMD'; then
+ _LT_PATH_MAGIC
+ fi
+ ;;
+esac
+
+# Use C for the default configuration in the libtool script
+LT_SUPPORTED_TAG([CC])
+_LT_LANG_C_CONFIG
+_LT_LANG_DEFAULT_CONFIG
+_LT_CONFIG_COMMANDS
+])# _LT_SETUP
+
+
+# _LT_PREPARE_SED_QUOTE_VARS
+# --------------------------
+# Define a few sed substitution that help us do robust quoting.
+m4_defun([_LT_PREPARE_SED_QUOTE_VARS],
+[# Backslashify metacharacters that are still active within
+# double-quoted strings.
+sed_quote_subst='s/\([["`$\\]]\)/\\\1/g'
+
+# Same as above, but do not quote variable references.
+double_quote_subst='s/\([["`\\]]\)/\\\1/g'
+
+# Sed substitution to delay expansion of an escaped shell variable in a
+# double_quote_subst'ed string.
+delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g'
+
+# Sed substitution to delay expansion of an escaped single quote.
+delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g'
+
+# Sed substitution to avoid accidental globbing in evaled expressions
+no_glob_subst='s/\*/\\\*/g'
+])
+
+# _LT_PROG_LTMAIN
+# ---------------
+# Note that this code is called both from `configure', and `config.status'
+# now that we use AC_CONFIG_COMMANDS to generate libtool. Notably,
+# `config.status' has no value for ac_aux_dir unless we are using Automake,
+# so we pass a copy along to make sure it has a sensible value anyway.
+m4_defun([_LT_PROG_LTMAIN],
+[m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl
+_LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir'])
+ltmain="$ac_aux_dir/ltmain.sh"
+])# _LT_PROG_LTMAIN
+
+
+## ------------------------------------- ##
+## Accumulate code for creating libtool. ##
+## ------------------------------------- ##
+
+# So that we can recreate a full libtool script including additional
+# tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS
+# in macros and then make a single call at the end using the `libtool'
+# label.
+
+
+# _LT_CONFIG_LIBTOOL_INIT([INIT-COMMANDS])
+# ----------------------------------------
+# Register INIT-COMMANDS to be passed to AC_CONFIG_COMMANDS later.
+m4_define([_LT_CONFIG_LIBTOOL_INIT],
+[m4_ifval([$1],
+ [m4_append([_LT_OUTPUT_LIBTOOL_INIT],
+ [$1
+])])])
+
+# Initialize.
+m4_define([_LT_OUTPUT_LIBTOOL_INIT])
+
+
+# _LT_CONFIG_LIBTOOL([COMMANDS])
+# ------------------------------
+# Register COMMANDS to be passed to AC_CONFIG_COMMANDS later.
+m4_define([_LT_CONFIG_LIBTOOL],
+[m4_ifval([$1],
+ [m4_append([_LT_OUTPUT_LIBTOOL_COMMANDS],
+ [$1
+])])])
+
+# Initialize.
+m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS])
+
+
+# _LT_CONFIG_SAVE_COMMANDS([COMMANDS], [INIT_COMMANDS])
+# -----------------------------------------------------
+m4_defun([_LT_CONFIG_SAVE_COMMANDS],
+[_LT_CONFIG_LIBTOOL([$1])
+_LT_CONFIG_LIBTOOL_INIT([$2])
+])
+
+
+# _LT_FORMAT_COMMENT([COMMENT])
+# -----------------------------
+# Add leading comment marks to the start of each line, and a trailing
+# full-stop to the whole comment if one is not present already.
+m4_define([_LT_FORMAT_COMMENT],
+[m4_ifval([$1], [
+m4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])],
+ [['`$\]], [\\\&])]m4_bmatch([$1], [[!?.]$], [], [.])
+)])
+
+
+
+## ------------------------ ##
+## FIXME: Eliminate VARNAME ##
+## ------------------------ ##
+
+
+# _LT_DECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION], [IS-TAGGED?])
+# -------------------------------------------------------------------
+# CONFIGNAME is the name given to the value in the libtool script.
+# VARNAME is the (base) name used in the configure script.
+# VALUE may be 0, 1 or 2 for a computed quote escaped value based on
+# VARNAME. Any other value will be used directly.
+m4_define([_LT_DECL],
+[lt_if_append_uniq([lt_decl_varnames], [$2], [, ],
+ [lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name],
+ [m4_ifval([$1], [$1], [$2])])
+ lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3])
+ m4_ifval([$4],
+ [lt_dict_add_subkey([lt_decl_dict], [$2], [description], [$4])])
+ lt_dict_add_subkey([lt_decl_dict], [$2],
+ [tagged?], [m4_ifval([$5], [yes], [no])])])
+])
+
+
+# _LT_TAGDECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION])
+# --------------------------------------------------------
+m4_define([_LT_TAGDECL], [_LT_DECL([$1], [$2], [$3], [$4], [yes])])
+
+
+# lt_decl_tag_varnames([SEPARATOR], [VARNAME1...])
+# ------------------------------------------------
+m4_define([lt_decl_tag_varnames],
+[_lt_decl_filter([tagged?], [yes], $@)])
+
+
+# _lt_decl_filter(SUBKEY, VALUE, [SEPARATOR], [VARNAME1..])
+# ---------------------------------------------------------
+m4_define([_lt_decl_filter],
+[m4_case([$#],
+ [0], [m4_fatal([$0: too few arguments: $#])],
+ [1], [m4_fatal([$0: too few arguments: $#: $1])],
+ [2], [lt_dict_filter([lt_decl_dict], [$1], [$2], [], lt_decl_varnames)],
+ [3], [lt_dict_filter([lt_decl_dict], [$1], [$2], [$3], lt_decl_varnames)],
+ [lt_dict_filter([lt_decl_dict], $@)])[]dnl
+])
+
+
+# lt_decl_quote_varnames([SEPARATOR], [VARNAME1...])
+# --------------------------------------------------
+m4_define([lt_decl_quote_varnames],
+[_lt_decl_filter([value], [1], $@)])
+
+
+# lt_decl_dquote_varnames([SEPARATOR], [VARNAME1...])
+# ---------------------------------------------------
+m4_define([lt_decl_dquote_varnames],
+[_lt_decl_filter([value], [2], $@)])
+
+
+# lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...])
+# ---------------------------------------------------
+m4_define([lt_decl_varnames_tagged],
+[m4_assert([$# <= 2])dnl
+_$0(m4_quote(m4_default([$1], [[, ]])),
+ m4_ifval([$2], [[$2]], [m4_dquote(lt_decl_tag_varnames)]),
+ m4_split(m4_normalize(m4_quote(_LT_TAGS)), [ ]))])
+m4_define([_lt_decl_varnames_tagged],
+[m4_ifval([$3], [lt_combine([$1], [$2], [_], $3)])])
+
+
+# lt_decl_all_varnames([SEPARATOR], [VARNAME1...])
+# ------------------------------------------------
+m4_define([lt_decl_all_varnames],
+[_$0(m4_quote(m4_default([$1], [[, ]])),
+ m4_if([$2], [],
+ m4_quote(lt_decl_varnames),
+ m4_quote(m4_shift($@))))[]dnl
+])
+m4_define([_lt_decl_all_varnames],
+[lt_join($@, lt_decl_varnames_tagged([$1],
+ lt_decl_tag_varnames([[, ]], m4_shift($@))))dnl
+])
+
+
+# _LT_CONFIG_STATUS_DECLARE([VARNAME])
+# ------------------------------------
+# Quote a variable value, and forward it to `config.status' so that its
+# declaration there will have the same value as in `configure'. VARNAME
+# must have a single quote delimited value for this to work.
+m4_define([_LT_CONFIG_STATUS_DECLARE],
+[$1='`$ECHO "$][$1" | $SED "$delay_single_quote_subst"`'])
+
+
+# _LT_CONFIG_STATUS_DECLARATIONS
+# ------------------------------
+# We delimit libtool config variables with single quotes, so when
+# we write them to config.status, we have to be sure to quote all
+# embedded single quotes properly. In configure, this macro expands
+# each variable declared with _LT_DECL (and _LT_TAGDECL) into:
+#
+# <var>='`$ECHO "$<var>" | $SED "$delay_single_quote_subst"`'
+m4_defun([_LT_CONFIG_STATUS_DECLARATIONS],
+[m4_foreach([_lt_var], m4_quote(lt_decl_all_varnames),
+ [m4_n([_LT_CONFIG_STATUS_DECLARE(_lt_var)])])])
+
+
+# _LT_LIBTOOL_TAGS
+# ----------------
+# Output comment and list of tags supported by the script
+m4_defun([_LT_LIBTOOL_TAGS],
+[_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl
+available_tags="_LT_TAGS"dnl
+])
+
+
+# _LT_LIBTOOL_DECLARE(VARNAME, [TAG])
+# -----------------------------------
+# Extract the dictionary values for VARNAME (optionally with TAG) and
+# expand to a commented shell variable setting:
+#
+# # Some comment about what VAR is for.
+# visible_name=$lt_internal_name
+m4_define([_LT_LIBTOOL_DECLARE],
+[_LT_FORMAT_COMMENT(m4_quote(lt_dict_fetch([lt_decl_dict], [$1],
+ [description])))[]dnl
+m4_pushdef([_libtool_name],
+ m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [libtool_name])))[]dnl
+m4_case(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [value])),
+ [0], [_libtool_name=[$]$1],
+ [1], [_libtool_name=$lt_[]$1],
+ [2], [_libtool_name=$lt_[]$1],
+ [_libtool_name=lt_dict_fetch([lt_decl_dict], [$1], [value])])[]dnl
+m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl
+])
+
+
+# _LT_LIBTOOL_CONFIG_VARS
+# -----------------------
+# Produce commented declarations of non-tagged libtool config variables
+# suitable for insertion in the LIBTOOL CONFIG section of the `libtool'
+# script. Tagged libtool config variables (even for the LIBTOOL CONFIG
+# section) are produced by _LT_LIBTOOL_TAG_VARS.
+m4_defun([_LT_LIBTOOL_CONFIG_VARS],
+[m4_foreach([_lt_var],
+ m4_quote(_lt_decl_filter([tagged?], [no], [], lt_decl_varnames)),
+ [m4_n([_LT_LIBTOOL_DECLARE(_lt_var)])])])
+
+
+# _LT_LIBTOOL_TAG_VARS(TAG)
+# -------------------------
+m4_define([_LT_LIBTOOL_TAG_VARS],
+[m4_foreach([_lt_var], m4_quote(lt_decl_tag_varnames),
+ [m4_n([_LT_LIBTOOL_DECLARE(_lt_var, [$1])])])])
+
+
+# _LT_TAGVAR(VARNAME, [TAGNAME])
+# ------------------------------
+m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])])
+
+
+# _LT_CONFIG_COMMANDS
+# -------------------
+# Send accumulated output to $CONFIG_STATUS. Thanks to the lists of
+# variables for single and double quote escaping we saved from calls
+# to _LT_DECL, we can put quote escaped variables declarations
+# into `config.status', and then the shell code to quote escape them in
+# for loops in `config.status'. Finally, any additional code accumulated
+# from calls to _LT_CONFIG_LIBTOOL_INIT is expanded.
+m4_defun([_LT_CONFIG_COMMANDS],
+[AC_PROVIDE_IFELSE([LT_OUTPUT],
+ dnl If the libtool generation code has been placed in $CONFIG_LT,
+ dnl instead of duplicating it all over again into config.status,
+ dnl then we will have config.status run $CONFIG_LT later, so it
+ dnl needs to know what name is stored there:
+ [AC_CONFIG_COMMANDS([libtool],
+ [$SHELL $CONFIG_LT || AS_EXIT(1)], [CONFIG_LT='$CONFIG_LT'])],
+ dnl If the libtool generation code is destined for config.status,
+ dnl expand the accumulated commands and init code now:
+ [AC_CONFIG_COMMANDS([libtool],
+ [_LT_OUTPUT_LIBTOOL_COMMANDS], [_LT_OUTPUT_LIBTOOL_COMMANDS_INIT])])
+])#_LT_CONFIG_COMMANDS
+
+
+# Initialize.
+m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS_INIT],
+[
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+sed_quote_subst='$sed_quote_subst'
+double_quote_subst='$double_quote_subst'
+delay_variable_subst='$delay_variable_subst'
+_LT_CONFIG_STATUS_DECLARATIONS
+LTCC='$LTCC'
+LTCFLAGS='$LTCFLAGS'
+compiler='$compiler_DEFAULT'
+
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
+{
+ eval 'cat <<_LTECHO_EOF
+\$[]1
+_LTECHO_EOF'
+}
+
+# Quote evaled strings.
+for var in lt_decl_all_varnames([[ \
+]], lt_decl_quote_varnames); do
+ case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
+ *[[\\\\\\\`\\"\\\$]]*)
+ eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\""
+ ;;
+ *)
+ eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+ ;;
+ esac
+done
+
+# Double-quote double-evaled strings.
+for var in lt_decl_all_varnames([[ \
+]], lt_decl_dquote_varnames); do
+ case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
+ *[[\\\\\\\`\\"\\\$]]*)
+ eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\""
+ ;;
+ *)
+ eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+ ;;
+ esac
+done
+
+_LT_OUTPUT_LIBTOOL_INIT
+])
+
+# _LT_GENERATED_FILE_INIT(FILE, [COMMENT])
+# ------------------------------------
+# Generate a child script FILE with all initialization necessary to
+# reuse the environment learned by the parent script, and make the
+# file executable. If COMMENT is supplied, it is inserted after the
+# `#!' sequence but before initialization text begins. After this
+# macro, additional text can be appended to FILE to form the body of
+# the child script. The macro ends with non-zero status if the
+# file could not be fully written (such as if the disk is full).
+m4_ifdef([AS_INIT_GENERATED],
+[m4_defun([_LT_GENERATED_FILE_INIT],[AS_INIT_GENERATED($@)])],
+[m4_defun([_LT_GENERATED_FILE_INIT],
+[m4_require([AS_PREPARE])]dnl
+[m4_pushdef([AS_MESSAGE_LOG_FD])]dnl
+[lt_write_fail=0
+cat >$1 <<_ASEOF || lt_write_fail=1
+#! $SHELL
+# Generated by $as_me.
+$2
+SHELL=\${CONFIG_SHELL-$SHELL}
+export SHELL
+_ASEOF
+cat >>$1 <<\_ASEOF || lt_write_fail=1
+AS_SHELL_SANITIZE
+_AS_PREPARE
+exec AS_MESSAGE_FD>&1
+_ASEOF
+test $lt_write_fail = 0 && chmod +x $1[]dnl
+m4_popdef([AS_MESSAGE_LOG_FD])])])# _LT_GENERATED_FILE_INIT
+
+# LT_OUTPUT
+# ---------
+# This macro allows early generation of the libtool script (before
+# AC_OUTPUT is called), incase it is used in configure for compilation
+# tests.
+AC_DEFUN([LT_OUTPUT],
+[: ${CONFIG_LT=./config.lt}
+AC_MSG_NOTICE([creating $CONFIG_LT])
+_LT_GENERATED_FILE_INIT(["$CONFIG_LT"],
+[# Run this file to recreate a libtool stub with the current configuration.])
+
+cat >>"$CONFIG_LT" <<\_LTEOF
+lt_cl_silent=false
+exec AS_MESSAGE_LOG_FD>>config.log
+{
+ echo
+ AS_BOX([Running $as_me.])
+} >&AS_MESSAGE_LOG_FD
+
+lt_cl_help="\
+\`$as_me' creates a local libtool stub from the current configuration,
+for use in further configure time tests before the real libtool is
+generated.
+
+Usage: $[0] [[OPTIONS]]
+
+ -h, --help print this help, then exit
+ -V, --version print version number, then exit
+ -q, --quiet do not print progress messages
+ -d, --debug don't remove temporary files
+
+Report bugs to <bug-libtool@gnu.org>."
+
+lt_cl_version="\
+m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl
+m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION])
+configured by $[0], generated by m4_PACKAGE_STRING.
+
+Copyright (C) 2011 Free Software Foundation, Inc.
+This config.lt script is free software; the Free Software Foundation
+gives unlimited permision to copy, distribute and modify it."
+
+while test $[#] != 0
+do
+ case $[1] in
+ --version | --v* | -V )
+ echo "$lt_cl_version"; exit 0 ;;
+ --help | --h* | -h )
+ echo "$lt_cl_help"; exit 0 ;;
+ --debug | --d* | -d )
+ debug=: ;;
+ --quiet | --q* | --silent | --s* | -q )
+ lt_cl_silent=: ;;
+
+ -*) AC_MSG_ERROR([unrecognized option: $[1]
+Try \`$[0] --help' for more information.]) ;;
+
+ *) AC_MSG_ERROR([unrecognized argument: $[1]
+Try \`$[0] --help' for more information.]) ;;
+ esac
+ shift
+done
+
+if $lt_cl_silent; then
+ exec AS_MESSAGE_FD>/dev/null
+fi
+_LTEOF
+
+cat >>"$CONFIG_LT" <<_LTEOF
+_LT_OUTPUT_LIBTOOL_COMMANDS_INIT
+_LTEOF
+
+cat >>"$CONFIG_LT" <<\_LTEOF
+AC_MSG_NOTICE([creating $ofile])
+_LT_OUTPUT_LIBTOOL_COMMANDS
+AS_EXIT(0)
+_LTEOF
+chmod +x "$CONFIG_LT"
+
+# configure is writing to config.log, but config.lt does its own redirection,
+# appending to config.log, which fails on DOS, as config.log is still kept
+# open by configure. Here we exec the FD to /dev/null, effectively closing
+# config.log, so it can be properly (re)opened and appended to by config.lt.
+lt_cl_success=:
+test "$silent" = yes &&
+ lt_config_lt_args="$lt_config_lt_args --quiet"
+exec AS_MESSAGE_LOG_FD>/dev/null
+$SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false
+exec AS_MESSAGE_LOG_FD>>config.log
+$lt_cl_success || AS_EXIT(1)
+])# LT_OUTPUT
+
+
+# _LT_CONFIG(TAG)
+# ---------------
+# If TAG is the built-in tag, create an initial libtool script with a
+# default configuration from the untagged config vars. Otherwise add code
+# to config.status for appending the configuration named by TAG from the
+# matching tagged config vars.
+m4_defun([_LT_CONFIG],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+_LT_CONFIG_SAVE_COMMANDS([
+ m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl
+ m4_if(_LT_TAG, [C], [
+ # See if we are running on zsh, and set the options which allow our
+ # commands through without removal of \ escapes.
+ if test -n "${ZSH_VERSION+set}" ; then
+ setopt NO_GLOB_SUBST
+ fi
+
+ cfgfile="${ofile}T"
+ trap "$RM \"$cfgfile\"; exit 1" 1 2 15
+ $RM "$cfgfile"
+
+ cat <<_LT_EOF >> "$cfgfile"
+#! $SHELL
+
+# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services.
+# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION
+# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+# NOTE: Changes made to this file will be lost: look at ltmain.sh.
+#
+_LT_COPYING
+_LT_LIBTOOL_TAGS
+
+# ### BEGIN LIBTOOL CONFIG
+_LT_LIBTOOL_CONFIG_VARS
+_LT_LIBTOOL_TAG_VARS
+# ### END LIBTOOL CONFIG
+
+_LT_EOF
+
+ case $host_os in
+ aix3*)
+ cat <<\_LT_EOF >> "$cfgfile"
+# AIX sometimes has problems with the GCC collect2 program. For some
+# reason, if we set the COLLECT_NAMES environment variable, the problems
+# vanish in a puff of smoke.
+if test "X${COLLECT_NAMES+set}" != Xset; then
+ COLLECT_NAMES=
+ export COLLECT_NAMES
+fi
+_LT_EOF
+ ;;
+ esac
+
+ _LT_PROG_LTMAIN
+
+ # We use sed instead of cat because bash on DJGPP gets confused if
+ # if finds mixed CR/LF and LF-only lines. Since sed operates in
+ # text mode, it properly converts lines to CR/LF. This bash problem
+ # is reportedly fixed, but why not run on old versions too?
+ sed '$q' "$ltmain" >> "$cfgfile" \
+ || (rm -f "$cfgfile"; exit 1)
+
+ _LT_PROG_REPLACE_SHELLFNS
+
+ mv -f "$cfgfile" "$ofile" ||
+ (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile")
+ chmod +x "$ofile"
+],
+[cat <<_LT_EOF >> "$ofile"
+
+dnl Unfortunately we have to use $1 here, since _LT_TAG is not expanded
+dnl in a comment (ie after a #).
+# ### BEGIN LIBTOOL TAG CONFIG: $1
+_LT_LIBTOOL_TAG_VARS(_LT_TAG)
+# ### END LIBTOOL TAG CONFIG: $1
+_LT_EOF
+])dnl /m4_if
+],
+[m4_if([$1], [], [
+ PACKAGE='$PACKAGE'
+ VERSION='$VERSION'
+ TIMESTAMP='$TIMESTAMP'
+ RM='$RM'
+ ofile='$ofile'], [])
+])dnl /_LT_CONFIG_SAVE_COMMANDS
+])# _LT_CONFIG
+
+
+# LT_SUPPORTED_TAG(TAG)
+# ---------------------
+# Trace this macro to discover what tags are supported by the libtool
+# --tag option, using:
+# autoconf --trace 'LT_SUPPORTED_TAG:$1'
+AC_DEFUN([LT_SUPPORTED_TAG], [])
+
+
+# C support is built-in for now
+m4_define([_LT_LANG_C_enabled], [])
+m4_define([_LT_TAGS], [])
+
+
+# LT_LANG(LANG)
+# -------------
+# Enable libtool support for the given language if not already enabled.
+AC_DEFUN([LT_LANG],
+[AC_BEFORE([$0], [LT_OUTPUT])dnl
+m4_case([$1],
+ [C], [_LT_LANG(C)],
+ [C++], [_LT_LANG(CXX)],
+ [Go], [_LT_LANG(GO)],
+ [Java], [_LT_LANG(GCJ)],
+ [Fortran 77], [_LT_LANG(F77)],
+ [Fortran], [_LT_LANG(FC)],
+ [Windows Resource], [_LT_LANG(RC)],
+ [m4_ifdef([_LT_LANG_]$1[_CONFIG],
+ [_LT_LANG($1)],
+ [m4_fatal([$0: unsupported language: "$1"])])])dnl
+])# LT_LANG
+
+
+# _LT_LANG(LANGNAME)
+# ------------------
+m4_defun([_LT_LANG],
+[m4_ifdef([_LT_LANG_]$1[_enabled], [],
+ [LT_SUPPORTED_TAG([$1])dnl
+ m4_append([_LT_TAGS], [$1 ])dnl
+ m4_define([_LT_LANG_]$1[_enabled], [])dnl
+ _LT_LANG_$1_CONFIG($1)])dnl
+])# _LT_LANG
+
+
+m4_ifndef([AC_PROG_GO], [
+############################################################
+# NOTE: This macro has been submitted for inclusion into #
+# GNU Autoconf as AC_PROG_GO. When it is available in #
+# a released version of Autoconf we should remove this #
+# macro and use it instead. #
+############################################################
+m4_defun([AC_PROG_GO],
+[AC_LANG_PUSH(Go)dnl
+AC_ARG_VAR([GOC], [Go compiler command])dnl
+AC_ARG_VAR([GOFLAGS], [Go compiler flags])dnl
+_AC_ARG_VAR_LDFLAGS()dnl
+AC_CHECK_TOOL(GOC, gccgo)
+if test -z "$GOC"; then
+ if test -n "$ac_tool_prefix"; then
+ AC_CHECK_PROG(GOC, [${ac_tool_prefix}gccgo], [${ac_tool_prefix}gccgo])
+ fi
+fi
+if test -z "$GOC"; then
+ AC_CHECK_PROG(GOC, gccgo, gccgo, false)
+fi
+])#m4_defun
+])#m4_ifndef
+
+
+# _LT_LANG_DEFAULT_CONFIG
+# -----------------------
+m4_defun([_LT_LANG_DEFAULT_CONFIG],
+[AC_PROVIDE_IFELSE([AC_PROG_CXX],
+ [LT_LANG(CXX)],
+ [m4_define([AC_PROG_CXX], defn([AC_PROG_CXX])[LT_LANG(CXX)])])
+
+AC_PROVIDE_IFELSE([AC_PROG_F77],
+ [LT_LANG(F77)],
+ [m4_define([AC_PROG_F77], defn([AC_PROG_F77])[LT_LANG(F77)])])
+
+AC_PROVIDE_IFELSE([AC_PROG_FC],
+ [LT_LANG(FC)],
+ [m4_define([AC_PROG_FC], defn([AC_PROG_FC])[LT_LANG(FC)])])
+
+dnl The call to [A][M_PROG_GCJ] is quoted like that to stop aclocal
+dnl pulling things in needlessly.
+AC_PROVIDE_IFELSE([AC_PROG_GCJ],
+ [LT_LANG(GCJ)],
+ [AC_PROVIDE_IFELSE([A][M_PROG_GCJ],
+ [LT_LANG(GCJ)],
+ [AC_PROVIDE_IFELSE([LT_PROG_GCJ],
+ [LT_LANG(GCJ)],
+ [m4_ifdef([AC_PROG_GCJ],
+ [m4_define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[LT_LANG(GCJ)])])
+ m4_ifdef([A][M_PROG_GCJ],
+ [m4_define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[LT_LANG(GCJ)])])
+ m4_ifdef([LT_PROG_GCJ],
+ [m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])])
+
+AC_PROVIDE_IFELSE([AC_PROG_GO],
+ [LT_LANG(GO)],
+ [m4_define([AC_PROG_GO], defn([AC_PROG_GO])[LT_LANG(GO)])])
+
+AC_PROVIDE_IFELSE([LT_PROG_RC],
+ [LT_LANG(RC)],
+ [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])])
+])# _LT_LANG_DEFAULT_CONFIG
+
+# Obsolete macros:
+AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)])
+AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)])
+AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)])
+AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)])
+AU_DEFUN([AC_LIBTOOL_RC], [LT_LANG(Windows Resource)])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_CXX], [])
+dnl AC_DEFUN([AC_LIBTOOL_F77], [])
+dnl AC_DEFUN([AC_LIBTOOL_FC], [])
+dnl AC_DEFUN([AC_LIBTOOL_GCJ], [])
+dnl AC_DEFUN([AC_LIBTOOL_RC], [])
+
+
+# _LT_TAG_COMPILER
+# ----------------
+m4_defun([_LT_TAG_COMPILER],
+[AC_REQUIRE([AC_PROG_CC])dnl
+
+_LT_DECL([LTCC], [CC], [1], [A C compiler])dnl
+_LT_DECL([LTCFLAGS], [CFLAGS], [1], [LTCC compiler flags])dnl
+_LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl
+_LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])dnl
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+])# _LT_TAG_COMPILER
+
+
+# _LT_COMPILER_BOILERPLATE
+# ------------------------
+# Check for compiler boilerplate output or warnings with
+# the simple compiler test code.
+m4_defun([_LT_COMPILER_BOILERPLATE],
+[m4_require([_LT_DECL_SED])dnl
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_compile_test_code" >conftest.$ac_ext
+eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_compiler_boilerplate=`cat conftest.err`
+$RM conftest*
+])# _LT_COMPILER_BOILERPLATE
+
+
+# _LT_LINKER_BOILERPLATE
+# ----------------------
+# Check for linker boilerplate output or warnings with
+# the simple link test code.
+m4_defun([_LT_LINKER_BOILERPLATE],
+[m4_require([_LT_DECL_SED])dnl
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_link_test_code" >conftest.$ac_ext
+eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_linker_boilerplate=`cat conftest.err`
+$RM -r conftest*
+])# _LT_LINKER_BOILERPLATE
+
+# _LT_REQUIRED_DARWIN_CHECKS
+# -------------------------
+m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[
+ case $host_os in
+ rhapsody* | darwin*)
+ AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:])
+ AC_CHECK_TOOL([NMEDIT], [nmedit], [:])
+ AC_CHECK_TOOL([LIPO], [lipo], [:])
+ AC_CHECK_TOOL([OTOOL], [otool], [:])
+ AC_CHECK_TOOL([OTOOL64], [otool64], [:])
+ _LT_DECL([], [DSYMUTIL], [1],
+ [Tool to manipulate archived DWARF debug symbol files on Mac OS X])
+ _LT_DECL([], [NMEDIT], [1],
+ [Tool to change global to local symbols on Mac OS X])
+ _LT_DECL([], [LIPO], [1],
+ [Tool to manipulate fat objects and archives on Mac OS X])
+ _LT_DECL([], [OTOOL], [1],
+ [ldd/readelf like tool for Mach-O binaries on Mac OS X])
+ _LT_DECL([], [OTOOL64], [1],
+ [ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4])
+
+ AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod],
+ [lt_cv_apple_cc_single_mod=no
+ if test -z "${LT_MULTI_MODULE}"; then
+ # By default we will add the -single_module flag. You can override
+ # by either setting the environment variable LT_MULTI_MODULE
+ # non-empty at configure time, or by adding -multi_module to the
+ # link flags.
+ rm -rf libconftest.dylib*
+ echo "int foo(void){return 1;}" > conftest.c
+ echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
+-dynamiclib -Wl,-single_module conftest.c" >&AS_MESSAGE_LOG_FD
+ $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
+ -dynamiclib -Wl,-single_module conftest.c 2>conftest.err
+ _lt_result=$?
+ # If there is a non-empty error log, and "single_module"
+ # appears in it, assume the flag caused a linker warning
+ if test -s conftest.err && $GREP single_module conftest.err; then
+ cat conftest.err >&AS_MESSAGE_LOG_FD
+ # Otherwise, if the output was created with a 0 exit code from
+ # the compiler, it worked.
+ elif test -f libconftest.dylib && test $_lt_result -eq 0; then
+ lt_cv_apple_cc_single_mod=yes
+ else
+ cat conftest.err >&AS_MESSAGE_LOG_FD
+ fi
+ rm -rf libconftest.dylib*
+ rm -f conftest.*
+ fi])
+
+ AC_CACHE_CHECK([for -exported_symbols_list linker flag],
+ [lt_cv_ld_exported_symbols_list],
+ [lt_cv_ld_exported_symbols_list=no
+ save_LDFLAGS=$LDFLAGS
+ echo "_main" > conftest.sym
+ LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym"
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])],
+ [lt_cv_ld_exported_symbols_list=yes],
+ [lt_cv_ld_exported_symbols_list=no])
+ LDFLAGS="$save_LDFLAGS"
+ ])
+
+ AC_CACHE_CHECK([for -force_load linker flag],[lt_cv_ld_force_load],
+ [lt_cv_ld_force_load=no
+ cat > conftest.c << _LT_EOF
+int forced_loaded() { return 2;}
+_LT_EOF
+ echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&AS_MESSAGE_LOG_FD
+ $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD
+ echo "$AR cru libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD
+ $AR cru libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD
+ echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD
+ $RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD
+ cat > conftest.c << _LT_EOF
+int main() { return 0;}
+_LT_EOF
+ echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&AS_MESSAGE_LOG_FD
+ $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err
+ _lt_result=$?
+ if test -s conftest.err && $GREP force_load conftest.err; then
+ cat conftest.err >&AS_MESSAGE_LOG_FD
+ elif test -f conftest && test $_lt_result -eq 0 && $GREP forced_load conftest >/dev/null 2>&1 ; then
+ lt_cv_ld_force_load=yes
+ else
+ cat conftest.err >&AS_MESSAGE_LOG_FD
+ fi
+ rm -f conftest.err libconftest.a conftest conftest.c
+ rm -rf conftest.dSYM
+ ])
+ case $host_os in
+ rhapsody* | darwin1.[[012]])
+ _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;;
+ darwin1.*)
+ _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
+ darwin*) # darwin 5.x on
+ # if running on 10.5 or later, the deployment target defaults
+ # to the OS version, if on x86, and 10.4, the deployment
+ # target defaults to 10.4. Don't you love it?
+ case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in
+ 10.0,*86*-darwin8*|10.0,*-darwin[[91]]*)
+ _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
+ 10.[[012]]*)
+ _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
+ 10.*)
+ _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
+ esac
+ ;;
+ esac
+ if test "$lt_cv_apple_cc_single_mod" = "yes"; then
+ _lt_dar_single_mod='$single_module'
+ fi
+ if test "$lt_cv_ld_exported_symbols_list" = "yes"; then
+ _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym'
+ else
+ _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}'
+ fi
+ if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then
+ _lt_dsymutil='~$DSYMUTIL $lib || :'
+ else
+ _lt_dsymutil=
+ fi
+ ;;
+ esac
+])
+
+
+# _LT_DARWIN_LINKER_FEATURES([TAG])
+# ---------------------------------
+# Checks for linker and compiler features on darwin
+m4_defun([_LT_DARWIN_LINKER_FEATURES],
+[
+ m4_require([_LT_REQUIRED_DARWIN_CHECKS])
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ _LT_TAGVAR(hardcode_automatic, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
+ if test "$lt_cv_ld_force_load" = "yes"; then
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`'
+ m4_case([$1], [F77], [_LT_TAGVAR(compiler_needs_object, $1)=yes],
+ [FC], [_LT_TAGVAR(compiler_needs_object, $1)=yes])
+ else
+ _LT_TAGVAR(whole_archive_flag_spec, $1)=''
+ fi
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ _LT_TAGVAR(allow_undefined_flag, $1)="$_lt_dar_allow_undefined"
+ case $cc_basename in
+ ifort*) _lt_dar_can_shared=yes ;;
+ *) _lt_dar_can_shared=$GCC ;;
+ esac
+ if test "$_lt_dar_can_shared" = "yes"; then
+ output_verbose_link_cmd=func_echo_all
+ _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}"
+ _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}"
+ _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}"
+ _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}"
+ m4_if([$1], [CXX],
+[ if test "$lt_cv_apple_cc_single_mod" != "yes"; then
+ _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}"
+ _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}"
+ fi
+],[])
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+])
+
+# _LT_SYS_MODULE_PATH_AIX([TAGNAME])
+# ----------------------------------
+# Links a minimal program and checks the executable
+# for the system default hardcoded library path. In most cases,
+# this is /usr/lib:/lib, but when the MPI compilers are used
+# the location of the communication and MPI libs are included too.
+# If we don't find anything, use the default library path according
+# to the aix ld manual.
+# Store the results from the different compilers for each TAGNAME.
+# Allow to override them for all tags through lt_cv_aix_libpath.
+m4_defun([_LT_SYS_MODULE_PATH_AIX],
+[m4_require([_LT_DECL_SED])dnl
+if test "${lt_cv_aix_libpath+set}" = set; then
+ aix_libpath=$lt_cv_aix_libpath
+else
+ AC_CACHE_VAL([_LT_TAGVAR([lt_cv_aix_libpath_], [$1])],
+ [AC_LINK_IFELSE([AC_LANG_PROGRAM],[
+ lt_aix_libpath_sed='[
+ /Import File Strings/,/^$/ {
+ /^0/ {
+ s/^0 *\([^ ]*\) *$/\1/
+ p
+ }
+ }]'
+ _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+ # Check for a 64-bit object if we didn't find anything.
+ if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then
+ _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+ fi],[])
+ if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then
+ _LT_TAGVAR([lt_cv_aix_libpath_], [$1])="/usr/lib:/lib"
+ fi
+ ])
+ aix_libpath=$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])
+fi
+])# _LT_SYS_MODULE_PATH_AIX
+
+
+# _LT_SHELL_INIT(ARG)
+# -------------------
+m4_define([_LT_SHELL_INIT],
+[m4_divert_text([M4SH-INIT], [$1
+])])# _LT_SHELL_INIT
+
+
+
+# _LT_PROG_ECHO_BACKSLASH
+# -----------------------
+# Find how we can fake an echo command that does not interpret backslash.
+# In particular, with Autoconf 2.60 or later we add some code to the start
+# of the generated configure script which will find a shell with a builtin
+# printf (which we can use as an echo command).
+m4_defun([_LT_PROG_ECHO_BACKSLASH],
+[ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO
+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO
+
+AC_MSG_CHECKING([how to print strings])
+# Test print first, because it will be a builtin if present.
+if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \
+ test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then
+ ECHO='print -r --'
+elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then
+ ECHO='printf %s\n'
+else
+ # Use this function as a fallback that always works.
+ func_fallback_echo ()
+ {
+ eval 'cat <<_LTECHO_EOF
+$[]1
+_LTECHO_EOF'
+ }
+ ECHO='func_fallback_echo'
+fi
+
+# func_echo_all arg...
+# Invoke $ECHO with all args, space-separated.
+func_echo_all ()
+{
+ $ECHO "$*"
+}
+
+case "$ECHO" in
+ printf*) AC_MSG_RESULT([printf]) ;;
+ print*) AC_MSG_RESULT([print -r]) ;;
+ *) AC_MSG_RESULT([cat]) ;;
+esac
+
+m4_ifdef([_AS_DETECT_SUGGESTED],
+[_AS_DETECT_SUGGESTED([
+ test -n "${ZSH_VERSION+set}${BASH_VERSION+set}" || (
+ ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+ ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO
+ ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO
+ PATH=/empty FPATH=/empty; export PATH FPATH
+ test "X`printf %s $ECHO`" = "X$ECHO" \
+ || test "X`print -r -- $ECHO`" = "X$ECHO" )])])
+
+_LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts])
+_LT_DECL([], [ECHO], [1], [An echo program that protects backslashes])
+])# _LT_PROG_ECHO_BACKSLASH
+
+
+# _LT_WITH_SYSROOT
+# ----------------
+AC_DEFUN([_LT_WITH_SYSROOT],
+[AC_MSG_CHECKING([for sysroot])
+AC_ARG_WITH([sysroot],
+[ --with-sysroot[=DIR] Search for dependent libraries within DIR
+ (or the compiler's sysroot if not specified).],
+[], [with_sysroot=no])
+
+dnl lt_sysroot will always be passed unquoted. We quote it here
+dnl in case the user passed a directory name.
+lt_sysroot=
+case ${with_sysroot} in #(
+ yes)
+ if test "$GCC" = yes; then
+ lt_sysroot=`$CC --print-sysroot 2>/dev/null`
+ fi
+ ;; #(
+ /*)
+ lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"`
+ ;; #(
+ no|'')
+ ;; #(
+ *)
+ AC_MSG_RESULT([${with_sysroot}])
+ AC_MSG_ERROR([The sysroot must be an absolute path.])
+ ;;
+esac
+
+ AC_MSG_RESULT([${lt_sysroot:-no}])
+_LT_DECL([], [lt_sysroot], [0], [The root where to search for ]dnl
+[dependent libraries, and in which our libraries should be installed.])])
+
+# _LT_ENABLE_LOCK
+# ---------------
+m4_defun([_LT_ENABLE_LOCK],
+[AC_ARG_ENABLE([libtool-lock],
+ [AS_HELP_STRING([--disable-libtool-lock],
+ [avoid locking (might break parallel builds)])])
+test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case $host in
+ia64-*-hpux*)
+ # Find out which ABI we are using.
+ echo 'int i;' > conftest.$ac_ext
+ if AC_TRY_EVAL(ac_compile); then
+ case `/usr/bin/file conftest.$ac_objext` in
+ *ELF-32*)
+ HPUX_IA64_MODE="32"
+ ;;
+ *ELF-64*)
+ HPUX_IA64_MODE="64"
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+*-*-irix6*)
+ # Find out which ABI we are using.
+ echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext
+ if AC_TRY_EVAL(ac_compile); then
+ if test "$lt_cv_prog_gnu_ld" = yes; then
+ case `/usr/bin/file conftest.$ac_objext` in
+ *32-bit*)
+ LD="${LD-ld} -melf32bsmip"
+ ;;
+ *N32*)
+ LD="${LD-ld} -melf32bmipn32"
+ ;;
+ *64-bit*)
+ LD="${LD-ld} -melf64bmip"
+ ;;
+ esac
+ else
+ case `/usr/bin/file conftest.$ac_objext` in
+ *32-bit*)
+ LD="${LD-ld} -32"
+ ;;
+ *N32*)
+ LD="${LD-ld} -n32"
+ ;;
+ *64-bit*)
+ LD="${LD-ld} -64"
+ ;;
+ esac
+ fi
+ fi
+ rm -rf conftest*
+ ;;
+
+x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \
+s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
+ # Find out which ABI we are using.
+ echo 'int i;' > conftest.$ac_ext
+ if AC_TRY_EVAL(ac_compile); then
+ case `/usr/bin/file conftest.o` in
+ *32-bit*)
+ case $host in
+ x86_64-*kfreebsd*-gnu)
+ LD="${LD-ld} -m elf_i386_fbsd"
+ ;;
+ x86_64-*linux*)
+ LD="${LD-ld} -m elf_i386"
+ ;;
+ ppc64-*linux*|powerpc64-*linux*)
+ LD="${LD-ld} -m elf32ppclinux"
+ ;;
+ s390x-*linux*)
+ LD="${LD-ld} -m elf_s390"
+ ;;
+ sparc64-*linux*)
+ LD="${LD-ld} -m elf32_sparc"
+ ;;
+ esac
+ ;;
+ *64-bit*)
+ case $host in
+ x86_64-*kfreebsd*-gnu)
+ LD="${LD-ld} -m elf_x86_64_fbsd"
+ ;;
+ x86_64-*linux*)
+ LD="${LD-ld} -m elf_x86_64"
+ ;;
+ ppc*-*linux*|powerpc*-*linux*)
+ LD="${LD-ld} -m elf64ppc"
+ ;;
+ s390*-*linux*|s390*-*tpf*)
+ LD="${LD-ld} -m elf64_s390"
+ ;;
+ sparc*-*linux*)
+ LD="${LD-ld} -m elf64_sparc"
+ ;;
+ esac
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+
+*-*-sco3.2v5*)
+ # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+ SAVE_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -belf"
+ AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf,
+ [AC_LANG_PUSH(C)
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no])
+ AC_LANG_POP])
+ if test x"$lt_cv_cc_needs_belf" != x"yes"; then
+ # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
+ CFLAGS="$SAVE_CFLAGS"
+ fi
+ ;;
+*-*solaris*)
+ # Find out which ABI we are using.
+ echo 'int i;' > conftest.$ac_ext
+ if AC_TRY_EVAL(ac_compile); then
+ case `/usr/bin/file conftest.o` in
+ *64-bit*)
+ case $lt_cv_prog_gnu_ld in
+ yes*)
+ case $host in
+ i?86-*-solaris*)
+ LD="${LD-ld} -m elf_x86_64"
+ ;;
+ sparc*-*-solaris*)
+ LD="${LD-ld} -m elf64_sparc"
+ ;;
+ esac
+ # GNU ld 2.21 introduced _sol2 emulations. Use them if available.
+ if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then
+ LD="${LD-ld}_sol2"
+ fi
+ ;;
+ *)
+ if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then
+ LD="${LD-ld} -64"
+ fi
+ ;;
+ esac
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+esac
+
+need_locks="$enable_libtool_lock"
+])# _LT_ENABLE_LOCK
+
+
+# _LT_PROG_AR
+# -----------
+m4_defun([_LT_PROG_AR],
+[AC_CHECK_TOOLS(AR, [ar], false)
+: ${AR=ar}
+: ${AR_FLAGS=cru}
+_LT_DECL([], [AR], [1], [The archiver])
+_LT_DECL([], [AR_FLAGS], [1], [Flags to create an archive])
+
+AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file],
+ [lt_cv_ar_at_file=no
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM],
+ [echo conftest.$ac_objext > conftest.lst
+ lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&AS_MESSAGE_LOG_FD'
+ AC_TRY_EVAL([lt_ar_try])
+ if test "$ac_status" -eq 0; then
+ # Ensure the archiver fails upon bogus file names.
+ rm -f conftest.$ac_objext libconftest.a
+ AC_TRY_EVAL([lt_ar_try])
+ if test "$ac_status" -ne 0; then
+ lt_cv_ar_at_file=@
+ fi
+ fi
+ rm -f conftest.* libconftest.a
+ ])
+ ])
+
+if test "x$lt_cv_ar_at_file" = xno; then
+ archiver_list_spec=
+else
+ archiver_list_spec=$lt_cv_ar_at_file
+fi
+_LT_DECL([], [archiver_list_spec], [1],
+ [How to feed a file listing to the archiver])
+])# _LT_PROG_AR
+
+
+# _LT_CMD_OLD_ARCHIVE
+# -------------------
+m4_defun([_LT_CMD_OLD_ARCHIVE],
+[_LT_PROG_AR
+
+AC_CHECK_TOOL(STRIP, strip, :)
+test -z "$STRIP" && STRIP=:
+_LT_DECL([], [STRIP], [1], [A symbol stripping program])
+
+AC_CHECK_TOOL(RANLIB, ranlib, :)
+test -z "$RANLIB" && RANLIB=:
+_LT_DECL([], [RANLIB], [1],
+ [Commands used to install an old-style archive])
+
+# Determine commands to create old-style static archives.
+old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs'
+old_postinstall_cmds='chmod 644 $oldlib'
+old_postuninstall_cmds=
+
+if test -n "$RANLIB"; then
+ case $host_os in
+ openbsd*)
+ old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib"
+ ;;
+ *)
+ old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib"
+ ;;
+ esac
+ old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib"
+fi
+
+case $host_os in
+ darwin*)
+ lock_old_archive_extraction=yes ;;
+ *)
+ lock_old_archive_extraction=no ;;
+esac
+_LT_DECL([], [old_postinstall_cmds], [2])
+_LT_DECL([], [old_postuninstall_cmds], [2])
+_LT_TAGDECL([], [old_archive_cmds], [2],
+ [Commands used to build an old-style archive])
+_LT_DECL([], [lock_old_archive_extraction], [0],
+ [Whether to use a lock for old archive extraction])
+])# _LT_CMD_OLD_ARCHIVE
+
+
+# _LT_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS,
+# [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE])
+# ----------------------------------------------------------------
+# Check whether the given compiler option works
+AC_DEFUN([_LT_COMPILER_OPTION],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_SED])dnl
+AC_CACHE_CHECK([$1], [$2],
+ [$2=no
+ m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4])
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+ lt_compiler_flag="$3"
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ # The option is referenced via a variable to avoid confusing sed.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD)
+ (eval "$lt_compile" 2>conftest.err)
+ ac_status=$?
+ cat conftest.err >&AS_MESSAGE_LOG_FD
+ echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD
+ if (exit $ac_status) && test -s "$ac_outfile"; then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings other than the usual output.
+ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+ $2=yes
+ fi
+ fi
+ $RM conftest*
+])
+
+if test x"[$]$2" = xyes; then
+ m4_if([$5], , :, [$5])
+else
+ m4_if([$6], , :, [$6])
+fi
+])# _LT_COMPILER_OPTION
+
+# Old name:
+AU_ALIAS([AC_LIBTOOL_COMPILER_OPTION], [_LT_COMPILER_OPTION])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], [])
+
+
+# _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS,
+# [ACTION-SUCCESS], [ACTION-FAILURE])
+# ----------------------------------------------------
+# Check whether the given linker option works
+AC_DEFUN([_LT_LINKER_OPTION],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_SED])dnl
+AC_CACHE_CHECK([$1], [$2],
+ [$2=no
+ save_LDFLAGS="$LDFLAGS"
+ LDFLAGS="$LDFLAGS $3"
+ echo "$lt_simple_link_test_code" > conftest.$ac_ext
+ if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+ # The linker can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ if test -s conftest.err; then
+ # Append any errors to the config.log.
+ cat conftest.err 1>&AS_MESSAGE_LOG_FD
+ $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if diff conftest.exp conftest.er2 >/dev/null; then
+ $2=yes
+ fi
+ else
+ $2=yes
+ fi
+ fi
+ $RM -r conftest*
+ LDFLAGS="$save_LDFLAGS"
+])
+
+if test x"[$]$2" = xyes; then
+ m4_if([$4], , :, [$4])
+else
+ m4_if([$5], , :, [$5])
+fi
+])# _LT_LINKER_OPTION
+
+# Old name:
+AU_ALIAS([AC_LIBTOOL_LINKER_OPTION], [_LT_LINKER_OPTION])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], [])
+
+
+# LT_CMD_MAX_LEN
+#---------------
+AC_DEFUN([LT_CMD_MAX_LEN],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+# find the maximum length of command line arguments
+AC_MSG_CHECKING([the maximum length of command line arguments])
+AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl
+ i=0
+ teststring="ABCD"
+
+ case $build_os in
+ msdosdjgpp*)
+ # On DJGPP, this test can blow up pretty badly due to problems in libc
+ # (any single argument exceeding 2000 bytes causes a buffer overrun
+ # during glob expansion). Even if it were fixed, the result of this
+ # check would be larger than it should be.
+ lt_cv_sys_max_cmd_len=12288; # 12K is about right
+ ;;
+
+ gnu*)
+ # Under GNU Hurd, this test is not required because there is
+ # no limit to the length of command line arguments.
+ # Libtool will interpret -1 as no limit whatsoever
+ lt_cv_sys_max_cmd_len=-1;
+ ;;
+
+ cygwin* | mingw* | cegcc*)
+ # On Win9x/ME, this test blows up -- it succeeds, but takes
+ # about 5 minutes as the teststring grows exponentially.
+ # Worse, since 9x/ME are not pre-emptively multitasking,
+ # you end up with a "frozen" computer, even though with patience
+ # the test eventually succeeds (with a max line length of 256k).
+ # Instead, let's just punt: use the minimum linelength reported by
+ # all of the supported platforms: 8192 (on NT/2K/XP).
+ lt_cv_sys_max_cmd_len=8192;
+ ;;
+
+ mint*)
+ # On MiNT this can take a long time and run out of memory.
+ lt_cv_sys_max_cmd_len=8192;
+ ;;
+
+ amigaos*)
+ # On AmigaOS with pdksh, this test takes hours, literally.
+ # So we just punt and use a minimum line length of 8192.
+ lt_cv_sys_max_cmd_len=8192;
+ ;;
+
+ netbsd* | freebsd* | openbsd* | darwin* | dragonfly*)
+ # This has been around since 386BSD, at least. Likely further.
+ if test -x /sbin/sysctl; then
+ lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax`
+ elif test -x /usr/sbin/sysctl; then
+ lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax`
+ else
+ lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs
+ fi
+ # And add a safety zone
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+ ;;
+
+ interix*)
+ # We know the value 262144 and hardcode it with a safety zone (like BSD)
+ lt_cv_sys_max_cmd_len=196608
+ ;;
+
+ os2*)
+ # The test takes a long time on OS/2.
+ lt_cv_sys_max_cmd_len=8192
+ ;;
+
+ osf*)
+ # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure
+ # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not
+ # nice to cause kernel panics so lets avoid the loop below.
+ # First set a reasonable default.
+ lt_cv_sys_max_cmd_len=16384
+ #
+ if test -x /sbin/sysconfig; then
+ case `/sbin/sysconfig -q proc exec_disable_arg_limit` in
+ *1*) lt_cv_sys_max_cmd_len=-1 ;;
+ esac
+ fi
+ ;;
+ sco3.2v5*)
+ lt_cv_sys_max_cmd_len=102400
+ ;;
+ sysv5* | sco5v6* | sysv4.2uw2*)
+ kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null`
+ if test -n "$kargmax"; then
+ lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'`
+ else
+ lt_cv_sys_max_cmd_len=32768
+ fi
+ ;;
+ *)
+ lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null`
+ if test -n "$lt_cv_sys_max_cmd_len"; then
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+ else
+ # Make teststring a little bigger before we do anything with it.
+ # a 1K string should be a reasonable start.
+ for i in 1 2 3 4 5 6 7 8 ; do
+ teststring=$teststring$teststring
+ done
+ SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}}
+ # If test is not a shell built-in, we'll probably end up computing a
+ # maximum length that is only half of the actual maximum length, but
+ # we can't tell.
+ while { test "X"`env echo "$teststring$teststring" 2>/dev/null` \
+ = "X$teststring$teststring"; } >/dev/null 2>&1 &&
+ test $i != 17 # 1/2 MB should be enough
+ do
+ i=`expr $i + 1`
+ teststring=$teststring$teststring
+ done
+ # Only check the string length outside the loop.
+ lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1`
+ teststring=
+ # Add a significant safety factor because C++ compilers can tack on
+ # massive amounts of additional arguments before passing them to the
+ # linker. It appears as though 1/2 is a usable value.
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2`
+ fi
+ ;;
+ esac
+])
+if test -n $lt_cv_sys_max_cmd_len ; then
+ AC_MSG_RESULT($lt_cv_sys_max_cmd_len)
+else
+ AC_MSG_RESULT(none)
+fi
+max_cmd_len=$lt_cv_sys_max_cmd_len
+_LT_DECL([], [max_cmd_len], [0],
+ [What is the maximum length of a command?])
+])# LT_CMD_MAX_LEN
+
+# Old name:
+AU_ALIAS([AC_LIBTOOL_SYS_MAX_CMD_LEN], [LT_CMD_MAX_LEN])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], [])
+
+
+# _LT_HEADER_DLFCN
+# ----------------
+m4_defun([_LT_HEADER_DLFCN],
+[AC_CHECK_HEADERS([dlfcn.h], [], [], [AC_INCLUDES_DEFAULT])dnl
+])# _LT_HEADER_DLFCN
+
+
+# _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE,
+# ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING)
+# ----------------------------------------------------------------
+m4_defun([_LT_TRY_DLOPEN_SELF],
+[m4_require([_LT_HEADER_DLFCN])dnl
+if test "$cross_compiling" = yes; then :
+ [$4]
+else
+ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+ lt_status=$lt_dlunknown
+ cat > conftest.$ac_ext <<_LT_EOF
+[#line $LINENO "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+# define LT_DLGLOBAL RTLD_GLOBAL
+#else
+# ifdef DL_GLOBAL
+# define LT_DLGLOBAL DL_GLOBAL
+# else
+# define LT_DLGLOBAL 0
+# endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+ find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+# ifdef RTLD_LAZY
+# define LT_DLLAZY_OR_NOW RTLD_LAZY
+# else
+# ifdef DL_LAZY
+# define LT_DLLAZY_OR_NOW DL_LAZY
+# else
+# ifdef RTLD_NOW
+# define LT_DLLAZY_OR_NOW RTLD_NOW
+# else
+# ifdef DL_NOW
+# define LT_DLLAZY_OR_NOW DL_NOW
+# else
+# define LT_DLLAZY_OR_NOW 0
+# endif
+# endif
+# endif
+# endif
+#endif
+
+/* When -fvisbility=hidden is used, assume the code has been annotated
+ correspondingly for the symbols needed. */
+#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
+int fnord () __attribute__((visibility("default")));
+#endif
+
+int fnord () { return 42; }
+int main ()
+{
+ void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+ int status = $lt_dlunknown;
+
+ if (self)
+ {
+ if (dlsym (self,"fnord")) status = $lt_dlno_uscore;
+ else
+ {
+ if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
+ else puts (dlerror ());
+ }
+ /* dlclose (self); */
+ }
+ else
+ puts (dlerror ());
+
+ return status;
+}]
+_LT_EOF
+ if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then
+ (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null
+ lt_status=$?
+ case x$lt_status in
+ x$lt_dlno_uscore) $1 ;;
+ x$lt_dlneed_uscore) $2 ;;
+ x$lt_dlunknown|x*) $3 ;;
+ esac
+ else :
+ # compilation failed
+ $3
+ fi
+fi
+rm -fr conftest*
+])# _LT_TRY_DLOPEN_SELF
+
+
+# LT_SYS_DLOPEN_SELF
+# ------------------
+AC_DEFUN([LT_SYS_DLOPEN_SELF],
+[m4_require([_LT_HEADER_DLFCN])dnl
+if test "x$enable_dlopen" != xyes; then
+ enable_dlopen=unknown
+ enable_dlopen_self=unknown
+ enable_dlopen_self_static=unknown
+else
+ lt_cv_dlopen=no
+ lt_cv_dlopen_libs=
+
+ case $host_os in
+ beos*)
+ lt_cv_dlopen="load_add_on"
+ lt_cv_dlopen_libs=
+ lt_cv_dlopen_self=yes
+ ;;
+
+ mingw* | pw32* | cegcc*)
+ lt_cv_dlopen="LoadLibrary"
+ lt_cv_dlopen_libs=
+ ;;
+
+ cygwin*)
+ lt_cv_dlopen="dlopen"
+ lt_cv_dlopen_libs=
+ ;;
+
+ darwin*)
+ # if libdl is installed we need to link against it
+ AC_CHECK_LIB([dl], [dlopen],
+ [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],[
+ lt_cv_dlopen="dyld"
+ lt_cv_dlopen_libs=
+ lt_cv_dlopen_self=yes
+ ])
+ ;;
+
+ *)
+ AC_CHECK_FUNC([shl_load],
+ [lt_cv_dlopen="shl_load"],
+ [AC_CHECK_LIB([dld], [shl_load],
+ [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"],
+ [AC_CHECK_FUNC([dlopen],
+ [lt_cv_dlopen="dlopen"],
+ [AC_CHECK_LIB([dl], [dlopen],
+ [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],
+ [AC_CHECK_LIB([svld], [dlopen],
+ [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"],
+ [AC_CHECK_LIB([dld], [dld_link],
+ [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"])
+ ])
+ ])
+ ])
+ ])
+ ])
+ ;;
+ esac
+
+ if test "x$lt_cv_dlopen" != xno; then
+ enable_dlopen=yes
+ else
+ enable_dlopen=no
+ fi
+
+ case $lt_cv_dlopen in
+ dlopen)
+ save_CPPFLAGS="$CPPFLAGS"
+ test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
+
+ save_LDFLAGS="$LDFLAGS"
+ wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
+
+ save_LIBS="$LIBS"
+ LIBS="$lt_cv_dlopen_libs $LIBS"
+
+ AC_CACHE_CHECK([whether a program can dlopen itself],
+ lt_cv_dlopen_self, [dnl
+ _LT_TRY_DLOPEN_SELF(
+ lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes,
+ lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross)
+ ])
+
+ if test "x$lt_cv_dlopen_self" = xyes; then
+ wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\"
+ AC_CACHE_CHECK([whether a statically linked program can dlopen itself],
+ lt_cv_dlopen_self_static, [dnl
+ _LT_TRY_DLOPEN_SELF(
+ lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes,
+ lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross)
+ ])
+ fi
+
+ CPPFLAGS="$save_CPPFLAGS"
+ LDFLAGS="$save_LDFLAGS"
+ LIBS="$save_LIBS"
+ ;;
+ esac
+
+ case $lt_cv_dlopen_self in
+ yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;;
+ *) enable_dlopen_self=unknown ;;
+ esac
+
+ case $lt_cv_dlopen_self_static in
+ yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;;
+ *) enable_dlopen_self_static=unknown ;;
+ esac
+fi
+_LT_DECL([dlopen_support], [enable_dlopen], [0],
+ [Whether dlopen is supported])
+_LT_DECL([dlopen_self], [enable_dlopen_self], [0],
+ [Whether dlopen of programs is supported])
+_LT_DECL([dlopen_self_static], [enable_dlopen_self_static], [0],
+ [Whether dlopen of statically linked programs is supported])
+])# LT_SYS_DLOPEN_SELF
+
+# Old name:
+AU_ALIAS([AC_LIBTOOL_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], [])
+
+
+# _LT_COMPILER_C_O([TAGNAME])
+# ---------------------------
+# Check to see if options -c and -o are simultaneously supported by compiler.
+# This macro does not hard code the compiler like AC_PROG_CC_C_O.
+m4_defun([_LT_COMPILER_C_O],
+[m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_TAG_COMPILER])dnl
+AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext],
+ [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)],
+ [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no
+ $RM -r conftest 2>/dev/null
+ mkdir conftest
+ cd conftest
+ mkdir out
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+ lt_compiler_flag="-o out/conftest2.$ac_objext"
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD)
+ (eval "$lt_compile" 2>out/conftest.err)
+ ac_status=$?
+ cat out/conftest.err >&AS_MESSAGE_LOG_FD
+ echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD
+ if (exit $ac_status) && test -s out/conftest2.$ac_objext
+ then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp
+ $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+ if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+ _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes
+ fi
+ fi
+ chmod u+w . 2>&AS_MESSAGE_LOG_FD
+ $RM conftest*
+ # SGI C++ compiler will create directory out/ii_files/ for
+ # template instantiation
+ test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
+ $RM out/* && rmdir out
+ cd ..
+ $RM -r conftest
+ $RM conftest*
+])
+_LT_TAGDECL([compiler_c_o], [lt_cv_prog_compiler_c_o], [1],
+ [Does compiler simultaneously support -c and -o options?])
+])# _LT_COMPILER_C_O
+
+
+# _LT_COMPILER_FILE_LOCKS([TAGNAME])
+# ----------------------------------
+# Check to see if we can do hard links to lock some files if needed
+m4_defun([_LT_COMPILER_FILE_LOCKS],
+[m4_require([_LT_ENABLE_LOCK])dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+_LT_COMPILER_C_O([$1])
+
+hard_links="nottested"
+if test "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" = no && test "$need_locks" != no; then
+ # do not overwrite the value of need_locks provided by the user
+ AC_MSG_CHECKING([if we can lock with hard links])
+ hard_links=yes
+ $RM conftest*
+ ln conftest.a conftest.b 2>/dev/null && hard_links=no
+ touch conftest.a
+ ln conftest.a conftest.b 2>&5 || hard_links=no
+ ln conftest.a conftest.b 2>/dev/null && hard_links=no
+ AC_MSG_RESULT([$hard_links])
+ if test "$hard_links" = no; then
+ AC_MSG_WARN([`$CC' does not support `-c -o', so `make -j' may be unsafe])
+ need_locks=warn
+ fi
+else
+ need_locks=no
+fi
+_LT_DECL([], [need_locks], [1], [Must we lock files when doing compilation?])
+])# _LT_COMPILER_FILE_LOCKS
+
+
+# _LT_CHECK_OBJDIR
+# ----------------
+m4_defun([_LT_CHECK_OBJDIR],
+[AC_CACHE_CHECK([for objdir], [lt_cv_objdir],
+[rm -f .libs 2>/dev/null
+mkdir .libs 2>/dev/null
+if test -d .libs; then
+ lt_cv_objdir=.libs
+else
+ # MS-DOS does not allow filenames that begin with a dot.
+ lt_cv_objdir=_libs
+fi
+rmdir .libs 2>/dev/null])
+objdir=$lt_cv_objdir
+_LT_DECL([], [objdir], [0],
+ [The name of the directory that contains temporary libtool files])dnl
+m4_pattern_allow([LT_OBJDIR])dnl
+AC_DEFINE_UNQUOTED(LT_OBJDIR, "$lt_cv_objdir/",
+ [Define to the sub-directory in which libtool stores uninstalled libraries.])
+])# _LT_CHECK_OBJDIR
+
+
+# _LT_LINKER_HARDCODE_LIBPATH([TAGNAME])
+# --------------------------------------
+# Check hardcoding attributes.
+m4_defun([_LT_LINKER_HARDCODE_LIBPATH],
+[AC_MSG_CHECKING([how to hardcode library paths into programs])
+_LT_TAGVAR(hardcode_action, $1)=
+if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" ||
+ test -n "$_LT_TAGVAR(runpath_var, $1)" ||
+ test "X$_LT_TAGVAR(hardcode_automatic, $1)" = "Xyes" ; then
+
+ # We can hardcode non-existent directories.
+ if test "$_LT_TAGVAR(hardcode_direct, $1)" != no &&
+ # If the only mechanism to avoid hardcoding is shlibpath_var, we
+ # have to relink, otherwise we might link with an installed library
+ # when we should be linking with a yet-to-be-installed one
+ ## test "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" != no &&
+ test "$_LT_TAGVAR(hardcode_minus_L, $1)" != no; then
+ # Linking always hardcodes the temporary library directory.
+ _LT_TAGVAR(hardcode_action, $1)=relink
+ else
+ # We can link without hardcoding, and we can hardcode nonexisting dirs.
+ _LT_TAGVAR(hardcode_action, $1)=immediate
+ fi
+else
+ # We cannot hardcode anything, or else we can only hardcode existing
+ # directories.
+ _LT_TAGVAR(hardcode_action, $1)=unsupported
+fi
+AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)])
+
+if test "$_LT_TAGVAR(hardcode_action, $1)" = relink ||
+ test "$_LT_TAGVAR(inherit_rpath, $1)" = yes; then
+ # Fast installation is not supported
+ enable_fast_install=no
+elif test "$shlibpath_overrides_runpath" = yes ||
+ test "$enable_shared" = no; then
+ # Fast installation is not necessary
+ enable_fast_install=needless
+fi
+_LT_TAGDECL([], [hardcode_action], [0],
+ [How to hardcode a shared library path into an executable])
+])# _LT_LINKER_HARDCODE_LIBPATH
+
+
+# _LT_CMD_STRIPLIB
+# ----------------
+m4_defun([_LT_CMD_STRIPLIB],
+[m4_require([_LT_DECL_EGREP])
+striplib=
+old_striplib=
+AC_MSG_CHECKING([whether stripping libraries is possible])
+if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then
+ test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
+ test -z "$striplib" && striplib="$STRIP --strip-unneeded"
+ AC_MSG_RESULT([yes])
+else
+# FIXME - insert some real tests, host_os isn't really good enough
+ case $host_os in
+ darwin*)
+ if test -n "$STRIP" ; then
+ striplib="$STRIP -x"
+ old_striplib="$STRIP -S"
+ AC_MSG_RESULT([yes])
+ else
+ AC_MSG_RESULT([no])
+ fi
+ ;;
+ *)
+ AC_MSG_RESULT([no])
+ ;;
+ esac
+fi
+_LT_DECL([], [old_striplib], [1], [Commands to strip libraries])
+_LT_DECL([], [striplib], [1])
+])# _LT_CMD_STRIPLIB
+
+
+# _LT_SYS_DYNAMIC_LINKER([TAG])
+# -----------------------------
+# PORTME Fill in your ld.so characteristics
+m4_defun([_LT_SYS_DYNAMIC_LINKER],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_OBJDUMP])dnl
+m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_CHECK_SHELL_FEATURES])dnl
+AC_MSG_CHECKING([dynamic linker characteristics])
+m4_if([$1],
+ [], [
+if test "$GCC" = yes; then
+ case $host_os in
+ darwin*) lt_awk_arg="/^libraries:/,/LR/" ;;
+ *) lt_awk_arg="/^libraries:/" ;;
+ esac
+ case $host_os in
+ mingw* | cegcc*) lt_sed_strip_eq="s,=\([[A-Za-z]]:\),\1,g" ;;
+ *) lt_sed_strip_eq="s,=/,/,g" ;;
+ esac
+ lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq`
+ case $lt_search_path_spec in
+ *\;*)
+ # if the path contains ";" then we assume it to be the separator
+ # otherwise default to the standard path separator (i.e. ":") - it is
+ # assumed that no part of a normal pathname contains ";" but that should
+ # okay in the real world where ";" in dirpaths is itself problematic.
+ lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'`
+ ;;
+ *)
+ lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"`
+ ;;
+ esac
+ # Ok, now we have the path, separated by spaces, we can step through it
+ # and add multilib dir if necessary.
+ lt_tmp_lt_search_path_spec=
+ lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null`
+ for lt_sys_path in $lt_search_path_spec; do
+ if test -d "$lt_sys_path/$lt_multi_os_dir"; then
+ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir"
+ else
+ test -d "$lt_sys_path" && \
+ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path"
+ fi
+ done
+ lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk '
+BEGIN {RS=" "; FS="/|\n";} {
+ lt_foo="";
+ lt_count=0;
+ for (lt_i = NF; lt_i > 0; lt_i--) {
+ if ($lt_i != "" && $lt_i != ".") {
+ if ($lt_i == "..") {
+ lt_count++;
+ } else {
+ if (lt_count == 0) {
+ lt_foo="/" $lt_i lt_foo;
+ } else {
+ lt_count--;
+ }
+ }
+ }
+ }
+ if (lt_foo != "") { lt_freq[[lt_foo]]++; }
+ if (lt_freq[[lt_foo]] == 1) { print lt_foo; }
+}'`
+ # AWK program above erroneously prepends '/' to C:/dos/paths
+ # for these hosts.
+ case $host_os in
+ mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\
+ $SED 's,/\([[A-Za-z]]:\),\1,g'` ;;
+ esac
+ sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP`
+else
+ sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+fi])
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+shrext_cmds=".so"
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+shlibpath_overrides_runpath=unknown
+version_type=none
+dynamic_linker="$host_os ld.so"
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+need_lib_prefix=unknown
+hardcode_into_libs=no
+
+# when you set need_version to no, make sure it does not cause -set_version
+# flags to be left without arguments
+need_version=unknown
+
+case $host_os in
+aix3*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'
+ shlibpath_var=LIBPATH
+
+ # AIX 3 has no versioning support, so we append a major version to the name.
+ soname_spec='${libname}${release}${shared_ext}$major'
+ ;;
+
+aix[[4-9]]*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ hardcode_into_libs=yes
+ if test "$host_cpu" = ia64; then
+ # AIX 5 supports IA64
+ library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}'
+ shlibpath_var=LD_LIBRARY_PATH
+ else
+ # With GCC up to 2.95.x, collect2 would create an import file
+ # for dependence libraries. The import file would start with
+ # the line `#! .'. This would cause the generated library to
+ # depend on `.', always an invalid library. This was fixed in
+ # development snapshots of GCC prior to 3.0.
+ case $host_os in
+ aix4 | aix4.[[01]] | aix4.[[01]].*)
+ if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
+ echo ' yes '
+ echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then
+ :
+ else
+ can_build_shared=no
+ fi
+ ;;
+ esac
+ # AIX (on Power*) has no versioning support, so currently we can not hardcode correct
+ # soname into executable. Probably we can add versioning support to
+ # collect2, so additional links can be useful in future.
+ if test "$aix_use_runtimelinking" = yes; then
+ # If using run time linking (on AIX 4.2 or later) use lib<name>.so
+ # instead of lib<name>.a to let people know that these are not
+ # typical AIX shared libraries.
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ else
+ # We preserve .a as extension for shared libraries through AIX4.2
+ # and later when we are not doing run time linking.
+ library_names_spec='${libname}${release}.a $libname.a'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ fi
+ shlibpath_var=LIBPATH
+ fi
+ ;;
+
+amigaos*)
+ case $host_cpu in
+ powerpc)
+ # Since July 2007 AmigaOS4 officially supports .so libraries.
+ # When compiling the executable, add -use-dynld -Lsobjs: to the compileline.
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ ;;
+ m68k)
+ library_names_spec='$libname.ixlibrary $libname.a'
+ # Create ${libname}_ixlibrary.a entries in /sys/libs.
+ finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
+ ;;
+ esac
+ ;;
+
+beos*)
+ library_names_spec='${libname}${shared_ext}'
+ dynamic_linker="$host_os ld.so"
+ shlibpath_var=LIBRARY_PATH
+ ;;
+
+bsdi[[45]]*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
+ sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
+ # the default ld.so.conf also contains /usr/contrib/lib and
+ # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
+ # libtool to hard-code these into programs
+ ;;
+
+cygwin* | mingw* | pw32* | cegcc*)
+ version_type=windows
+ shrext_cmds=".dll"
+ need_version=no
+ need_lib_prefix=no
+
+ case $GCC,$cc_basename in
+ yes,*)
+ # gcc
+ library_names_spec='$libname.dll.a'
+ # DLL is installed to $(libdir)/../bin by postinstall_cmds
+ postinstall_cmds='base_file=`basename \${file}`~
+ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
+ dldir=$destdir/`dirname \$dlpath`~
+ test -d \$dldir || mkdir -p \$dldir~
+ $install_prog $dir/$dlname \$dldir/$dlname~
+ chmod a+x \$dldir/$dlname~
+ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then
+ eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;
+ fi'
+ postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+ dlpath=$dir/\$dldll~
+ $RM \$dlpath'
+ shlibpath_overrides_runpath=yes
+
+ case $host_os in
+ cygwin*)
+ # Cygwin DLLs use 'cyg' prefix rather than 'lib'
+ soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
+m4_if([$1], [],[
+ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"])
+ ;;
+ mingw* | cegcc*)
+ # MinGW DLLs use traditional 'lib' prefix
+ soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
+ ;;
+ pw32*)
+ # pw32 DLLs use 'pw' prefix rather than 'lib'
+ library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
+ ;;
+ esac
+ dynamic_linker='Win32 ld.exe'
+ ;;
+
+ *,cl*)
+ # Native MSVC
+ libname_spec='$name'
+ soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
+ library_names_spec='${libname}.dll.lib'
+
+ case $build_os in
+ mingw*)
+ sys_lib_search_path_spec=
+ lt_save_ifs=$IFS
+ IFS=';'
+ for lt_path in $LIB
+ do
+ IFS=$lt_save_ifs
+ # Let DOS variable expansion print the short 8.3 style file name.
+ lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"`
+ sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path"
+ done
+ IFS=$lt_save_ifs
+ # Convert to MSYS style.
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([[a-zA-Z]]\\):| /\\1|g' -e 's|^ ||'`
+ ;;
+ cygwin*)
+ # Convert to unix form, then to dos form, then back to unix form
+ # but this time dos style (no spaces!) so that the unix form looks
+ # like /cygdrive/c/PROGRA~1:/cygdr...
+ sys_lib_search_path_spec=`cygpath --path --unix "$LIB"`
+ sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null`
+ sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+ ;;
+ *)
+ sys_lib_search_path_spec="$LIB"
+ if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then
+ # It is most probably a Windows format PATH.
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+ else
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+ fi
+ # FIXME: find the short name or the path components, as spaces are
+ # common. (e.g. "Program Files" -> "PROGRA~1")
+ ;;
+ esac
+
+ # DLL is installed to $(libdir)/../bin by postinstall_cmds
+ postinstall_cmds='base_file=`basename \${file}`~
+ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
+ dldir=$destdir/`dirname \$dlpath`~
+ test -d \$dldir || mkdir -p \$dldir~
+ $install_prog $dir/$dlname \$dldir/$dlname'
+ postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+ dlpath=$dir/\$dldll~
+ $RM \$dlpath'
+ shlibpath_overrides_runpath=yes
+ dynamic_linker='Win32 link.exe'
+ ;;
+
+ *)
+ # Assume MSVC wrapper
+ library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $libname.lib'
+ dynamic_linker='Win32 ld.exe'
+ ;;
+ esac
+ # FIXME: first we should search . and the directory the executable is in
+ shlibpath_var=PATH
+ ;;
+
+darwin* | rhapsody*)
+ dynamic_linker="$host_os dyld"
+ version_type=darwin
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext'
+ soname_spec='${libname}${release}${major}$shared_ext'
+ shlibpath_overrides_runpath=yes
+ shlibpath_var=DYLD_LIBRARY_PATH
+ shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
+m4_if([$1], [],[
+ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"])
+ sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
+ ;;
+
+dgux*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+freebsd* | dragonfly*)
+ # DragonFly does not have aout. When/if they implement a new
+ # versioning mechanism, adjust this.
+ if test -x /usr/bin/objformat; then
+ objformat=`/usr/bin/objformat`
+ else
+ case $host_os in
+ freebsd[[23]].*) objformat=aout ;;
+ *) objformat=elf ;;
+ esac
+ fi
+ version_type=freebsd-$objformat
+ case $version_type in
+ freebsd-elf*)
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+ need_version=no
+ need_lib_prefix=no
+ ;;
+ freebsd-*)
+ library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix'
+ need_version=yes
+ ;;
+ esac
+ shlibpath_var=LD_LIBRARY_PATH
+ case $host_os in
+ freebsd2.*)
+ shlibpath_overrides_runpath=yes
+ ;;
+ freebsd3.[[01]]* | freebsdelf3.[[01]]*)
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+ freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \
+ freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1)
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+ *) # from 4.6 on, and DragonFly
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+ esac
+ ;;
+
+gnu*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+
+haiku*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ dynamic_linker="$host_os runtime_loader"
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib'
+ hardcode_into_libs=yes
+ ;;
+
+hpux9* | hpux10* | hpux11*)
+ # Give a soname corresponding to the major version so that dld.sl refuses to
+ # link against other versions.
+ version_type=sunos
+ need_lib_prefix=no
+ need_version=no
+ case $host_cpu in
+ ia64*)
+ shrext_cmds='.so'
+ hardcode_into_libs=yes
+ dynamic_linker="$host_os dld.so"
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ if test "X$HPUX_IA64_MODE" = X32; then
+ sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
+ else
+ sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
+ fi
+ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+ ;;
+ hppa*64*)
+ shrext_cmds='.sl'
+ hardcode_into_libs=yes
+ dynamic_linker="$host_os dld.sl"
+ shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
+ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
+ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+ ;;
+ *)
+ shrext_cmds='.sl'
+ dynamic_linker="$host_os dld.sl"
+ shlibpath_var=SHLIB_PATH
+ shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ ;;
+ esac
+ # HP-UX runs *really* slowly unless shared libraries are mode 555, ...
+ postinstall_cmds='chmod 555 $lib'
+ # or fails outright, so override atomically:
+ install_override_mode=555
+ ;;
+
+interix[[3-9]]*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+
+irix5* | irix6* | nonstopux*)
+ case $host_os in
+ nonstopux*) version_type=nonstopux ;;
+ *)
+ if test "$lt_cv_prog_gnu_ld" = yes; then
+ version_type=linux # correct to gnu/linux during the next big refactor
+ else
+ version_type=irix
+ fi ;;
+ esac
+ need_lib_prefix=no
+ need_version=no
+ soname_spec='${libname}${release}${shared_ext}$major'
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}'
+ case $host_os in
+ irix5* | nonstopux*)
+ libsuff= shlibsuff=
+ ;;
+ *)
+ case $LD in # libtool.m4 will add one of these switches to LD
+ *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ")
+ libsuff= shlibsuff= libmagic=32-bit;;
+ *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")
+ libsuff=32 shlibsuff=N32 libmagic=N32;;
+ *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ")
+ libsuff=64 shlibsuff=64 libmagic=64-bit;;
+ *) libsuff= shlibsuff= libmagic=never-match;;
+ esac
+ ;;
+ esac
+ shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
+ shlibpath_overrides_runpath=no
+ sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
+ sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
+ hardcode_into_libs=yes
+ ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux*oldld* | linux*aout* | linux*coff*)
+ dynamic_linker=no
+ ;;
+
+# This must be glibc/ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+
+ # Some binutils ld are patched to set DT_RUNPATH
+ AC_CACHE_VAL([lt_cv_shlibpath_overrides_runpath],
+ [lt_cv_shlibpath_overrides_runpath=no
+ save_LDFLAGS=$LDFLAGS
+ save_libdir=$libdir
+ eval "libdir=/foo; wl=\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\"; \
+ LDFLAGS=\"\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\""
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])],
+ [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null],
+ [lt_cv_shlibpath_overrides_runpath=yes])])
+ LDFLAGS=$save_LDFLAGS
+ libdir=$save_libdir
+ ])
+ shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath
+
+ # This implies no fast_install, which is unacceptable.
+ # Some rework will be needed to allow for fast_install
+ # before this can be enabled.
+ hardcode_into_libs=yes
+
+ # Add ABI-specific directories to the system library path.
+ sys_lib_dlsearch_path_spec="/lib64 /usr/lib64 /lib /usr/lib"
+
+ # Append ld.so.conf contents to the search path
+ if test -f /etc/ld.so.conf; then
+ lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '`
+ sys_lib_dlsearch_path_spec="$sys_lib_dlsearch_path_spec $lt_ld_extra"
+
+ fi
+
+ # We used to test for /lib/ld.so.1 and disable shared libraries on
+ # powerpc, because MkLinux only supported shared libraries with the
+ # GNU dynamic linker. Since this was broken with cross compilers,
+ # most powerpc-linux boxes support dynamic linking these days and
+ # people can always --disable-shared, the test was removed, and we
+ # assume the GNU/Linux dynamic linker is in use.
+ dynamic_linker='GNU/Linux ld.so'
+ ;;
+
+netbsd*)
+ version_type=sunos
+ need_lib_prefix=no
+ need_version=no
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+ dynamic_linker='NetBSD (a.out) ld.so'
+ else
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ dynamic_linker='NetBSD ld.elf_so'
+ fi
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+
+newsos6)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ ;;
+
+*nto* | *qnx*)
+ version_type=qnx
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ dynamic_linker='ldqnx.so'
+ ;;
+
+openbsd*)
+ version_type=sunos
+ sys_lib_dlsearch_path_spec="/usr/lib"
+ need_lib_prefix=no
+ # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs.
+ case $host_os in
+ openbsd3.3 | openbsd3.3.*) need_version=yes ;;
+ *) need_version=no ;;
+ esac
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ case $host_os in
+ openbsd2.[[89]] | openbsd2.[[89]].*)
+ shlibpath_overrides_runpath=no
+ ;;
+ *)
+ shlibpath_overrides_runpath=yes
+ ;;
+ esac
+ else
+ shlibpath_overrides_runpath=yes
+ fi
+ ;;
+
+os2*)
+ libname_spec='$name'
+ shrext_cmds=".dll"
+ need_lib_prefix=no
+ library_names_spec='$libname${shared_ext} $libname.a'
+ dynamic_linker='OS/2 ld.exe'
+ shlibpath_var=LIBPATH
+ ;;
+
+osf3* | osf4* | osf5*)
+ version_type=osf
+ need_lib_prefix=no
+ need_version=no
+ soname_spec='${libname}${release}${shared_ext}$major'
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ shlibpath_var=LD_LIBRARY_PATH
+ sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
+ sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
+ ;;
+
+rdos*)
+ dynamic_linker=no
+ ;;
+
+solaris*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ # ldd complains unless libraries are executable
+ postinstall_cmds='chmod +x $lib'
+ ;;
+
+sunos4*)
+ version_type=sunos
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+ finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ if test "$with_gnu_ld" = yes; then
+ need_lib_prefix=no
+ fi
+ need_version=yes
+ ;;
+
+sysv4 | sysv4.3*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ case $host_vendor in
+ sni)
+ shlibpath_overrides_runpath=no
+ need_lib_prefix=no
+ runpath_var=LD_RUN_PATH
+ ;;
+ siemens)
+ need_lib_prefix=no
+ ;;
+ motorola)
+ need_lib_prefix=no
+ need_version=no
+ shlibpath_overrides_runpath=no
+ sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
+ ;;
+ esac
+ ;;
+
+sysv4*MP*)
+ if test -d /usr/nec ;then
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'
+ soname_spec='$libname${shared_ext}.$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ fi
+ ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+ version_type=freebsd-elf
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ if test "$with_gnu_ld" = yes; then
+ sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
+ else
+ sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
+ case $host_os in
+ sco3.2v5*)
+ sys_lib_search_path_spec="$sys_lib_search_path_spec /lib"
+ ;;
+ esac
+ fi
+ sys_lib_dlsearch_path_spec='/usr/lib'
+ ;;
+
+tpf*)
+ # TPF is a cross-target only. Preferred cross-host = GNU/Linux.
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+
+uts4*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+*)
+ dynamic_linker=no
+ ;;
+esac
+AC_MSG_RESULT([$dynamic_linker])
+test "$dynamic_linker" = no && can_build_shared=no
+
+variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
+if test "$GCC" = yes; then
+ variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
+fi
+
+if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then
+ sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec"
+fi
+if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then
+ sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec"
+fi
+
+_LT_DECL([], [variables_saved_for_relink], [1],
+ [Variables whose values should be saved in libtool wrapper scripts and
+ restored at link time])
+_LT_DECL([], [need_lib_prefix], [0],
+ [Do we need the "lib" prefix for modules?])
+_LT_DECL([], [need_version], [0], [Do we need a version for libraries?])
+_LT_DECL([], [version_type], [0], [Library versioning type])
+_LT_DECL([], [runpath_var], [0], [Shared library runtime path variable])
+_LT_DECL([], [shlibpath_var], [0],[Shared library path variable])
+_LT_DECL([], [shlibpath_overrides_runpath], [0],
+ [Is shlibpath searched before the hard-coded library search path?])
+_LT_DECL([], [libname_spec], [1], [Format of library name prefix])
+_LT_DECL([], [library_names_spec], [1],
+ [[List of archive names. First name is the real one, the rest are links.
+ The last name is the one that the linker finds with -lNAME]])
+_LT_DECL([], [soname_spec], [1],
+ [[The coded name of the library, if different from the real name]])
+_LT_DECL([], [install_override_mode], [1],
+ [Permission mode override for installation of shared libraries])
+_LT_DECL([], [postinstall_cmds], [2],
+ [Command to use after installation of a shared archive])
+_LT_DECL([], [postuninstall_cmds], [2],
+ [Command to use after uninstallation of a shared archive])
+_LT_DECL([], [finish_cmds], [2],
+ [Commands used to finish a libtool library installation in a directory])
+_LT_DECL([], [finish_eval], [1],
+ [[As "finish_cmds", except a single script fragment to be evaled but
+ not shown]])
+_LT_DECL([], [hardcode_into_libs], [0],
+ [Whether we should hardcode library paths into libraries])
+_LT_DECL([], [sys_lib_search_path_spec], [2],
+ [Compile-time system search path for libraries])
+_LT_DECL([], [sys_lib_dlsearch_path_spec], [2],
+ [Run-time system search path for libraries])
+])# _LT_SYS_DYNAMIC_LINKER
+
+
+# _LT_PATH_TOOL_PREFIX(TOOL)
+# --------------------------
+# find a file program which can recognize shared library
+AC_DEFUN([_LT_PATH_TOOL_PREFIX],
+[m4_require([_LT_DECL_EGREP])dnl
+AC_MSG_CHECKING([for $1])
+AC_CACHE_VAL(lt_cv_path_MAGIC_CMD,
+[case $MAGIC_CMD in
+[[\\/*] | ?:[\\/]*])
+ lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
+ ;;
+*)
+ lt_save_MAGIC_CMD="$MAGIC_CMD"
+ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+dnl $ac_dummy forces splitting on constant user-supplied paths.
+dnl POSIX.2 word splitting is done only on the output of word expansions,
+dnl not every word. This closes a longstanding sh security hole.
+ ac_dummy="m4_if([$2], , $PATH, [$2])"
+ for ac_dir in $ac_dummy; do
+ IFS="$lt_save_ifs"
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$1; then
+ lt_cv_path_MAGIC_CMD="$ac_dir/$1"
+ if test -n "$file_magic_test_file"; then
+ case $deplibs_check_method in
+ "file_magic "*)
+ file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
+ MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+ if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+ $EGREP "$file_magic_regex" > /dev/null; then
+ :
+ else
+ cat <<_LT_EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such. This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem. Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+_LT_EOF
+ fi ;;
+ esac
+ fi
+ break
+ fi
+ done
+ IFS="$lt_save_ifs"
+ MAGIC_CMD="$lt_save_MAGIC_CMD"
+ ;;
+esac])
+MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+if test -n "$MAGIC_CMD"; then
+ AC_MSG_RESULT($MAGIC_CMD)
+else
+ AC_MSG_RESULT(no)
+fi
+_LT_DECL([], [MAGIC_CMD], [0],
+ [Used to examine libraries when file_magic_cmd begins with "file"])dnl
+])# _LT_PATH_TOOL_PREFIX
+
+# Old name:
+AU_ALIAS([AC_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], [])
+
+
+# _LT_PATH_MAGIC
+# --------------
+# find a file program which can recognize a shared library
+m4_defun([_LT_PATH_MAGIC],
+[_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH)
+if test -z "$lt_cv_path_MAGIC_CMD"; then
+ if test -n "$ac_tool_prefix"; then
+ _LT_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH)
+ else
+ MAGIC_CMD=:
+ fi
+fi
+])# _LT_PATH_MAGIC
+
+
+# LT_PATH_LD
+# ----------
+# find the pathname to the GNU or non-GNU linker
+AC_DEFUN([LT_PATH_LD],
+[AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_PROG_ECHO_BACKSLASH])dnl
+
+AC_ARG_WITH([gnu-ld],
+ [AS_HELP_STRING([--with-gnu-ld],
+ [assume the C compiler uses GNU ld @<:@default=no@:>@])],
+ [test "$withval" = no || with_gnu_ld=yes],
+ [with_gnu_ld=no])dnl
+
+ac_prog=ld
+if test "$GCC" = yes; then
+ # Check if gcc -print-prog-name=ld gives a path.
+ AC_MSG_CHECKING([for ld used by $CC])
+ case $host in
+ *-*-mingw*)
+ # gcc leaves a trailing carriage return which upsets mingw
+ ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
+ *)
+ ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
+ esac
+ case $ac_prog in
+ # Accept absolute paths.
+ [[\\/]]* | ?:[[\\/]]*)
+ re_direlt='/[[^/]][[^/]]*/\.\./'
+ # Canonicalize the pathname of ld
+ ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'`
+ while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do
+ ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"`
+ done
+ test -z "$LD" && LD="$ac_prog"
+ ;;
+ "")
+ # If it fails, then pretend we aren't using GCC.
+ ac_prog=ld
+ ;;
+ *)
+ # If it is relative, then search for the first ld in PATH.
+ with_gnu_ld=unknown
+ ;;
+ esac
+elif test "$with_gnu_ld" = yes; then
+ AC_MSG_CHECKING([for GNU ld])
+else
+ AC_MSG_CHECKING([for non-GNU ld])
+fi
+AC_CACHE_VAL(lt_cv_path_LD,
+[if test -z "$LD"; then
+ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+ for ac_dir in $PATH; do
+ IFS="$lt_save_ifs"
+ test -z "$ac_dir" && ac_dir=.
+ if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+ lt_cv_path_LD="$ac_dir/$ac_prog"
+ # Check to see if the program is GNU ld. I'd rather use --version,
+ # but apparently some variants of GNU ld only accept -v.
+ # Break only if it was the GNU/non-GNU ld that we prefer.
+ case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
+ *GNU* | *'with BFD'*)
+ test "$with_gnu_ld" != no && break
+ ;;
+ *)
+ test "$with_gnu_ld" != yes && break
+ ;;
+ esac
+ fi
+ done
+ IFS="$lt_save_ifs"
+else
+ lt_cv_path_LD="$LD" # Let the user override the test with a path.
+fi])
+LD="$lt_cv_path_LD"
+if test -n "$LD"; then
+ AC_MSG_RESULT($LD)
+else
+ AC_MSG_RESULT(no)
+fi
+test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH])
+_LT_PATH_LD_GNU
+AC_SUBST([LD])
+
+_LT_TAGDECL([], [LD], [1], [The linker used to build libraries])
+])# LT_PATH_LD
+
+# Old names:
+AU_ALIAS([AM_PROG_LD], [LT_PATH_LD])
+AU_ALIAS([AC_PROG_LD], [LT_PATH_LD])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AM_PROG_LD], [])
+dnl AC_DEFUN([AC_PROG_LD], [])
+
+
+# _LT_PATH_LD_GNU
+#- --------------
+m4_defun([_LT_PATH_LD_GNU],
+[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], lt_cv_prog_gnu_ld,
+[# I'd rather use --version here, but apparently some GNU lds only accept -v.
+case `$LD -v 2>&1 </dev/null` in
+*GNU* | *'with BFD'*)
+ lt_cv_prog_gnu_ld=yes
+ ;;
+*)
+ lt_cv_prog_gnu_ld=no
+ ;;
+esac])
+with_gnu_ld=$lt_cv_prog_gnu_ld
+])# _LT_PATH_LD_GNU
+
+
+# _LT_CMD_RELOAD
+# --------------
+# find reload flag for linker
+# -- PORTME Some linkers may need a different reload flag.
+m4_defun([_LT_CMD_RELOAD],
+[AC_CACHE_CHECK([for $LD option to reload object files],
+ lt_cv_ld_reload_flag,
+ [lt_cv_ld_reload_flag='-r'])
+reload_flag=$lt_cv_ld_reload_flag
+case $reload_flag in
+"" | " "*) ;;
+*) reload_flag=" $reload_flag" ;;
+esac
+reload_cmds='$LD$reload_flag -o $output$reload_objs'
+case $host_os in
+ cygwin* | mingw* | pw32* | cegcc*)
+ if test "$GCC" != yes; then
+ reload_cmds=false
+ fi
+ ;;
+ darwin*)
+ if test "$GCC" = yes; then
+ reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs'
+ else
+ reload_cmds='$LD$reload_flag -o $output$reload_objs'
+ fi
+ ;;
+esac
+_LT_TAGDECL([], [reload_flag], [1], [How to create reloadable object files])dnl
+_LT_TAGDECL([], [reload_cmds], [2])dnl
+])# _LT_CMD_RELOAD
+
+
+# _LT_CHECK_MAGIC_METHOD
+# ----------------------
+# how to check for library dependencies
+# -- PORTME fill in with the dynamic library characteristics
+m4_defun([_LT_CHECK_MAGIC_METHOD],
+[m4_require([_LT_DECL_EGREP])
+m4_require([_LT_DECL_OBJDUMP])
+AC_CACHE_CHECK([how to recognize dependent libraries],
+lt_cv_deplibs_check_method,
+[lt_cv_file_magic_cmd='$MAGIC_CMD'
+lt_cv_file_magic_test_file=
+lt_cv_deplibs_check_method='unknown'
+# Need to set the preceding variable on all platforms that support
+# interlibrary dependencies.
+# 'none' -- dependencies not supported.
+# `unknown' -- same as none, but documents that we really don't know.
+# 'pass_all' -- all dependencies passed with no checks.
+# 'test_compile' -- check by making test program.
+# 'file_magic [[regex]]' -- check by looking for files in library path
+# which responds to the $file_magic_cmd with a given extended regex.
+# If you have `file' or equivalent on your system and you're not sure
+# whether `pass_all' will *always* work, you probably want this one.
+
+case $host_os in
+aix[[4-9]]*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+beos*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+bsdi[[45]]*)
+ lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib)'
+ lt_cv_file_magic_cmd='/usr/bin/file -L'
+ lt_cv_file_magic_test_file=/shlib/libc.so
+ ;;
+
+cygwin*)
+ # func_win32_libid is a shell function defined in ltmain.sh
+ lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+ lt_cv_file_magic_cmd='func_win32_libid'
+ ;;
+
+mingw* | pw32*)
+ # Base MSYS/MinGW do not provide the 'file' command needed by
+ # func_win32_libid shell function, so use a weaker test based on 'objdump',
+ # unless we find 'file', for example because we are cross-compiling.
+ # func_win32_libid assumes BSD nm, so disallow it if using MS dumpbin.
+ if ( test "$lt_cv_nm_interface" = "BSD nm" && file / ) >/dev/null 2>&1; then
+ lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+ lt_cv_file_magic_cmd='func_win32_libid'
+ else
+ # Keep this pattern in sync with the one in func_win32_libid.
+ lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)'
+ lt_cv_file_magic_cmd='$OBJDUMP -f'
+ fi
+ ;;
+
+cegcc*)
+ # use the weaker test based on 'objdump'. See mingw*.
+ lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?'
+ lt_cv_file_magic_cmd='$OBJDUMP -f'
+ ;;
+
+darwin* | rhapsody*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+freebsd* | dragonfly*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
+ case $host_cpu in
+ i*86 )
+ # Not sure whether the presence of OpenBSD here was a mistake.
+ # Let's accept both of them until this is cleared up.
+ lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library'
+ lt_cv_file_magic_cmd=/usr/bin/file
+ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
+ ;;
+ esac
+ else
+ lt_cv_deplibs_check_method=pass_all
+ fi
+ ;;
+
+gnu*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+haiku*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+hpux10.20* | hpux11*)
+ lt_cv_file_magic_cmd=/usr/bin/file
+ case $host_cpu in
+ ia64*)
+ lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64'
+ lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so
+ ;;
+ hppa*64*)
+ [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]']
+ lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl
+ ;;
+ *)
+ lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]]\.[[0-9]]) shared library'
+ lt_cv_file_magic_test_file=/usr/lib/libc.sl
+ ;;
+ esac
+ ;;
+
+interix[[3-9]]*)
+ # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here
+ lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$'
+ ;;
+
+irix5* | irix6* | nonstopux*)
+ case $LD in
+ *-32|*"-32 ") libmagic=32-bit;;
+ *-n32|*"-n32 ") libmagic=N32;;
+ *-64|*"-64 ") libmagic=64-bit;;
+ *) libmagic=never-match;;
+ esac
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+# This must be glibc/ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+netbsd*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
+ lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$'
+ else
+ lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$'
+ fi
+ ;;
+
+newos6*)
+ lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)'
+ lt_cv_file_magic_cmd=/usr/bin/file
+ lt_cv_file_magic_test_file=/usr/lib/libnls.so
+ ;;
+
+*nto* | *qnx*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+openbsd*)
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$'
+ else
+ lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$'
+ fi
+ ;;
+
+osf3* | osf4* | osf5*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+rdos*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+solaris*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+sysv4 | sysv4.3*)
+ case $host_vendor in
+ motorola)
+ lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]'
+ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*`
+ ;;
+ ncr)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ sequent)
+ lt_cv_file_magic_cmd='/bin/file'
+ lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )'
+ ;;
+ sni)
+ lt_cv_file_magic_cmd='/bin/file'
+ lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib"
+ lt_cv_file_magic_test_file=/lib/libc.so
+ ;;
+ siemens)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ pc)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ esac
+ ;;
+
+tpf*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+esac
+])
+
+file_magic_glob=
+want_nocaseglob=no
+if test "$build" = "$host"; then
+ case $host_os in
+ mingw* | pw32*)
+ if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then
+ want_nocaseglob=yes
+ else
+ file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[[\1]]\/[[\1]]\/g;/g"`
+ fi
+ ;;
+ esac
+fi
+
+file_magic_cmd=$lt_cv_file_magic_cmd
+deplibs_check_method=$lt_cv_deplibs_check_method
+test -z "$deplibs_check_method" && deplibs_check_method=unknown
+
+_LT_DECL([], [deplibs_check_method], [1],
+ [Method to check whether dependent libraries are shared objects])
+_LT_DECL([], [file_magic_cmd], [1],
+ [Command to use when deplibs_check_method = "file_magic"])
+_LT_DECL([], [file_magic_glob], [1],
+ [How to find potential files when deplibs_check_method = "file_magic"])
+_LT_DECL([], [want_nocaseglob], [1],
+ [Find potential files using nocaseglob when deplibs_check_method = "file_magic"])
+])# _LT_CHECK_MAGIC_METHOD
+
+
+# LT_PATH_NM
+# ----------
+# find the pathname to a BSD- or MS-compatible name lister
+AC_DEFUN([LT_PATH_NM],
+[AC_REQUIRE([AC_PROG_CC])dnl
+AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM,
+[if test -n "$NM"; then
+ # Let the user override the test.
+ lt_cv_path_NM="$NM"
+else
+ lt_nm_to_check="${ac_tool_prefix}nm"
+ if test -n "$ac_tool_prefix" && test "$build" = "$host"; then
+ lt_nm_to_check="$lt_nm_to_check nm"
+ fi
+ for lt_tmp_nm in $lt_nm_to_check; do
+ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+ for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do
+ IFS="$lt_save_ifs"
+ test -z "$ac_dir" && ac_dir=.
+ tmp_nm="$ac_dir/$lt_tmp_nm"
+ if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then
+ # Check to see if the nm accepts a BSD-compat flag.
+ # Adding the `sed 1q' prevents false positives on HP-UX, which says:
+ # nm: unknown option "B" ignored
+ # Tru64's nm complains that /dev/null is an invalid object file
+ case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in
+ */dev/null* | *'Invalid file or object type'*)
+ lt_cv_path_NM="$tmp_nm -B"
+ break
+ ;;
+ *)
+ case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in
+ */dev/null*)
+ lt_cv_path_NM="$tmp_nm -p"
+ break
+ ;;
+ *)
+ lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
+ continue # so that we can try to find one that supports BSD flags
+ ;;
+ esac
+ ;;
+ esac
+ fi
+ done
+ IFS="$lt_save_ifs"
+ done
+ : ${lt_cv_path_NM=no}
+fi])
+if test "$lt_cv_path_NM" != "no"; then
+ NM="$lt_cv_path_NM"
+else
+ # Didn't find any BSD compatible name lister, look for dumpbin.
+ if test -n "$DUMPBIN"; then :
+ # Let the user override the test.
+ else
+ AC_CHECK_TOOLS(DUMPBIN, [dumpbin "link -dump"], :)
+ case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in
+ *COFF*)
+ DUMPBIN="$DUMPBIN -symbols"
+ ;;
+ *)
+ DUMPBIN=:
+ ;;
+ esac
+ fi
+ AC_SUBST([DUMPBIN])
+ if test "$DUMPBIN" != ":"; then
+ NM="$DUMPBIN"
+ fi
+fi
+test -z "$NM" && NM=nm
+AC_SUBST([NM])
+_LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl
+
+AC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface],
+ [lt_cv_nm_interface="BSD nm"
+ echo "int some_variable = 0;" > conftest.$ac_ext
+ (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&AS_MESSAGE_LOG_FD)
+ (eval "$ac_compile" 2>conftest.err)
+ cat conftest.err >&AS_MESSAGE_LOG_FD
+ (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD)
+ (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
+ cat conftest.err >&AS_MESSAGE_LOG_FD
+ (eval echo "\"\$as_me:$LINENO: output\"" >&AS_MESSAGE_LOG_FD)
+ cat conftest.out >&AS_MESSAGE_LOG_FD
+ if $GREP 'External.*some_variable' conftest.out > /dev/null; then
+ lt_cv_nm_interface="MS dumpbin"
+ fi
+ rm -f conftest*])
+])# LT_PATH_NM
+
+# Old names:
+AU_ALIAS([AM_PROG_NM], [LT_PATH_NM])
+AU_ALIAS([AC_PROG_NM], [LT_PATH_NM])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AM_PROG_NM], [])
+dnl AC_DEFUN([AC_PROG_NM], [])
+
+# _LT_CHECK_SHAREDLIB_FROM_LINKLIB
+# --------------------------------
+# how to determine the name of the shared library
+# associated with a specific link library.
+# -- PORTME fill in with the dynamic library characteristics
+m4_defun([_LT_CHECK_SHAREDLIB_FROM_LINKLIB],
+[m4_require([_LT_DECL_EGREP])
+m4_require([_LT_DECL_OBJDUMP])
+m4_require([_LT_DECL_DLLTOOL])
+AC_CACHE_CHECK([how to associate runtime and link libraries],
+lt_cv_sharedlib_from_linklib_cmd,
+[lt_cv_sharedlib_from_linklib_cmd='unknown'
+
+case $host_os in
+cygwin* | mingw* | pw32* | cegcc*)
+ # two different shell functions defined in ltmain.sh
+ # decide which to use based on capabilities of $DLLTOOL
+ case `$DLLTOOL --help 2>&1` in
+ *--identify-strict*)
+ lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib
+ ;;
+ *)
+ lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback
+ ;;
+ esac
+ ;;
+*)
+ # fallback: assume linklib IS sharedlib
+ lt_cv_sharedlib_from_linklib_cmd="$ECHO"
+ ;;
+esac
+])
+sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd
+test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO
+
+_LT_DECL([], [sharedlib_from_linklib_cmd], [1],
+ [Command to associate shared and link libraries])
+])# _LT_CHECK_SHAREDLIB_FROM_LINKLIB
+
+
+# _LT_PATH_MANIFEST_TOOL
+# ----------------------
+# locate the manifest tool
+m4_defun([_LT_PATH_MANIFEST_TOOL],
+[AC_CHECK_TOOL(MANIFEST_TOOL, mt, :)
+test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt
+AC_CACHE_CHECK([if $MANIFEST_TOOL is a manifest tool], [lt_cv_path_mainfest_tool],
+ [lt_cv_path_mainfest_tool=no
+ echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&AS_MESSAGE_LOG_FD
+ $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out
+ cat conftest.err >&AS_MESSAGE_LOG_FD
+ if $GREP 'Manifest Tool' conftest.out > /dev/null; then
+ lt_cv_path_mainfest_tool=yes
+ fi
+ rm -f conftest*])
+if test "x$lt_cv_path_mainfest_tool" != xyes; then
+ MANIFEST_TOOL=:
+fi
+_LT_DECL([], [MANIFEST_TOOL], [1], [Manifest tool])dnl
+])# _LT_PATH_MANIFEST_TOOL
+
+
+# LT_LIB_M
+# --------
+# check for math library
+AC_DEFUN([LT_LIB_M],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+LIBM=
+case $host in
+*-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-pw32* | *-*-darwin*)
+ # These system don't have libm, or don't need it
+ ;;
+*-ncr-sysv4.3*)
+ AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw")
+ AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm")
+ ;;
+*)
+ AC_CHECK_LIB(m, cos, LIBM="-lm")
+ ;;
+esac
+AC_SUBST([LIBM])
+])# LT_LIB_M
+
+# Old name:
+AU_ALIAS([AC_CHECK_LIBM], [LT_LIB_M])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_CHECK_LIBM], [])
+
+
+# _LT_COMPILER_NO_RTTI([TAGNAME])
+# -------------------------------
+m4_defun([_LT_COMPILER_NO_RTTI],
+[m4_require([_LT_TAG_COMPILER])dnl
+
+_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=
+
+if test "$GCC" = yes; then
+ case $cc_basename in
+ nvcc*)
+ _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -Xcompiler -fno-builtin' ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' ;;
+ esac
+
+ _LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions],
+ lt_cv_prog_compiler_rtti_exceptions,
+ [-fno-rtti -fno-exceptions], [],
+ [_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"])
+fi
+_LT_TAGDECL([no_builtin_flag], [lt_prog_compiler_no_builtin_flag], [1],
+ [Compiler flag to turn off builtin functions])
+])# _LT_COMPILER_NO_RTTI
+
+
+# _LT_CMD_GLOBAL_SYMBOLS
+# ----------------------
+m4_defun([_LT_CMD_GLOBAL_SYMBOLS],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_PROG_AWK])dnl
+AC_REQUIRE([LT_PATH_NM])dnl
+AC_REQUIRE([LT_PATH_LD])dnl
+m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_TAG_COMPILER])dnl
+
+# Check for command to grab the raw symbol name followed by C symbol from nm.
+AC_MSG_CHECKING([command to parse $NM output from $compiler object])
+AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe],
+[
+# These are sane defaults that work on at least a few old systems.
+# [They come from Ultrix. What could be older than Ultrix?!! ;)]
+
+# Character class describing NM global symbol codes.
+symcode='[[BCDEGRST]]'
+
+# Regexp to match symbols that can be accessed directly from C.
+sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)'
+
+# Define system-specific variables.
+case $host_os in
+aix*)
+ symcode='[[BCDT]]'
+ ;;
+cygwin* | mingw* | pw32* | cegcc*)
+ symcode='[[ABCDGISTW]]'
+ ;;
+hpux*)
+ if test "$host_cpu" = ia64; then
+ symcode='[[ABCDEGRST]]'
+ fi
+ ;;
+irix* | nonstopux*)
+ symcode='[[BCDEGRST]]'
+ ;;
+osf*)
+ symcode='[[BCDEGQRST]]'
+ ;;
+solaris*)
+ symcode='[[BDRT]]'
+ ;;
+sco3.2v5*)
+ symcode='[[DT]]'
+ ;;
+sysv4.2uw2*)
+ symcode='[[DT]]'
+ ;;
+sysv5* | sco5v6* | unixware* | OpenUNIX*)
+ symcode='[[ABDT]]'
+ ;;
+sysv4)
+ symcode='[[DFNSTU]]'
+ ;;
+esac
+
+# If we're using GNU nm, then use its standard symbol codes.
+case `$NM -V 2>&1` in
+*GNU* | *'with BFD'*)
+ symcode='[[ABCDGIRSTW]]' ;;
+esac
+
+# Transform an extracted symbol line into a proper C declaration.
+# Some systems (esp. on ia64) link data and code symbols differently,
+# so use this general approach.
+lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'"
+
+# Transform an extracted symbol line into symbol name and symbol address
+lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p'"
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \(lib[[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"lib\2\", (void *) \&\2},/p'"
+
+# Handle CRLF in mingw tool chain
+opt_cr=
+case $build_os in
+mingw*)
+ opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp
+ ;;
+esac
+
+# Try without a prefix underscore, then with it.
+for ac_symprfx in "" "_"; do
+
+ # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol.
+ symxfrm="\\1 $ac_symprfx\\2 \\2"
+
+ # Write the raw and C identifiers.
+ if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+ # Fake it for dumpbin and say T for any non-static function
+ # and D for any global variable.
+ # Also find C++ and __fastcall symbols from MSVC++,
+ # which start with @ or ?.
+ lt_cv_sys_global_symbol_pipe="$AWK ['"\
+" {last_section=section; section=\$ 3};"\
+" /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\
+" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\
+" \$ 0!~/External *\|/{next};"\
+" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\
+" {if(hide[section]) next};"\
+" {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\
+" {split(\$ 0, a, /\||\r/); split(a[2], s)};"\
+" s[1]~/^[@?]/{print s[1], s[1]; next};"\
+" s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\
+" ' prfx=^$ac_symprfx]"
+ else
+ lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'"
+ fi
+ lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'"
+
+ # Check to see that the pipe works correctly.
+ pipe_works=no
+
+ rm -f conftest*
+ cat > conftest.$ac_ext <<_LT_EOF
+#ifdef __cplusplus
+extern "C" {
+#endif
+char nm_test_var;
+void nm_test_func(void);
+void nm_test_func(void){}
+#ifdef __cplusplus
+}
+#endif
+int main(){nm_test_var='a';nm_test_func();return(0);}
+_LT_EOF
+
+ if AC_TRY_EVAL(ac_compile); then
+ # Now try to grab the symbols.
+ nlist=conftest.nm
+ if AC_TRY_EVAL(NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) && test -s "$nlist"; then
+ # Try sorting and uniquifying the output.
+ if sort "$nlist" | uniq > "$nlist"T; then
+ mv -f "$nlist"T "$nlist"
+ else
+ rm -f "$nlist"T
+ fi
+
+ # Make sure that we snagged all the symbols we need.
+ if $GREP ' nm_test_var$' "$nlist" >/dev/null; then
+ if $GREP ' nm_test_func$' "$nlist" >/dev/null; then
+ cat <<_LT_EOF > conftest.$ac_ext
+/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */
+#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE)
+/* DATA imports from DLLs on WIN32 con't be const, because runtime
+ relocations are performed -- see ld's documentation on pseudo-relocs. */
+# define LT@&t@_DLSYM_CONST
+#elif defined(__osf__)
+/* This system does not cope well with relocations in const data. */
+# define LT@&t@_DLSYM_CONST
+#else
+# define LT@&t@_DLSYM_CONST const
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+_LT_EOF
+ # Now generate the symbol file.
+ eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext'
+
+ cat <<_LT_EOF >> conftest.$ac_ext
+
+/* The mapping between symbol names and symbols. */
+LT@&t@_DLSYM_CONST struct {
+ const char *name;
+ void *address;
+}
+lt__PROGRAM__LTX_preloaded_symbols[[]] =
+{
+ { "@PROGRAM@", (void *) 0 },
+_LT_EOF
+ $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext
+ cat <<\_LT_EOF >> conftest.$ac_ext
+ {0, (void *) 0}
+};
+
+/* This works around a problem in FreeBSD linker */
+#ifdef FREEBSD_WORKAROUND
+static const void *lt_preloaded_setup() {
+ return lt__PROGRAM__LTX_preloaded_symbols;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+_LT_EOF
+ # Now try linking the two files.
+ mv conftest.$ac_objext conftstm.$ac_objext
+ lt_globsym_save_LIBS=$LIBS
+ lt_globsym_save_CFLAGS=$CFLAGS
+ LIBS="conftstm.$ac_objext"
+ CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)"
+ if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext}; then
+ pipe_works=yes
+ fi
+ LIBS=$lt_globsym_save_LIBS
+ CFLAGS=$lt_globsym_save_CFLAGS
+ else
+ echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD
+ fi
+ else
+ echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD
+ fi
+ else
+ echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD
+ fi
+ else
+ echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD
+ cat conftest.$ac_ext >&5
+ fi
+ rm -rf conftest* conftst*
+
+ # Do not use the global_symbol_pipe unless it works.
+ if test "$pipe_works" = yes; then
+ break
+ else
+ lt_cv_sys_global_symbol_pipe=
+ fi
+done
+])
+if test -z "$lt_cv_sys_global_symbol_pipe"; then
+ lt_cv_sys_global_symbol_to_cdecl=
+fi
+if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then
+ AC_MSG_RESULT(failed)
+else
+ AC_MSG_RESULT(ok)
+fi
+
+# Response file support.
+if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+ nm_file_list_spec='@'
+elif $NM --help 2>/dev/null | grep '[[@]]FILE' >/dev/null; then
+ nm_file_list_spec='@'
+fi
+
+_LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1],
+ [Take the output of nm and produce a listing of raw symbols and C names])
+_LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1],
+ [Transform the output of nm in a proper C declaration])
+_LT_DECL([global_symbol_to_c_name_address],
+ [lt_cv_sys_global_symbol_to_c_name_address], [1],
+ [Transform the output of nm in a C name address pair])
+_LT_DECL([global_symbol_to_c_name_address_lib_prefix],
+ [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1],
+ [Transform the output of nm in a C name address pair when lib prefix is needed])
+_LT_DECL([], [nm_file_list_spec], [1],
+ [Specify filename containing input files for $NM])
+]) # _LT_CMD_GLOBAL_SYMBOLS
+
+
+# _LT_COMPILER_PIC([TAGNAME])
+# ---------------------------
+m4_defun([_LT_COMPILER_PIC],
+[m4_require([_LT_TAG_COMPILER])dnl
+_LT_TAGVAR(lt_prog_compiler_wl, $1)=
+_LT_TAGVAR(lt_prog_compiler_pic, $1)=
+_LT_TAGVAR(lt_prog_compiler_static, $1)=
+
+m4_if([$1], [CXX], [
+ # C++ specific cases for pic, static, wl, etc.
+ if test "$GXX" = yes; then
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+
+ case $host_os in
+ aix*)
+ # All AIX code is PIC.
+ if test "$host_cpu" = ia64; then
+ # AIX 5 now supports IA64 processor
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ fi
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ m68k)
+ # FIXME: we need at least 68020 code to build shared libraries, but
+ # adding the `-m68020' flag to GCC prevents building anything better,
+ # like `-m68040'.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4'
+ ;;
+ esac
+ ;;
+
+ beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+ # PIC is the default for these OSes.
+ ;;
+ mingw* | cygwin* | os2* | pw32* | cegcc*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ # Although the cygwin gcc ignores -fPIC, still need this for old-style
+ # (--disable-auto-import) libraries
+ m4_if([$1], [GCJ], [],
+ [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
+ ;;
+ darwin* | rhapsody*)
+ # PIC is the default on this platform
+ # Common symbols not allowed in MH_DYLIB files
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common'
+ ;;
+ *djgpp*)
+ # DJGPP does not support shared libraries at all
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)=
+ ;;
+ haiku*)
+ # PIC is the default for Haiku.
+ # The "-static" flag exists, but is broken.
+ _LT_TAGVAR(lt_prog_compiler_static, $1)=
+ ;;
+ interix[[3-9]]*)
+ # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+ # Instead, we relocate shared libraries at runtime.
+ ;;
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic
+ fi
+ ;;
+ hpux*)
+ # PIC is the default for 64-bit PA HP-UX, but not for 32-bit
+ # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag
+ # sets the default TLS model and affects inlining.
+ case $host_cpu in
+ hppa*64*)
+ ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ esac
+ ;;
+ *qnx* | *nto*)
+ # QNX uses GNU C++, but need to define -shared option too, otherwise
+ # it will coredump.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
+ ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ esac
+ else
+ case $host_os in
+ aix[[4-9]]*)
+ # All AIX code is PIC.
+ if test "$host_cpu" = ia64; then
+ # AIX 5 now supports IA64 processor
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ else
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp'
+ fi
+ ;;
+ chorus*)
+ case $cc_basename in
+ cxch68*)
+ # Green Hills C++ Compiler
+ # _LT_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a"
+ ;;
+ esac
+ ;;
+ mingw* | cygwin* | os2* | pw32* | cegcc*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ m4_if([$1], [GCJ], [],
+ [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
+ ;;
+ dgux*)
+ case $cc_basename in
+ ec++*)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ ;;
+ ghcx*)
+ # Green Hills C++ Compiler
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ freebsd* | dragonfly*)
+ # FreeBSD uses GNU C++
+ ;;
+ hpux9* | hpux10* | hpux11*)
+ case $cc_basename in
+ CC*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive'
+ if test "$host_cpu" != ia64; then
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
+ fi
+ ;;
+ aCC*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive'
+ case $host_cpu in
+ hppa*64*|ia64*)
+ # +Z the default
+ ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
+ ;;
+ esac
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ interix*)
+ # This is c89, which is MS Visual C++ (no shared libs)
+ # Anyone wants to do a port?
+ ;;
+ irix5* | irix6* | nonstopux*)
+ case $cc_basename in
+ CC*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ # CC pic flag -KPIC is the default.
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ linux* | k*bsd*-gnu | kopensolaris*-gnu)
+ case $cc_basename in
+ KCC*)
+ # KAI C++ Compiler
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ ecpc* )
+ # old Intel C++ for x86_64 which still supported -KPIC.
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+ ;;
+ icpc* )
+ # Intel C++, used to be incompatible with GCC.
+ # ICC 10 doesn't accept -KPIC any more.
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+ ;;
+ pgCC* | pgcpp*)
+ # Portland Group C++ compiler
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+ cxx*)
+ # Compaq C++
+ # Make sure the PIC flag is empty. It appears that all Alpha
+ # Linux and Compaq Tru64 Unix objects are PIC.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)=
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ ;;
+ xlc* | xlC* | bgxl[[cC]]* | mpixl[[cC]]*)
+ # IBM XL 8.0, 9.0 on PPC and BlueGene
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink'
+ ;;
+ *)
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ C*)
+ # Sun C++ 5.9
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
+ ;;
+ esac
+ ;;
+ esac
+ ;;
+ lynxos*)
+ ;;
+ m88k*)
+ ;;
+ mvs*)
+ case $cc_basename in
+ cxx*)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ netbsd*)
+ ;;
+ *qnx* | *nto*)
+ # QNX uses GNU C++, but need to define -shared option too, otherwise
+ # it will coredump.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
+ ;;
+ osf3* | osf4* | osf5*)
+ case $cc_basename in
+ KCC*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,'
+ ;;
+ RCC*)
+ # Rational C++ 2.4.1
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+ ;;
+ cxx*)
+ # Digital/Compaq C++
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ # Make sure the PIC flag is empty. It appears that all Alpha
+ # Linux and Compaq Tru64 Unix objects are PIC.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)=
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ psos*)
+ ;;
+ solaris*)
+ case $cc_basename in
+ CC* | sunCC*)
+ # Sun C++ 4.2, 5.x and Centerline C++
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
+ ;;
+ gcx*)
+ # Green Hills C++ Compiler
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ sunos4*)
+ case $cc_basename in
+ CC*)
+ # Sun C++ 4.x
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+ lcc*)
+ # Lucid
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+ case $cc_basename in
+ CC*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+ esac
+ ;;
+ tandem*)
+ case $cc_basename in
+ NCC*)
+ # NonStop-UX NCC 3.20
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ vxworks*)
+ ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+ ;;
+ esac
+ fi
+],
+[
+ if test "$GCC" = yes; then
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+
+ case $host_os in
+ aix*)
+ # All AIX code is PIC.
+ if test "$host_cpu" = ia64; then
+ # AIX 5 now supports IA64 processor
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ fi
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ m68k)
+ # FIXME: we need at least 68020 code to build shared libraries, but
+ # adding the `-m68020' flag to GCC prevents building anything better,
+ # like `-m68040'.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4'
+ ;;
+ esac
+ ;;
+
+ beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+ # PIC is the default for these OSes.
+ ;;
+
+ mingw* | cygwin* | pw32* | os2* | cegcc*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ # Although the cygwin gcc ignores -fPIC, still need this for old-style
+ # (--disable-auto-import) libraries
+ m4_if([$1], [GCJ], [],
+ [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
+ ;;
+
+ darwin* | rhapsody*)
+ # PIC is the default on this platform
+ # Common symbols not allowed in MH_DYLIB files
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common'
+ ;;
+
+ haiku*)
+ # PIC is the default for Haiku.
+ # The "-static" flag exists, but is broken.
+ _LT_TAGVAR(lt_prog_compiler_static, $1)=
+ ;;
+
+ hpux*)
+ # PIC is the default for 64-bit PA HP-UX, but not for 32-bit
+ # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag
+ # sets the default TLS model and affects inlining.
+ case $host_cpu in
+ hppa*64*)
+ # +Z the default
+ ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ esac
+ ;;
+
+ interix[[3-9]]*)
+ # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+ # Instead, we relocate shared libraries at runtime.
+ ;;
+
+ msdosdjgpp*)
+ # Just because we use GCC doesn't mean we suddenly get shared libraries
+ # on systems that don't support them.
+ _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+ enable_shared=no
+ ;;
+
+ *nto* | *qnx*)
+ # QNX uses GNU C++, but need to define -shared option too, otherwise
+ # it will coredump.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic
+ fi
+ ;;
+
+ *)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ esac
+
+ case $cc_basename in
+ nvcc*) # Cuda Compiler Driver 2.2
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Xlinker '
+ if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)="-Xcompiler $_LT_TAGVAR(lt_prog_compiler_pic, $1)"
+ fi
+ ;;
+ esac
+ else
+ # PORTME Check for flag to pass linker flags through the system compiler.
+ case $host_os in
+ aix*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ if test "$host_cpu" = ia64; then
+ # AIX 5 now supports IA64 processor
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ else
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp'
+ fi
+ ;;
+
+ mingw* | cygwin* | pw32* | os2* | cegcc*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ m4_if([$1], [GCJ], [],
+ [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
+ ;;
+
+ hpux9* | hpux10* | hpux11*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
+ # not for PA HP-UX.
+ case $host_cpu in
+ hppa*64*|ia64*)
+ # +Z the default
+ ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
+ ;;
+ esac
+ # Is there a better lt_prog_compiler_static that works with the bundled CC?
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive'
+ ;;
+
+ irix5* | irix6* | nonstopux*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ # PIC (with -KPIC) is the default.
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ ;;
+
+ linux* | k*bsd*-gnu | kopensolaris*-gnu)
+ case $cc_basename in
+ # old Intel for x86_64 which still supported -KPIC.
+ ecc*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+ ;;
+ # icc used to be incompatible with GCC.
+ # ICC 10 doesn't accept -KPIC any more.
+ icc* | ifort*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+ ;;
+ # Lahey Fortran 8.1.
+ lf95*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='--static'
+ ;;
+ nagfor*)
+ # NAG Fortran compiler
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+ pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*)
+ # Portland Group compilers (*not* the Pentium gcc compiler,
+ # which looks to be a dead project)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+ ccc*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ # All Alpha code is PIC.
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ ;;
+ xl* | bgxl* | bgf* | mpixl*)
+ # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink'
+ ;;
+ *)
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [[1-7]].* | *Sun*Fortran*\ 8.[[0-3]]*)
+ # Sun Fortran 8.3 passes all unrecognized flags to the linker
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)=''
+ ;;
+ *Sun\ F* | *Sun*Fortran*)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
+ ;;
+ *Sun\ C*)
+ # Sun C 5.9
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ ;;
+ *Intel*\ [[CF]]*Compiler*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+ ;;
+ *Portland\ Group*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+ esac
+ ;;
+ esac
+ ;;
+
+ newsos6)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+
+ *nto* | *qnx*)
+ # QNX uses GNU C++, but need to define -shared option too, otherwise
+ # it will coredump.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
+ ;;
+
+ osf3* | osf4* | osf5*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ # All OSF/1 code is PIC.
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ ;;
+
+ rdos*)
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ ;;
+
+ solaris*)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ case $cc_basename in
+ f77* | f90* | f95* | sunf77* | sunf90* | sunf95*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';;
+ esac
+ ;;
+
+ sunos4*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+
+ sysv4 | sysv4.2uw2* | sysv4.3*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec ;then
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ fi
+ ;;
+
+ sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+
+ unicos*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+ ;;
+
+ uts4*)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+
+ *)
+ _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+ ;;
+ esac
+ fi
+])
+case $host_os in
+ # For platforms which do not support PIC, -DPIC is meaningless:
+ *djgpp*)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)=
+ ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])"
+ ;;
+esac
+
+AC_CACHE_CHECK([for $compiler option to produce PIC],
+ [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)],
+ [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_prog_compiler_pic, $1)])
+_LT_TAGVAR(lt_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)
+
+#
+# Check to make sure the PIC flag actually works.
+#
+if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then
+ _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, $1) works],
+ [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, $1)],
+ [$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])], [],
+ [case $_LT_TAGVAR(lt_prog_compiler_pic, $1) in
+ "" | " "*) ;;
+ *) _LT_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_TAGVAR(lt_prog_compiler_pic, $1)" ;;
+ esac],
+ [_LT_TAGVAR(lt_prog_compiler_pic, $1)=
+ _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no])
+fi
+_LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1],
+ [Additional compiler flags for building library objects])
+
+_LT_TAGDECL([wl], [lt_prog_compiler_wl], [1],
+ [How to pass a linker flag through the compiler])
+#
+# Check to make sure the static flag actually works.
+#
+wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_TAGVAR(lt_prog_compiler_static, $1)\"
+_LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works],
+ _LT_TAGVAR(lt_cv_prog_compiler_static_works, $1),
+ $lt_tmp_static_flag,
+ [],
+ [_LT_TAGVAR(lt_prog_compiler_static, $1)=])
+_LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1],
+ [Compiler flag to prevent dynamic linking])
+])# _LT_COMPILER_PIC
+
+
+# _LT_LINKER_SHLIBS([TAGNAME])
+# ----------------------------
+# See if the linker supports building shared libraries.
+m4_defun([_LT_LINKER_SHLIBS],
+[AC_REQUIRE([LT_PATH_LD])dnl
+AC_REQUIRE([LT_PATH_NM])dnl
+m4_require([_LT_PATH_MANIFEST_TOOL])dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl
+m4_require([_LT_TAG_COMPILER])dnl
+AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries])
+m4_if([$1], [CXX], [
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+ _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*']
+ case $host_os in
+ aix[[4-9]]*)
+ # If we're using GNU nm, then we don't want the "-C" option.
+ # -C means demangle to AIX nm, but means don't demangle with GNU nm
+ # Also, AIX nm treats weak defined symbols like other global defined
+ # symbols, whereas GNU nm marks them as "W".
+ if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+ else
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+ fi
+ ;;
+ pw32*)
+ _LT_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds"
+ ;;
+ cygwin* | mingw* | cegcc*)
+ case $cc_basename in
+ cl*)
+ _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*'
+ ;;
+ *)
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols'
+ _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname']
+ ;;
+ esac
+ ;;
+ *)
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+ ;;
+ esac
+], [
+ runpath_var=
+ _LT_TAGVAR(allow_undefined_flag, $1)=
+ _LT_TAGVAR(always_export_symbols, $1)=no
+ _LT_TAGVAR(archive_cmds, $1)=
+ _LT_TAGVAR(archive_expsym_cmds, $1)=
+ _LT_TAGVAR(compiler_needs_object, $1)=no
+ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)=
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+ _LT_TAGVAR(hardcode_automatic, $1)=no
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=no
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=
+ _LT_TAGVAR(hardcode_minus_L, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
+ _LT_TAGVAR(inherit_rpath, $1)=no
+ _LT_TAGVAR(link_all_deplibs, $1)=unknown
+ _LT_TAGVAR(module_cmds, $1)=
+ _LT_TAGVAR(module_expsym_cmds, $1)=
+ _LT_TAGVAR(old_archive_from_new_cmds, $1)=
+ _LT_TAGVAR(old_archive_from_expsyms_cmds, $1)=
+ _LT_TAGVAR(thread_safe_flag_spec, $1)=
+ _LT_TAGVAR(whole_archive_flag_spec, $1)=
+ # include_expsyms should be a list of space-separated symbols to be *always*
+ # included in the symbol list
+ _LT_TAGVAR(include_expsyms, $1)=
+ # exclude_expsyms can be an extended regexp of symbols to exclude
+ # it will be wrapped by ` (' and `)$', so one must not match beginning or
+ # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc',
+ # as well as any symbol that contains `d'.
+ _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*']
+ # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
+ # platforms (ab)use it in PIC code, but their linkers get confused if
+ # the symbol is explicitly referenced. Since portable code cannot
+ # rely on this symbol name, it's probably fine to never include it in
+ # preloaded symbol tables.
+ # Exclude shared library initialization/finalization symbols.
+dnl Note also adjust exclude_expsyms for C++ above.
+ extract_expsyms_cmds=
+
+ case $host_os in
+ cygwin* | mingw* | pw32* | cegcc*)
+ # FIXME: the MSVC++ port hasn't been tested in a loooong time
+ # When not using gcc, we currently assume that we are using
+ # Microsoft Visual C++.
+ if test "$GCC" != yes; then
+ with_gnu_ld=no
+ fi
+ ;;
+ interix*)
+ # we just hope/assume this is gcc and not c89 (= MSVC++)
+ with_gnu_ld=yes
+ ;;
+ openbsd*)
+ with_gnu_ld=no
+ ;;
+ esac
+
+ _LT_TAGVAR(ld_shlibs, $1)=yes
+
+ # On some targets, GNU ld is compatible enough with the native linker
+ # that we're better off using the native interface for both.
+ lt_use_gnu_ld_interface=no
+ if test "$with_gnu_ld" = yes; then
+ case $host_os in
+ aix*)
+ # The AIX port of GNU ld has always aspired to compatibility
+ # with the native linker. However, as the warning in the GNU ld
+ # block says, versions before 2.19.5* couldn't really create working
+ # shared libraries, regardless of the interface used.
+ case `$LD -v 2>&1` in
+ *\ \(GNU\ Binutils\)\ 2.19.5*) ;;
+ *\ \(GNU\ Binutils\)\ 2.[[2-9]]*) ;;
+ *\ \(GNU\ Binutils\)\ [[3-9]]*) ;;
+ *)
+ lt_use_gnu_ld_interface=yes
+ ;;
+ esac
+ ;;
+ *)
+ lt_use_gnu_ld_interface=yes
+ ;;
+ esac
+ fi
+
+ if test "$lt_use_gnu_ld_interface" = yes; then
+ # If archive_cmds runs LD, not CC, wlarc should be empty
+ wlarc='${wl}'
+
+ # Set some defaults for GNU ld with shared library support. These
+ # are reset later if shared libraries are not supported. Putting them
+ # here allows them to be overridden if necessary.
+ runpath_var=LD_RUN_PATH
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+ # ancient GNU ld didn't support --whole-archive et. al.
+ if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then
+ _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+ else
+ _LT_TAGVAR(whole_archive_flag_spec, $1)=
+ fi
+ supports_anon_versioning=no
+ case `$LD -v 2>&1` in
+ *GNU\ gold*) supports_anon_versioning=yes ;;
+ *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11
+ *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
+ *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...
+ *\ 2.11.*) ;; # other 2.11 versions
+ *) supports_anon_versioning=yes ;;
+ esac
+
+ # See if GNU ld supports shared libraries.
+ case $host_os in
+ aix[[3-9]]*)
+ # On AIX/PPC, the GNU linker is very broken
+ if test "$host_cpu" != ia64; then
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ cat <<_LT_EOF 1>&2
+
+*** Warning: the GNU linker, at least up to release 2.19, is reported
+*** to be unable to reliably create shared libraries on AIX.
+*** Therefore, libtool is disabling shared libraries support. If you
+*** really care for shared libraries, you may want to install binutils
+*** 2.20 or above, or modify your PATH so that a non-GNU linker is found.
+*** You will then need to restart the configuration process.
+
+_LT_EOF
+ fi
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)=''
+ ;;
+ m68k)
+ _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ ;;
+ esac
+ ;;
+
+ beos*)
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+ # support --undefined. This deserves some investigation. FIXME
+ _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ cygwin* | mingw* | pw32* | cegcc*)
+ # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless,
+ # as there is no search path for DLLs.
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols'
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ _LT_TAGVAR(always_export_symbols, $1)=no
+ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols'
+ _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname']
+
+ if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ # If the export-symbols file already is a .def file (1st line
+ # is EXPORTS), use it as is; otherwise, prepend...
+ _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+ cp $export_symbols $output_objdir/$soname.def;
+ else
+ echo EXPORTS > $output_objdir/$soname.def;
+ cat $export_symbols >> $output_objdir/$soname.def;
+ fi~
+ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ haiku*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ ;;
+
+ interix[[3-9]]*)
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+ # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+ # Instead, shared libraries are loaded at an image base (0x10000000 by
+ # default) and relocated if they conflict, which is a slow very memory
+ # consuming and fragmenting process. To avoid this, we pick a random,
+ # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+ # time. Moving up from 0x10000000 also allows more sbrk(2) space.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ ;;
+
+ gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu)
+ tmp_diet=no
+ if test "$host_os" = linux-dietlibc; then
+ case $cc_basename in
+ diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn)
+ esac
+ fi
+ if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \
+ && test "$tmp_diet" = no
+ then
+ tmp_addflag=' $pic_flag'
+ tmp_sharedflag='-shared'
+ case $cc_basename,$host_cpu in
+ pgcc*) # Portland Group C compiler
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+ tmp_addflag=' $pic_flag'
+ ;;
+ pgf77* | pgf90* | pgf95* | pgfortran*)
+ # Portland Group f77 and f90 compilers
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+ tmp_addflag=' $pic_flag -Mnomain' ;;
+ ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64
+ tmp_addflag=' -i_dynamic' ;;
+ efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64
+ tmp_addflag=' -i_dynamic -nofor_main' ;;
+ ifc* | ifort*) # Intel Fortran compiler
+ tmp_addflag=' -nofor_main' ;;
+ lf95*) # Lahey Fortran 8.1
+ _LT_TAGVAR(whole_archive_flag_spec, $1)=
+ tmp_sharedflag='--shared' ;;
+ xl[[cC]]* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below)
+ tmp_sharedflag='-qmkshrobj'
+ tmp_addflag= ;;
+ nvcc*) # Cuda Compiler Driver 2.2
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+ _LT_TAGVAR(compiler_needs_object, $1)=yes
+ ;;
+ esac
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ C*) # Sun C 5.9
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+ _LT_TAGVAR(compiler_needs_object, $1)=yes
+ tmp_sharedflag='-G' ;;
+ *Sun\ F*) # Sun Fortran 8.3
+ tmp_sharedflag='-G' ;;
+ esac
+ _LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+
+ if test "x$supports_anon_versioning" = xyes; then
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
+ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+ echo "local: *; };" >> $output_objdir/$libname.ver~
+ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
+ fi
+
+ case $cc_basename in
+ xlf* | bgf* | bgxlf* | mpixlf*)
+ # IBM XL Fortran 10.1 on PPC cannot create shared libs itself
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib'
+ if test "x$supports_anon_versioning" = xyes; then
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
+ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+ echo "local: *; };" >> $output_objdir/$libname.ver~
+ $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
+ fi
+ ;;
+ esac
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ netbsd*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
+ wlarc=
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ fi
+ ;;
+
+ solaris*)
+ if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ cat <<_LT_EOF 1>&2
+
+*** Warning: The releases 2.8.* of the GNU linker cannot reliably
+*** create shared libraries on Solaris systems. Therefore, libtool
+*** is disabling shared libraries support. We urge you to upgrade GNU
+*** binutils to release 2.9.1 or newer. Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+ elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
+ case `$LD -v 2>&1` in
+ *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*)
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ cat <<_LT_EOF 1>&2
+
+*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not
+*** reliably create shared libraries on SCO systems. Therefore, libtool
+*** is disabling shared libraries support. We urge you to upgrade GNU
+*** binutils to release 2.16.91.0.3 or newer. Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+ ;;
+ *)
+ # For security reasons, it is highly recommended that you always
+ # use absolute paths for naming shared libraries, and exclude the
+ # DT_RUNPATH tag from executables and libraries. But doing so
+ # requires that you compile everything twice, which is a pain.
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+ esac
+ ;;
+
+ sunos4*)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ wlarc=
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ *)
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+ esac
+
+ if test "$_LT_TAGVAR(ld_shlibs, $1)" = no; then
+ runpath_var=
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)=
+ _LT_TAGVAR(whole_archive_flag_spec, $1)=
+ fi
+ else
+ # PORTME fill in a description of your system's linker (not GNU ld)
+ case $host_os in
+ aix3*)
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ _LT_TAGVAR(always_export_symbols, $1)=yes
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname'
+ # Note: this linker hardcodes the directories in LIBPATH if there
+ # are no directories specified by -L.
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then
+ # Neither direct hardcoding nor static linking is supported with a
+ # broken collect2.
+ _LT_TAGVAR(hardcode_direct, $1)=unsupported
+ fi
+ ;;
+
+ aix[[4-9]]*)
+ if test "$host_cpu" = ia64; then
+ # On IA64, the linker does run time linking by default, so we don't
+ # have to do anything special.
+ aix_use_runtimelinking=no
+ exp_sym_flag='-Bexport'
+ no_entry_flag=""
+ else
+ # If we're using GNU nm, then we don't want the "-C" option.
+ # -C means demangle to AIX nm, but means don't demangle with GNU nm
+ # Also, AIX nm treats weak defined symbols like other global
+ # defined symbols, whereas GNU nm marks them as "W".
+ if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+ else
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+ fi
+ aix_use_runtimelinking=no
+
+ # Test if we are trying to use run time linking or normal
+ # AIX style linking. If -brtl is somewhere in LDFLAGS, we
+ # need to do runtime linking.
+ case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*)
+ for ld_flag in $LDFLAGS; do
+ if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
+ aix_use_runtimelinking=yes
+ break
+ fi
+ done
+ ;;
+ esac
+
+ exp_sym_flag='-bexport'
+ no_entry_flag='-bnoentry'
+ fi
+
+ # When large executables or shared objects are built, AIX ld can
+ # have problems creating the table of contents. If linking a library
+ # or program results in "error TOC overflow" add -mminimal-toc to
+ # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not
+ # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+ _LT_TAGVAR(archive_cmds, $1)=''
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ _LT_TAGVAR(file_list_spec, $1)='${wl}-f,'
+
+ if test "$GCC" = yes; then
+ case $host_os in aix4.[[012]]|aix4.[[012]].*)
+ # We only want to do this on AIX 4.2 and lower, the check
+ # below for broken collect2 doesn't work under 4.3+
+ collect2name=`${CC} -print-prog-name=collect2`
+ if test -f "$collect2name" &&
+ strings "$collect2name" | $GREP resolve_lib_name >/dev/null
+ then
+ # We have reworked collect2
+ :
+ else
+ # We have old collect2
+ _LT_TAGVAR(hardcode_direct, $1)=unsupported
+ # It fails to find uninstalled libraries when the uninstalled
+ # path is not listed in the libpath. Setting hardcode_minus_L
+ # to unsupported forces relinking
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=
+ fi
+ ;;
+ esac
+ shared_flag='-shared'
+ if test "$aix_use_runtimelinking" = yes; then
+ shared_flag="$shared_flag "'${wl}-G'
+ fi
+ else
+ # not using gcc
+ if test "$host_cpu" = ia64; then
+ # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+ # chokes on -Wl,-G. The following line is correct:
+ shared_flag='-G'
+ else
+ if test "$aix_use_runtimelinking" = yes; then
+ shared_flag='${wl}-G'
+ else
+ shared_flag='${wl}-bM:SRE'
+ fi
+ fi
+ fi
+
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall'
+ # It seems that -bexpall does not export symbols beginning with
+ # underscore (_), so it is better to generate a list of symbols to export.
+ _LT_TAGVAR(always_export_symbols, $1)=yes
+ if test "$aix_use_runtimelinking" = yes; then
+ # Warning - without using the other runtime loading flags (-brtl),
+ # -berok will link without error, but may produce a broken library.
+ _LT_TAGVAR(allow_undefined_flag, $1)='-berok'
+ # Determine the default libpath from the value encoded in an
+ # empty executable.
+ _LT_SYS_MODULE_PATH_AIX([$1])
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+ else
+ if test "$host_cpu" = ia64; then
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib'
+ _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs"
+ _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
+ else
+ # Determine the default libpath from the value encoded in an
+ # empty executable.
+ _LT_SYS_MODULE_PATH_AIX([$1])
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
+ # Warning - without using the other run time loading flags,
+ # -berok will link without error, but may produce a broken library.
+ _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok'
+ _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok'
+ if test "$with_gnu_ld" = yes; then
+ # We only use this code for GNU lds that support --whole-archive.
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
+ else
+ # Exported symbols can be pulled into shared objects from archives
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience'
+ fi
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=yes
+ # This is similar to how AIX traditionally builds its shared libraries.
+ _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+ fi
+ fi
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)=''
+ ;;
+ m68k)
+ _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ ;;
+ esac
+ ;;
+
+ bsdi[[45]]*)
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic
+ ;;
+
+ cygwin* | mingw* | pw32* | cegcc*)
+ # When not using gcc, we currently assume that we are using
+ # Microsoft Visual C++.
+ # hardcode_libdir_flag_spec is actually meaningless, as there is
+ # no search path for DLLs.
+ case $cc_basename in
+ cl*)
+ # Native MSVC
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ _LT_TAGVAR(always_export_symbols, $1)=yes
+ _LT_TAGVAR(file_list_spec, $1)='@'
+ # Tell ltmain to make .lib files, not .a files.
+ libext=lib
+ # Tell ltmain to make .dll files, not .so files.
+ shrext_cmds=".dll"
+ # FIXME: Setting linknames here is a bad hack.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames='
+ _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+ sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp;
+ else
+ sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp;
+ fi~
+ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
+ linknames='
+ # The linker will not automatically build a static lib if we build a DLL.
+ # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true'
+ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+ _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*'
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1,DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols'
+ # Don't use ranlib
+ _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib'
+ _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~
+ lt_tool_outputfile="@TOOL_OUTPUT@"~
+ case $lt_outputfile in
+ *.exe|*.EXE) ;;
+ *)
+ lt_outputfile="$lt_outputfile.exe"
+ lt_tool_outputfile="$lt_tool_outputfile.exe"
+ ;;
+ esac~
+ if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then
+ $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
+ $RM "$lt_outputfile.manifest";
+ fi'
+ ;;
+ *)
+ # Assume MSVC wrapper
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ # Tell ltmain to make .lib files, not .a files.
+ libext=lib
+ # Tell ltmain to make .dll files, not .so files.
+ shrext_cmds=".dll"
+ # FIXME: Setting linknames here is a bad hack.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames='
+ # The linker will automatically build a .lib file if we build a DLL.
+ _LT_TAGVAR(old_archive_from_new_cmds, $1)='true'
+ # FIXME: Should let the user specify the lib program.
+ _LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs'
+ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+ ;;
+ esac
+ ;;
+
+ darwin* | rhapsody*)
+ _LT_DARWIN_LINKER_FEATURES($1)
+ ;;
+
+ dgux*)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
+ # support. Future versions do this automatically, but an explicit c++rt0.o
+ # does not break anything, and helps significantly (at the cost of a little
+ # extra space).
+ freebsd2.2*)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ # Unfortunately, older versions of FreeBSD 2 do not have this feature.
+ freebsd2.*)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
+ freebsd* | dragonfly*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ hpux9*)
+ if test "$GCC" = yes; then
+ _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+ fi
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+ ;;
+
+ hpux10*)
+ if test "$GCC" = yes && test "$with_gnu_ld" = no; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+ fi
+ if test "$with_gnu_ld" = no; then
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ fi
+ ;;
+
+ hpux11*)
+ if test "$GCC" = yes && test "$with_gnu_ld" = no; then
+ case $host_cpu in
+ hppa*64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ ia64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ *)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ esac
+ else
+ case $host_cpu in
+ hppa*64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ ia64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ *)
+ m4_if($1, [], [
+ # Older versions of the 11.00 compiler do not understand -b yet
+ # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does)
+ _LT_LINKER_OPTION([if $CC understands -b],
+ _LT_TAGVAR(lt_cv_prog_compiler__b, $1), [-b],
+ [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'],
+ [_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'])],
+ [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'])
+ ;;
+ esac
+ fi
+ if test "$with_gnu_ld" = no; then
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+ case $host_cpu in
+ hppa*64*|ia64*)
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+ *)
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ ;;
+ esac
+ fi
+ ;;
+
+ irix5* | irix6* | nonstopux*)
+ if test "$GCC" = yes; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ # Try to use the -exported_symbol ld option, if it does not
+ # work, assume that -exports_file does not work either and
+ # implicitly export all symbols.
+ # This should be the same for all languages, so no per-tag cache variable.
+ AC_CACHE_CHECK([whether the $host_os linker accepts -exported_symbol],
+ [lt_cv_irix_exported_symbol],
+ [save_LDFLAGS="$LDFLAGS"
+ LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null"
+ AC_LINK_IFELSE(
+ [AC_LANG_SOURCE(
+ [AC_LANG_CASE([C], [[int foo (void) { return 0; }]],
+ [C++], [[int foo (void) { return 0; }]],
+ [Fortran 77], [[
+ subroutine foo
+ end]],
+ [Fortran], [[
+ subroutine foo
+ end]])])],
+ [lt_cv_irix_exported_symbol=yes],
+ [lt_cv_irix_exported_symbol=no])
+ LDFLAGS="$save_LDFLAGS"])
+ if test "$lt_cv_irix_exported_symbol" = yes; then
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib'
+ fi
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib'
+ fi
+ _LT_TAGVAR(archive_cmds_need_lc, $1)='no'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ _LT_TAGVAR(inherit_rpath, $1)=yes
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ ;;
+
+ netbsd*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF
+ fi
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ newsos6)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ *nto* | *qnx*)
+ ;;
+
+ openbsd*)
+ if test -f /usr/libexec/ld.so; then
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+ else
+ case $host_os in
+ openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ ;;
+ *)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+ ;;
+ esac
+ fi
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ os2*)
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def'
+ _LT_TAGVAR(old_archive_from_new_cmds, $1)='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def'
+ ;;
+
+ osf3*)
+ if test "$GCC" = yes; then
+ _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ else
+ _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+ fi
+ _LT_TAGVAR(archive_cmds_need_lc, $1)='no'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ ;;
+
+ osf4* | osf5*) # as osf3* with the addition of -msym flag
+ if test "$GCC" = yes; then
+ _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ else
+ _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~
+ $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp'
+
+ # Both c and cxx compiler support -rpath directly
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
+ fi
+ _LT_TAGVAR(archive_cmds_need_lc, $1)='no'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ ;;
+
+ solaris*)
+ _LT_TAGVAR(no_undefined_flag, $1)=' -z defs'
+ if test "$GCC" = yes; then
+ wlarc='${wl}'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+ else
+ case `$CC -V 2>&1` in
+ *"Compilers 5.0"*)
+ wlarc=''
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp'
+ ;;
+ *)
+ wlarc='${wl}'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+ ;;
+ esac
+ fi
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ case $host_os in
+ solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
+ *)
+ # The compiler driver will combine and reorder linker options,
+ # but understands `-z linker_flag'. GCC discards it without `$wl',
+ # but is careful enough not to reorder.
+ # Supported since Solaris 2.6 (maybe 2.5.1?)
+ if test "$GCC" = yes; then
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
+ else
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract'
+ fi
+ ;;
+ esac
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ ;;
+
+ sunos4*)
+ if test "x$host_vendor" = xsequent; then
+ # Use $CC to link under sequent, because it throws in some extra .o
+ # files that make .init and .fini sections work.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'
+ fi
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ sysv4)
+ case $host_vendor in
+ sni)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_direct, $1)=yes # is this really true???
+ ;;
+ siemens)
+ ## LD is ld it makes a PLAMLIB
+ ## CC just makes a GrossModule.
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs'
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ ;;
+ motorola)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie
+ ;;
+ esac
+ runpath_var='LD_RUN_PATH'
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ sysv4.3*)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ runpath_var=LD_RUN_PATH
+ hardcode_runpath_var=yes
+ _LT_TAGVAR(ld_shlibs, $1)=yes
+ fi
+ ;;
+
+ sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*)
+ _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ runpath_var='LD_RUN_PATH'
+
+ if test "$GCC" = yes; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ fi
+ ;;
+
+ sysv5* | sco3.2v5* | sco5v6*)
+ # Note: We can NOT use -z defs as we might desire, because we do not
+ # link with -lc, and that would cause any symbols used from libc to
+ # always be unresolved, which means just about no library would
+ # ever link correctly. If we're not using GNU ld we use -z text
+ # though, which does catch some bad symbols but isn't as heavy-handed
+ # as -z defs.
+ _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
+ _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs'
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport'
+ runpath_var='LD_RUN_PATH'
+
+ if test "$GCC" = yes; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ fi
+ ;;
+
+ uts4*)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ *)
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+
+ if test x$host_vendor = xsni; then
+ case $host in
+ sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Blargedynsym'
+ ;;
+ esac
+ fi
+ fi
+])
+AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)])
+test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no
+
+_LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld
+
+_LT_DECL([], [libext], [0], [Old archive suffix (normally "a")])dnl
+_LT_DECL([], [shrext_cmds], [1], [Shared library suffix (normally ".so")])dnl
+_LT_DECL([], [extract_expsyms_cmds], [2],
+ [The commands to extract the exported symbol list from a shared archive])
+
+#
+# Do we need to explicitly link libc?
+#
+case "x$_LT_TAGVAR(archive_cmds_need_lc, $1)" in
+x|xyes)
+ # Assume -lc should be added
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=yes
+
+ if test "$enable_shared" = yes && test "$GCC" = yes; then
+ case $_LT_TAGVAR(archive_cmds, $1) in
+ *'~'*)
+ # FIXME: we may have to deal with multi-command sequences.
+ ;;
+ '$CC '*)
+ # Test whether the compiler implicitly links with -lc since on some
+ # systems, -lgcc has to come before -lc. If gcc already passes -lc
+ # to ld, don't add -lc before -lgcc.
+ AC_CACHE_CHECK([whether -lc should be explicitly linked in],
+ [lt_cv_]_LT_TAGVAR(archive_cmds_need_lc, $1),
+ [$RM conftest*
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+ if AC_TRY_EVAL(ac_compile) 2>conftest.err; then
+ soname=conftest
+ lib=conftest
+ libobjs=conftest.$ac_objext
+ deplibs=
+ wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1)
+ pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1)
+ compiler_flags=-v
+ linker_flags=-v
+ verstring=
+ output_objdir=.
+ libname=conftest
+ lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1)
+ _LT_TAGVAR(allow_undefined_flag, $1)=
+ if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1)
+ then
+ lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ else
+ lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=yes
+ fi
+ _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag
+ else
+ cat conftest.err 1>&5
+ fi
+ $RM conftest*
+ ])
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=$lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)
+ ;;
+ esac
+ fi
+ ;;
+esac
+
+_LT_TAGDECL([build_libtool_need_lc], [archive_cmds_need_lc], [0],
+ [Whether or not to add -lc for building shared libraries])
+_LT_TAGDECL([allow_libtool_libs_with_static_runtimes],
+ [enable_shared_with_static_runtimes], [0],
+ [Whether or not to disallow shared libs when runtime libs are static])
+_LT_TAGDECL([], [export_dynamic_flag_spec], [1],
+ [Compiler flag to allow reflexive dlopens])
+_LT_TAGDECL([], [whole_archive_flag_spec], [1],
+ [Compiler flag to generate shared objects directly from archives])
+_LT_TAGDECL([], [compiler_needs_object], [1],
+ [Whether the compiler copes with passing no objects directly])
+_LT_TAGDECL([], [old_archive_from_new_cmds], [2],
+ [Create an old-style archive from a shared archive])
+_LT_TAGDECL([], [old_archive_from_expsyms_cmds], [2],
+ [Create a temporary old-style archive to link instead of a shared archive])
+_LT_TAGDECL([], [archive_cmds], [2], [Commands used to build a shared archive])
+_LT_TAGDECL([], [archive_expsym_cmds], [2])
+_LT_TAGDECL([], [module_cmds], [2],
+ [Commands used to build a loadable module if different from building
+ a shared archive.])
+_LT_TAGDECL([], [module_expsym_cmds], [2])
+_LT_TAGDECL([], [with_gnu_ld], [1],
+ [Whether we are building with GNU ld or not])
+_LT_TAGDECL([], [allow_undefined_flag], [1],
+ [Flag that allows shared libraries with undefined symbols to be built])
+_LT_TAGDECL([], [no_undefined_flag], [1],
+ [Flag that enforces no undefined symbols])
+_LT_TAGDECL([], [hardcode_libdir_flag_spec], [1],
+ [Flag to hardcode $libdir into a binary during linking.
+ This must work even if $libdir does not exist])
+_LT_TAGDECL([], [hardcode_libdir_separator], [1],
+ [Whether we need a single "-rpath" flag with a separated argument])
+_LT_TAGDECL([], [hardcode_direct], [0],
+ [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes
+ DIR into the resulting binary])
+_LT_TAGDECL([], [hardcode_direct_absolute], [0],
+ [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes
+ DIR into the resulting binary and the resulting library dependency is
+ "absolute", i.e impossible to change by setting ${shlibpath_var} if the
+ library is relocated])
+_LT_TAGDECL([], [hardcode_minus_L], [0],
+ [Set to "yes" if using the -LDIR flag during linking hardcodes DIR
+ into the resulting binary])
+_LT_TAGDECL([], [hardcode_shlibpath_var], [0],
+ [Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR
+ into the resulting binary])
+_LT_TAGDECL([], [hardcode_automatic], [0],
+ [Set to "yes" if building a shared library automatically hardcodes DIR
+ into the library and all subsequent libraries and executables linked
+ against it])
+_LT_TAGDECL([], [inherit_rpath], [0],
+ [Set to yes if linker adds runtime paths of dependent libraries
+ to runtime path list])
+_LT_TAGDECL([], [link_all_deplibs], [0],
+ [Whether libtool must link a program against all its dependency libraries])
+_LT_TAGDECL([], [always_export_symbols], [0],
+ [Set to "yes" if exported symbols are required])
+_LT_TAGDECL([], [export_symbols_cmds], [2],
+ [The commands to list exported symbols])
+_LT_TAGDECL([], [exclude_expsyms], [1],
+ [Symbols that should not be listed in the preloaded symbols])
+_LT_TAGDECL([], [include_expsyms], [1],
+ [Symbols that must always be exported])
+_LT_TAGDECL([], [prelink_cmds], [2],
+ [Commands necessary for linking programs (against libraries) with templates])
+_LT_TAGDECL([], [postlink_cmds], [2],
+ [Commands necessary for finishing linking programs])
+_LT_TAGDECL([], [file_list_spec], [1],
+ [Specify filename containing input files])
+dnl FIXME: Not yet implemented
+dnl _LT_TAGDECL([], [thread_safe_flag_spec], [1],
+dnl [Compiler flag to generate thread safe objects])
+])# _LT_LINKER_SHLIBS
+
+
+# _LT_LANG_C_CONFIG([TAG])
+# ------------------------
+# Ensure that the configuration variables for a C compiler are suitably
+# defined. These variables are subsequently used by _LT_CONFIG to write
+# the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_C_CONFIG],
+[m4_require([_LT_DECL_EGREP])dnl
+lt_save_CC="$CC"
+AC_LANG_PUSH(C)
+
+# Source file extension for C test sources.
+ac_ext=c
+
+# Object file extension for compiled C test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="int some_variable = 0;"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='int main(){return(0);}'
+
+_LT_TAG_COMPILER
+# Save the default compiler, since it gets overwritten when the other
+# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP.
+compiler_DEFAULT=$CC
+
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
+
+## CAVEAT EMPTOR:
+## There is no encapsulation within the following macros, do not change
+## the running order or otherwise move them around unless you know exactly
+## what you are doing...
+if test -n "$compiler"; then
+ _LT_COMPILER_NO_RTTI($1)
+ _LT_COMPILER_PIC($1)
+ _LT_COMPILER_C_O($1)
+ _LT_COMPILER_FILE_LOCKS($1)
+ _LT_LINKER_SHLIBS($1)
+ _LT_SYS_DYNAMIC_LINKER($1)
+ _LT_LINKER_HARDCODE_LIBPATH($1)
+ LT_SYS_DLOPEN_SELF
+ _LT_CMD_STRIPLIB
+
+ # Report which library types will actually be built
+ AC_MSG_CHECKING([if libtool supports shared libraries])
+ AC_MSG_RESULT([$can_build_shared])
+
+ AC_MSG_CHECKING([whether to build shared libraries])
+ test "$can_build_shared" = "no" && enable_shared=no
+
+ # On AIX, shared libraries and static libraries use the same namespace, and
+ # are all built from PIC.
+ case $host_os in
+ aix3*)
+ test "$enable_shared" = yes && enable_static=no
+ if test -n "$RANLIB"; then
+ archive_cmds="$archive_cmds~\$RANLIB \$lib"
+ postinstall_cmds='$RANLIB $lib'
+ fi
+ ;;
+
+ aix[[4-9]]*)
+ if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+ test "$enable_shared" = yes && enable_static=no
+ fi
+ ;;
+ esac
+ AC_MSG_RESULT([$enable_shared])
+
+ AC_MSG_CHECKING([whether to build static libraries])
+ # Make sure either enable_shared or enable_static is yes.
+ test "$enable_shared" = yes || enable_static=yes
+ AC_MSG_RESULT([$enable_static])
+
+ _LT_CONFIG($1)
+fi
+AC_LANG_POP
+CC="$lt_save_CC"
+])# _LT_LANG_C_CONFIG
+
+
+# _LT_LANG_CXX_CONFIG([TAG])
+# --------------------------
+# Ensure that the configuration variables for a C++ compiler are suitably
+# defined. These variables are subsequently used by _LT_CONFIG to write
+# the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_CXX_CONFIG],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_PATH_MANIFEST_TOOL])dnl
+if test -n "$CXX" && ( test "X$CXX" != "Xno" &&
+ ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) ||
+ (test "X$CXX" != "Xg++"))) ; then
+ AC_PROG_CXXCPP
+else
+ _lt_caught_CXX_error=yes
+fi
+
+AC_LANG_PUSH(C++)
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+_LT_TAGVAR(allow_undefined_flag, $1)=
+_LT_TAGVAR(always_export_symbols, $1)=no
+_LT_TAGVAR(archive_expsym_cmds, $1)=
+_LT_TAGVAR(compiler_needs_object, $1)=no
+_LT_TAGVAR(export_dynamic_flag_spec, $1)=
+_LT_TAGVAR(hardcode_direct, $1)=no
+_LT_TAGVAR(hardcode_direct_absolute, $1)=no
+_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+_LT_TAGVAR(hardcode_libdir_separator, $1)=
+_LT_TAGVAR(hardcode_minus_L, $1)=no
+_LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
+_LT_TAGVAR(hardcode_automatic, $1)=no
+_LT_TAGVAR(inherit_rpath, $1)=no
+_LT_TAGVAR(module_cmds, $1)=
+_LT_TAGVAR(module_expsym_cmds, $1)=
+_LT_TAGVAR(link_all_deplibs, $1)=unknown
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(reload_flag, $1)=$reload_flag
+_LT_TAGVAR(reload_cmds, $1)=$reload_cmds
+_LT_TAGVAR(no_undefined_flag, $1)=
+_LT_TAGVAR(whole_archive_flag_spec, $1)=
+_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+
+# Source file extension for C++ test sources.
+ac_ext=cpp
+
+# Object file extension for compiled C++ test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# No sense in running all these tests if we already determined that
+# the CXX compiler isn't working. Some variables (like enable_shared)
+# are currently assumed to apply to all compilers on this platform,
+# and will be corrupted by setting them based on a non-working compiler.
+if test "$_lt_caught_CXX_error" != yes; then
+ # Code to be used in simple compile tests
+ lt_simple_compile_test_code="int some_variable = 0;"
+
+ # Code to be used in simple link tests
+ lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }'
+
+ # ltmain only uses $CC for tagged configurations so make sure $CC is set.
+ _LT_TAG_COMPILER
+
+ # save warnings/boilerplate of simple test code
+ _LT_COMPILER_BOILERPLATE
+ _LT_LINKER_BOILERPLATE
+
+ # Allow CC to be a program name with arguments.
+ lt_save_CC=$CC
+ lt_save_CFLAGS=$CFLAGS
+ lt_save_LD=$LD
+ lt_save_GCC=$GCC
+ GCC=$GXX
+ lt_save_with_gnu_ld=$with_gnu_ld
+ lt_save_path_LD=$lt_cv_path_LD
+ if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then
+ lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx
+ else
+ $as_unset lt_cv_prog_gnu_ld
+ fi
+ if test -n "${lt_cv_path_LDCXX+set}"; then
+ lt_cv_path_LD=$lt_cv_path_LDCXX
+ else
+ $as_unset lt_cv_path_LD
+ fi
+ test -z "${LDCXX+set}" || LD=$LDCXX
+ CC=${CXX-"c++"}
+ CFLAGS=$CXXFLAGS
+ compiler=$CC
+ _LT_TAGVAR(compiler, $1)=$CC
+ _LT_CC_BASENAME([$compiler])
+
+ if test -n "$compiler"; then
+ # We don't want -fno-exception when compiling C++ code, so set the
+ # no_builtin_flag separately
+ if test "$GXX" = yes; then
+ _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin'
+ else
+ _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=
+ fi
+
+ if test "$GXX" = yes; then
+ # Set up default GNU C++ configuration
+
+ LT_PATH_LD
+
+ # Check if GNU C++ uses GNU ld as the underlying linker, since the
+ # archiving commands below assume that GNU ld is being used.
+ if test "$with_gnu_ld" = yes; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+
+ # If archive_cmds runs LD, not CC, wlarc should be empty
+ # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to
+ # investigate it a little bit more. (MM)
+ wlarc='${wl}'
+
+ # ancient GNU ld didn't support --whole-archive et. al.
+ if eval "`$CC -print-prog-name=ld` --help 2>&1" |
+ $GREP 'no-whole-archive' > /dev/null; then
+ _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+ else
+ _LT_TAGVAR(whole_archive_flag_spec, $1)=
+ fi
+ else
+ with_gnu_ld=no
+ wlarc=
+
+ # A generic and very simple default shared library creation
+ # command for GNU C++ for the case where it uses the native
+ # linker, instead of GNU ld. If possible, this setting should
+ # overridden to take advantage of the native linker features on
+ # the platform it is being used on.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
+ fi
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+
+ else
+ GXX=no
+ with_gnu_ld=no
+ wlarc=
+ fi
+
+ # PORTME: fill in a description of your system's C++ link characteristics
+ AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries])
+ _LT_TAGVAR(ld_shlibs, $1)=yes
+ case $host_os in
+ aix3*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ aix[[4-9]]*)
+ if test "$host_cpu" = ia64; then
+ # On IA64, the linker does run time linking by default, so we don't
+ # have to do anything special.
+ aix_use_runtimelinking=no
+ exp_sym_flag='-Bexport'
+ no_entry_flag=""
+ else
+ aix_use_runtimelinking=no
+
+ # Test if we are trying to use run time linking or normal
+ # AIX style linking. If -brtl is somewhere in LDFLAGS, we
+ # need to do runtime linking.
+ case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*)
+ for ld_flag in $LDFLAGS; do
+ case $ld_flag in
+ *-brtl*)
+ aix_use_runtimelinking=yes
+ break
+ ;;
+ esac
+ done
+ ;;
+ esac
+
+ exp_sym_flag='-bexport'
+ no_entry_flag='-bnoentry'
+ fi
+
+ # When large executables or shared objects are built, AIX ld can
+ # have problems creating the table of contents. If linking a library
+ # or program results in "error TOC overflow" add -mminimal-toc to
+ # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not
+ # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+ _LT_TAGVAR(archive_cmds, $1)=''
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ _LT_TAGVAR(file_list_spec, $1)='${wl}-f,'
+
+ if test "$GXX" = yes; then
+ case $host_os in aix4.[[012]]|aix4.[[012]].*)
+ # We only want to do this on AIX 4.2 and lower, the check
+ # below for broken collect2 doesn't work under 4.3+
+ collect2name=`${CC} -print-prog-name=collect2`
+ if test -f "$collect2name" &&
+ strings "$collect2name" | $GREP resolve_lib_name >/dev/null
+ then
+ # We have reworked collect2
+ :
+ else
+ # We have old collect2
+ _LT_TAGVAR(hardcode_direct, $1)=unsupported
+ # It fails to find uninstalled libraries when the uninstalled
+ # path is not listed in the libpath. Setting hardcode_minus_L
+ # to unsupported forces relinking
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=
+ fi
+ esac
+ shared_flag='-shared'
+ if test "$aix_use_runtimelinking" = yes; then
+ shared_flag="$shared_flag "'${wl}-G'
+ fi
+ else
+ # not using gcc
+ if test "$host_cpu" = ia64; then
+ # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+ # chokes on -Wl,-G. The following line is correct:
+ shared_flag='-G'
+ else
+ if test "$aix_use_runtimelinking" = yes; then
+ shared_flag='${wl}-G'
+ else
+ shared_flag='${wl}-bM:SRE'
+ fi
+ fi
+ fi
+
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall'
+ # It seems that -bexpall does not export symbols beginning with
+ # underscore (_), so it is better to generate a list of symbols to
+ # export.
+ _LT_TAGVAR(always_export_symbols, $1)=yes
+ if test "$aix_use_runtimelinking" = yes; then
+ # Warning - without using the other runtime loading flags (-brtl),
+ # -berok will link without error, but may produce a broken library.
+ _LT_TAGVAR(allow_undefined_flag, $1)='-berok'
+ # Determine the default libpath from the value encoded in an empty
+ # executable.
+ _LT_SYS_MODULE_PATH_AIX([$1])
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
+
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+ else
+ if test "$host_cpu" = ia64; then
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib'
+ _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs"
+ _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
+ else
+ # Determine the default libpath from the value encoded in an
+ # empty executable.
+ _LT_SYS_MODULE_PATH_AIX([$1])
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
+ # Warning - without using the other run time loading flags,
+ # -berok will link without error, but may produce a broken library.
+ _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok'
+ _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok'
+ if test "$with_gnu_ld" = yes; then
+ # We only use this code for GNU lds that support --whole-archive.
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
+ else
+ # Exported symbols can be pulled into shared objects from archives
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience'
+ fi
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=yes
+ # This is similar to how AIX traditionally builds its shared
+ # libraries.
+ _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+ fi
+ fi
+ ;;
+
+ beos*)
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+ # support --undefined. This deserves some investigation. FIXME
+ _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ chorus*)
+ case $cc_basename in
+ *)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+ ;;
+
+ cygwin* | mingw* | pw32* | cegcc*)
+ case $GXX,$cc_basename in
+ ,cl* | no,cl*)
+ # Native MSVC
+ # hardcode_libdir_flag_spec is actually meaningless, as there is
+ # no search path for DLLs.
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ _LT_TAGVAR(always_export_symbols, $1)=yes
+ _LT_TAGVAR(file_list_spec, $1)='@'
+ # Tell ltmain to make .lib files, not .a files.
+ libext=lib
+ # Tell ltmain to make .dll files, not .so files.
+ shrext_cmds=".dll"
+ # FIXME: Setting linknames here is a bad hack.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames='
+ _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+ $SED -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp;
+ else
+ $SED -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp;
+ fi~
+ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
+ linknames='
+ # The linker will not automatically build a static lib if we build a DLL.
+ # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true'
+ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+ # Don't use ranlib
+ _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib'
+ _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~
+ lt_tool_outputfile="@TOOL_OUTPUT@"~
+ case $lt_outputfile in
+ *.exe|*.EXE) ;;
+ *)
+ lt_outputfile="$lt_outputfile.exe"
+ lt_tool_outputfile="$lt_tool_outputfile.exe"
+ ;;
+ esac~
+ func_to_tool_file "$lt_outputfile"~
+ if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then
+ $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
+ $RM "$lt_outputfile.manifest";
+ fi'
+ ;;
+ *)
+ # g++
+ # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless,
+ # as there is no search path for DLLs.
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols'
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ _LT_TAGVAR(always_export_symbols, $1)=no
+ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+
+ if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ # If the export-symbols file already is a .def file (1st line
+ # is EXPORTS), use it as is; otherwise, prepend...
+ _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+ cp $export_symbols $output_objdir/$soname.def;
+ else
+ echo EXPORTS > $output_objdir/$soname.def;
+ cat $export_symbols >> $output_objdir/$soname.def;
+ fi~
+ $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+ esac
+ ;;
+ darwin* | rhapsody*)
+ _LT_DARWIN_LINKER_FEATURES($1)
+ ;;
+
+ dgux*)
+ case $cc_basename in
+ ec++*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ ghcx*)
+ # Green Hills C++ Compiler
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ *)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+ ;;
+
+ freebsd2.*)
+ # C++ shared libraries reported to be fairly broken before
+ # switch to ELF
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+
+ freebsd-elf*)
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ ;;
+
+ freebsd* | dragonfly*)
+ # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF
+ # conventions
+ _LT_TAGVAR(ld_shlibs, $1)=yes
+ ;;
+
+ gnu*)
+ ;;
+
+ haiku*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ ;;
+
+ hpux9*)
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH,
+ # but as the default
+ # location of the library.
+
+ case $cc_basename in
+ CC*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ aCC*)
+ _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ #
+ # There doesn't appear to be a way to prevent this compiler from
+ # explicitly linking system object files so we need to strip them
+ # from the output so that they don't get included in the library
+ # dependencies.
+ output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+ ;;
+ *)
+ if test "$GXX" = yes; then
+ _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+ else
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+ esac
+ ;;
+
+ hpux10*|hpux11*)
+ if test $with_gnu_ld = no; then
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+ case $host_cpu in
+ hppa*64*|ia64*)
+ ;;
+ *)
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+ ;;
+ esac
+ fi
+ case $host_cpu in
+ hppa*64*|ia64*)
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+ *)
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH,
+ # but as the default
+ # location of the library.
+ ;;
+ esac
+
+ case $cc_basename in
+ CC*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ aCC*)
+ case $host_cpu in
+ hppa*64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ ia64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ *)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ esac
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ #
+ # There doesn't appear to be a way to prevent this compiler from
+ # explicitly linking system object files so we need to strip them
+ # from the output so that they don't get included in the library
+ # dependencies.
+ output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+ ;;
+ *)
+ if test "$GXX" = yes; then
+ if test $with_gnu_ld = no; then
+ case $host_cpu in
+ hppa*64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ ia64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ *)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ esac
+ fi
+ else
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+ esac
+ ;;
+
+ interix[[3-9]]*)
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+ # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+ # Instead, shared libraries are loaded at an image base (0x10000000 by
+ # default) and relocated if they conflict, which is a slow very memory
+ # consuming and fragmenting process. To avoid this, we pick a random,
+ # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+ # time. Moving up from 0x10000000 also allows more sbrk(2) space.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ ;;
+ irix5* | irix6*)
+ case $cc_basename in
+ CC*)
+ # SGI C++
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+
+ # Archives containing C++ object files must be created using
+ # "CC -ar", where "CC" is the IRIX C++ compiler. This is
+ # necessary to make sure instantiated templates are included
+ # in the archive.
+ _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs'
+ ;;
+ *)
+ if test "$GXX" = yes; then
+ if test "$with_gnu_ld" = no; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` -o $lib'
+ fi
+ fi
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ ;;
+ esac
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ _LT_TAGVAR(inherit_rpath, $1)=yes
+ ;;
+
+ linux* | k*bsd*-gnu | kopensolaris*-gnu)
+ case $cc_basename in
+ KCC*)
+ # Kuck and Associates, Inc. (KAI) C++ Compiler
+
+ # KCC will only create a shared library if the output file
+ # ends with ".so" (or ".sl" for HP-UX), so rename the library
+ # to its proper name (with version) after linking.
+ _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib'
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ #
+ # There doesn't appear to be a way to prevent this compiler from
+ # explicitly linking system object files so we need to strip them
+ # from the output so that they don't get included in the library
+ # dependencies.
+ output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+
+ # Archives containing C++ object files must be created using
+ # "CC -Bstatic", where "CC" is the KAI C++ compiler.
+ _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs'
+ ;;
+ icpc* | ecpc* )
+ # Intel C++
+ with_gnu_ld=yes
+ # version 8.0 and above of icpc choke on multiply defined symbols
+ # if we add $predep_objects and $postdep_objects, however 7.1 and
+ # earlier do not add the objects themselves.
+ case `$CC -V 2>&1` in
+ *"Version 7."*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ ;;
+ *) # Version 8.0 or newer
+ tmp_idyn=
+ case $host_cpu in
+ ia64*) tmp_idyn=' -i_dynamic';;
+ esac
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ ;;
+ esac
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
+ ;;
+ pgCC* | pgcpp*)
+ # Portland Group C++ compiler
+ case `$CC -V` in
+ *pgCC\ [[1-5]].* | *pgcpp\ [[1-5]].*)
+ _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~
+ rm -rf $tpldir~
+ $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~
+ compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"'
+ _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~
+ rm -rf $tpldir~
+ $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~
+ $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~
+ $RANLIB $oldlib'
+ _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~
+ rm -rf $tpldir~
+ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
+ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~
+ rm -rf $tpldir~
+ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
+ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib'
+ ;;
+ *) # Version 6 and above use weak symbols
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib'
+ ;;
+ esac
+
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+ ;;
+ cxx*)
+ # Compaq C++
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols'
+
+ runpath_var=LD_RUN_PATH
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ #
+ # There doesn't appear to be a way to prevent this compiler from
+ # explicitly linking system object files so we need to strip them
+ # from the output so that they don't get included in the library
+ # dependencies.
+ output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed'
+ ;;
+ xl* | mpixl* | bgxl*)
+ # IBM XL 8.0 on PPC, with GNU ld
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ if test "x$supports_anon_versioning" = xyes; then
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
+ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+ echo "local: *; };" >> $output_objdir/$libname.ver~
+ $CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
+ fi
+ ;;
+ *)
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ C*)
+ # Sun C++ 5.9
+ _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+ _LT_TAGVAR(compiler_needs_object, $1)=yes
+
+ # Not sure whether something based on
+ # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1
+ # would be better.
+ output_verbose_link_cmd='func_echo_all'
+
+ # Archives containing C++ object files must be created using
+ # "CC -xar", where "CC" is the Sun C++ compiler. This is
+ # necessary to make sure instantiated templates are included
+ # in the archive.
+ _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs'
+ ;;
+ esac
+ ;;
+ esac
+ ;;
+
+ lynxos*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+
+ m88k*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+
+ mvs*)
+ case $cc_basename in
+ cxx*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ *)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+ ;;
+
+ netbsd*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags'
+ wlarc=
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ fi
+ # Workaround some broken pre-1.5 toolchains
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"'
+ ;;
+
+ *nto* | *qnx*)
+ _LT_TAGVAR(ld_shlibs, $1)=yes
+ ;;
+
+ openbsd2*)
+ # C++ shared libraries are fairly broken
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+
+ openbsd*)
+ if test -f /usr/libexec/ld.so; then
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+ if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+ _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+ fi
+ output_verbose_link_cmd=func_echo_all
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ osf3* | osf4* | osf5*)
+ case $cc_basename in
+ KCC*)
+ # Kuck and Associates, Inc. (KAI) C++ Compiler
+
+ # KCC will only create a shared library if the output file
+ # ends with ".so" (or ".sl" for HP-UX), so rename the library
+ # to its proper name (with version) after linking.
+ _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+ # Archives containing C++ object files must be created using
+ # the KAI C++ compiler.
+ case $host in
+ osf3*) _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;;
+ *) _LT_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;;
+ esac
+ ;;
+ RCC*)
+ # Rational C++ 2.4.1
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ cxx*)
+ case $host in
+ osf3*)
+ _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && func_echo_all "${wl}-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ ;;
+ *)
+ _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~
+ echo "-hidden">> $lib.exp~
+ $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~
+ $RM $lib.exp'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
+ ;;
+ esac
+
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ #
+ # There doesn't appear to be a way to prevent this compiler from
+ # explicitly linking system object files so we need to strip them
+ # from the output so that they don't get included in the library
+ # dependencies.
+ output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+ ;;
+ *)
+ if test "$GXX" = yes && test "$with_gnu_ld" = no; then
+ _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+ case $host in
+ osf3*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ ;;
+ *)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ ;;
+ esac
+
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+
+ else
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+ esac
+ ;;
+
+ psos*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+
+ sunos4*)
+ case $cc_basename in
+ CC*)
+ # Sun C++ 4.x
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ lcc*)
+ # Lucid
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ *)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+ ;;
+
+ solaris*)
+ case $cc_basename in
+ CC* | sunCC*)
+ # Sun C++ 4.2, 5.x and Centerline C++
+ _LT_TAGVAR(archive_cmds_need_lc,$1)=yes
+ _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ case $host_os in
+ solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
+ *)
+ # The compiler driver will combine and reorder linker options,
+ # but understands `-z linker_flag'.
+ # Supported since Solaris 2.6 (maybe 2.5.1?)
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract'
+ ;;
+ esac
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+
+ output_verbose_link_cmd='func_echo_all'
+
+ # Archives containing C++ object files must be created using
+ # "CC -xar", where "CC" is the Sun C++ compiler. This is
+ # necessary to make sure instantiated templates are included
+ # in the archive.
+ _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs'
+ ;;
+ gcx*)
+ # Green Hills C++ Compiler
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+
+ # The C++ compiler must be used to create the archive.
+ _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs'
+ ;;
+ *)
+ # GNU C++ compiler with Solaris linker
+ if test "$GXX" = yes && test "$with_gnu_ld" = no; then
+ _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-z ${wl}defs'
+ if $CC --version | $GREP -v '^2\.7' > /dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -shared $pic_flag -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+ else
+ # g++ 2.7 appears to require `-G' NOT `-shared' on this
+ # platform.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+ fi
+
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $wl$libdir'
+ case $host_os in
+ solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
+ *)
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
+ ;;
+ esac
+ fi
+ ;;
+ esac
+ ;;
+
+ sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*)
+ _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ runpath_var='LD_RUN_PATH'
+
+ case $cc_basename in
+ CC*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ *)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ esac
+ ;;
+
+ sysv5* | sco3.2v5* | sco5v6*)
+ # Note: We can NOT use -z defs as we might desire, because we do not
+ # link with -lc, and that would cause any symbols used from libc to
+ # always be unresolved, which means just about no library would
+ # ever link correctly. If we're not using GNU ld we use -z text
+ # though, which does catch some bad symbols but isn't as heavy-handed
+ # as -z defs.
+ _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
+ _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs'
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport'
+ runpath_var='LD_RUN_PATH'
+
+ case $cc_basename in
+ CC*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(old_archive_cmds, $1)='$CC -Tprelink_objects $oldobjs~
+ '"$_LT_TAGVAR(old_archive_cmds, $1)"
+ _LT_TAGVAR(reload_cmds, $1)='$CC -Tprelink_objects $reload_objs~
+ '"$_LT_TAGVAR(reload_cmds, $1)"
+ ;;
+ *)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ esac
+ ;;
+
+ tandem*)
+ case $cc_basename in
+ NCC*)
+ # NonStop-UX NCC 3.20
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ *)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+ ;;
+
+ vxworks*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+
+ *)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+
+ AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)])
+ test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no
+
+ _LT_TAGVAR(GCC, $1)="$GXX"
+ _LT_TAGVAR(LD, $1)="$LD"
+
+ ## CAVEAT EMPTOR:
+ ## There is no encapsulation within the following macros, do not change
+ ## the running order or otherwise move them around unless you know exactly
+ ## what you are doing...
+ _LT_SYS_HIDDEN_LIBDEPS($1)
+ _LT_COMPILER_PIC($1)
+ _LT_COMPILER_C_O($1)
+ _LT_COMPILER_FILE_LOCKS($1)
+ _LT_LINKER_SHLIBS($1)
+ _LT_SYS_DYNAMIC_LINKER($1)
+ _LT_LINKER_HARDCODE_LIBPATH($1)
+
+ _LT_CONFIG($1)
+ fi # test -n "$compiler"
+
+ CC=$lt_save_CC
+ CFLAGS=$lt_save_CFLAGS
+ LDCXX=$LD
+ LD=$lt_save_LD
+ GCC=$lt_save_GCC
+ with_gnu_ld=$lt_save_with_gnu_ld
+ lt_cv_path_LDCXX=$lt_cv_path_LD
+ lt_cv_path_LD=$lt_save_path_LD
+ lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld
+ lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld
+fi # test "$_lt_caught_CXX_error" != yes
+
+AC_LANG_POP
+])# _LT_LANG_CXX_CONFIG
+
+
+# _LT_FUNC_STRIPNAME_CNF
+# ----------------------
+# func_stripname_cnf prefix suffix name
+# strip PREFIX and SUFFIX off of NAME.
+# PREFIX and SUFFIX must not contain globbing or regex special
+# characters, hashes, percent signs, but SUFFIX may contain a leading
+# dot (in which case that matches only a dot).
+#
+# This function is identical to the (non-XSI) version of func_stripname,
+# except this one can be used by m4 code that may be executed by configure,
+# rather than the libtool script.
+m4_defun([_LT_FUNC_STRIPNAME_CNF],[dnl
+AC_REQUIRE([_LT_DECL_SED])
+AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])
+func_stripname_cnf ()
+{
+ case ${2} in
+ .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;;
+ *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;;
+ esac
+} # func_stripname_cnf
+])# _LT_FUNC_STRIPNAME_CNF
+
+# _LT_SYS_HIDDEN_LIBDEPS([TAGNAME])
+# ---------------------------------
+# Figure out "hidden" library dependencies from verbose
+# compiler output when linking a shared library.
+# Parse the compiler output and extract the necessary
+# objects, libraries and library flags.
+m4_defun([_LT_SYS_HIDDEN_LIBDEPS],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+AC_REQUIRE([_LT_FUNC_STRIPNAME_CNF])dnl
+# Dependencies to place before and after the object being linked:
+_LT_TAGVAR(predep_objects, $1)=
+_LT_TAGVAR(postdep_objects, $1)=
+_LT_TAGVAR(predeps, $1)=
+_LT_TAGVAR(postdeps, $1)=
+_LT_TAGVAR(compiler_lib_search_path, $1)=
+
+dnl we can't use the lt_simple_compile_test_code here,
+dnl because it contains code intended for an executable,
+dnl not a library. It's possible we should let each
+dnl tag define a new lt_????_link_test_code variable,
+dnl but it's only used here...
+m4_if([$1], [], [cat > conftest.$ac_ext <<_LT_EOF
+int a;
+void foo (void) { a = 0; }
+_LT_EOF
+], [$1], [CXX], [cat > conftest.$ac_ext <<_LT_EOF
+class Foo
+{
+public:
+ Foo (void) { a = 0; }
+private:
+ int a;
+};
+_LT_EOF
+], [$1], [F77], [cat > conftest.$ac_ext <<_LT_EOF
+ subroutine foo
+ implicit none
+ integer*4 a
+ a=0
+ return
+ end
+_LT_EOF
+], [$1], [FC], [cat > conftest.$ac_ext <<_LT_EOF
+ subroutine foo
+ implicit none
+ integer a
+ a=0
+ return
+ end
+_LT_EOF
+], [$1], [GCJ], [cat > conftest.$ac_ext <<_LT_EOF
+public class foo {
+ private int a;
+ public void bar (void) {
+ a = 0;
+ }
+};
+_LT_EOF
+], [$1], [GO], [cat > conftest.$ac_ext <<_LT_EOF
+package foo
+func foo() {
+}
+_LT_EOF
+])
+
+_lt_libdeps_save_CFLAGS=$CFLAGS
+case "$CC $CFLAGS " in #(
+*\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;;
+*\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;;
+*\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;;
+esac
+
+dnl Parse the compiler output and extract the necessary
+dnl objects, libraries and library flags.
+if AC_TRY_EVAL(ac_compile); then
+ # Parse the compiler output and extract the necessary
+ # objects, libraries and library flags.
+
+ # Sentinel used to keep track of whether or not we are before
+ # the conftest object file.
+ pre_test_object_deps_done=no
+
+ for p in `eval "$output_verbose_link_cmd"`; do
+ case ${prev}${p} in
+
+ -L* | -R* | -l*)
+ # Some compilers place space between "-{L,R}" and the path.
+ # Remove the space.
+ if test $p = "-L" ||
+ test $p = "-R"; then
+ prev=$p
+ continue
+ fi
+
+ # Expand the sysroot to ease extracting the directories later.
+ if test -z "$prev"; then
+ case $p in
+ -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;;
+ -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;;
+ -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;;
+ esac
+ fi
+ case $p in
+ =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;;
+ esac
+ if test "$pre_test_object_deps_done" = no; then
+ case ${prev} in
+ -L | -R)
+ # Internal compiler library paths should come after those
+ # provided the user. The postdeps already come after the
+ # user supplied libs so there is no need to process them.
+ if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then
+ _LT_TAGVAR(compiler_lib_search_path, $1)="${prev}${p}"
+ else
+ _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} ${prev}${p}"
+ fi
+ ;;
+ # The "-l" case would never come before the object being
+ # linked, so don't bother handling this case.
+ esac
+ else
+ if test -z "$_LT_TAGVAR(postdeps, $1)"; then
+ _LT_TAGVAR(postdeps, $1)="${prev}${p}"
+ else
+ _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} ${prev}${p}"
+ fi
+ fi
+ prev=
+ ;;
+
+ *.lto.$objext) ;; # Ignore GCC LTO objects
+ *.$objext)
+ # This assumes that the test object file only shows up
+ # once in the compiler output.
+ if test "$p" = "conftest.$objext"; then
+ pre_test_object_deps_done=yes
+ continue
+ fi
+
+ if test "$pre_test_object_deps_done" = no; then
+ if test -z "$_LT_TAGVAR(predep_objects, $1)"; then
+ _LT_TAGVAR(predep_objects, $1)="$p"
+ else
+ _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p"
+ fi
+ else
+ if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then
+ _LT_TAGVAR(postdep_objects, $1)="$p"
+ else
+ _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p"
+ fi
+ fi
+ ;;
+
+ *) ;; # Ignore the rest.
+
+ esac
+ done
+
+ # Clean up.
+ rm -f a.out a.exe
+else
+ echo "libtool.m4: error: problem compiling $1 test program"
+fi
+
+$RM -f confest.$objext
+CFLAGS=$_lt_libdeps_save_CFLAGS
+
+# PORTME: override above test on systems where it is broken
+m4_if([$1], [CXX],
+[case $host_os in
+interix[[3-9]]*)
+ # Interix 3.5 installs completely hosed .la files for C++, so rather than
+ # hack all around it, let's just trust "g++" to DTRT.
+ _LT_TAGVAR(predep_objects,$1)=
+ _LT_TAGVAR(postdep_objects,$1)=
+ _LT_TAGVAR(postdeps,$1)=
+ ;;
+
+linux*)
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ C*)
+ # Sun C++ 5.9
+
+ # The more standards-conforming stlport4 library is
+ # incompatible with the Cstd library. Avoid specifying
+ # it if it's in CXXFLAGS. Ignore libCrun as
+ # -library=stlport4 depends on it.
+ case " $CXX $CXXFLAGS " in
+ *" -library=stlport4 "*)
+ solaris_use_stlport4=yes
+ ;;
+ esac
+
+ if test "$solaris_use_stlport4" != yes; then
+ _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun'
+ fi
+ ;;
+ esac
+ ;;
+
+solaris*)
+ case $cc_basename in
+ CC* | sunCC*)
+ # The more standards-conforming stlport4 library is
+ # incompatible with the Cstd library. Avoid specifying
+ # it if it's in CXXFLAGS. Ignore libCrun as
+ # -library=stlport4 depends on it.
+ case " $CXX $CXXFLAGS " in
+ *" -library=stlport4 "*)
+ solaris_use_stlport4=yes
+ ;;
+ esac
+
+ # Adding this requires a known-good setup of shared libraries for
+ # Sun compiler versions before 5.6, else PIC objects from an old
+ # archive will be linked into the output, leading to subtle bugs.
+ if test "$solaris_use_stlport4" != yes; then
+ _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun'
+ fi
+ ;;
+ esac
+ ;;
+esac
+])
+
+case " $_LT_TAGVAR(postdeps, $1) " in
+*" -lc "*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;;
+esac
+ _LT_TAGVAR(compiler_lib_search_dirs, $1)=
+if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then
+ _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | ${SED} -e 's! -L! !g' -e 's!^ !!'`
+fi
+_LT_TAGDECL([], [compiler_lib_search_dirs], [1],
+ [The directories searched by this compiler when creating a shared library])
+_LT_TAGDECL([], [predep_objects], [1],
+ [Dependencies to place before and after the objects being linked to
+ create a shared library])
+_LT_TAGDECL([], [postdep_objects], [1])
+_LT_TAGDECL([], [predeps], [1])
+_LT_TAGDECL([], [postdeps], [1])
+_LT_TAGDECL([], [compiler_lib_search_path], [1],
+ [The library search path used internally by the compiler when linking
+ a shared library])
+])# _LT_SYS_HIDDEN_LIBDEPS
+
+
+# _LT_LANG_F77_CONFIG([TAG])
+# --------------------------
+# Ensure that the configuration variables for a Fortran 77 compiler are
+# suitably defined. These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_F77_CONFIG],
+[AC_LANG_PUSH(Fortran 77)
+if test -z "$F77" || test "X$F77" = "Xno"; then
+ _lt_disable_F77=yes
+fi
+
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+_LT_TAGVAR(allow_undefined_flag, $1)=
+_LT_TAGVAR(always_export_symbols, $1)=no
+_LT_TAGVAR(archive_expsym_cmds, $1)=
+_LT_TAGVAR(export_dynamic_flag_spec, $1)=
+_LT_TAGVAR(hardcode_direct, $1)=no
+_LT_TAGVAR(hardcode_direct_absolute, $1)=no
+_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+_LT_TAGVAR(hardcode_libdir_separator, $1)=
+_LT_TAGVAR(hardcode_minus_L, $1)=no
+_LT_TAGVAR(hardcode_automatic, $1)=no
+_LT_TAGVAR(inherit_rpath, $1)=no
+_LT_TAGVAR(module_cmds, $1)=
+_LT_TAGVAR(module_expsym_cmds, $1)=
+_LT_TAGVAR(link_all_deplibs, $1)=unknown
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(reload_flag, $1)=$reload_flag
+_LT_TAGVAR(reload_cmds, $1)=$reload_cmds
+_LT_TAGVAR(no_undefined_flag, $1)=
+_LT_TAGVAR(whole_archive_flag_spec, $1)=
+_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+
+# Source file extension for f77 test sources.
+ac_ext=f
+
+# Object file extension for compiled f77 test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# No sense in running all these tests if we already determined that
+# the F77 compiler isn't working. Some variables (like enable_shared)
+# are currently assumed to apply to all compilers on this platform,
+# and will be corrupted by setting them based on a non-working compiler.
+if test "$_lt_disable_F77" != yes; then
+ # Code to be used in simple compile tests
+ lt_simple_compile_test_code="\
+ subroutine t
+ return
+ end
+"
+
+ # Code to be used in simple link tests
+ lt_simple_link_test_code="\
+ program t
+ end
+"
+
+ # ltmain only uses $CC for tagged configurations so make sure $CC is set.
+ _LT_TAG_COMPILER
+
+ # save warnings/boilerplate of simple test code
+ _LT_COMPILER_BOILERPLATE
+ _LT_LINKER_BOILERPLATE
+
+ # Allow CC to be a program name with arguments.
+ lt_save_CC="$CC"
+ lt_save_GCC=$GCC
+ lt_save_CFLAGS=$CFLAGS
+ CC=${F77-"f77"}
+ CFLAGS=$FFLAGS
+ compiler=$CC
+ _LT_TAGVAR(compiler, $1)=$CC
+ _LT_CC_BASENAME([$compiler])
+ GCC=$G77
+ if test -n "$compiler"; then
+ AC_MSG_CHECKING([if libtool supports shared libraries])
+ AC_MSG_RESULT([$can_build_shared])
+
+ AC_MSG_CHECKING([whether to build shared libraries])
+ test "$can_build_shared" = "no" && enable_shared=no
+
+ # On AIX, shared libraries and static libraries use the same namespace, and
+ # are all built from PIC.
+ case $host_os in
+ aix3*)
+ test "$enable_shared" = yes && enable_static=no
+ if test -n "$RANLIB"; then
+ archive_cmds="$archive_cmds~\$RANLIB \$lib"
+ postinstall_cmds='$RANLIB $lib'
+ fi
+ ;;
+ aix[[4-9]]*)
+ if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+ test "$enable_shared" = yes && enable_static=no
+ fi
+ ;;
+ esac
+ AC_MSG_RESULT([$enable_shared])
+
+ AC_MSG_CHECKING([whether to build static libraries])
+ # Make sure either enable_shared or enable_static is yes.
+ test "$enable_shared" = yes || enable_static=yes
+ AC_MSG_RESULT([$enable_static])
+
+ _LT_TAGVAR(GCC, $1)="$G77"
+ _LT_TAGVAR(LD, $1)="$LD"
+
+ ## CAVEAT EMPTOR:
+ ## There is no encapsulation within the following macros, do not change
+ ## the running order or otherwise move them around unless you know exactly
+ ## what you are doing...
+ _LT_COMPILER_PIC($1)
+ _LT_COMPILER_C_O($1)
+ _LT_COMPILER_FILE_LOCKS($1)
+ _LT_LINKER_SHLIBS($1)
+ _LT_SYS_DYNAMIC_LINKER($1)
+ _LT_LINKER_HARDCODE_LIBPATH($1)
+
+ _LT_CONFIG($1)
+ fi # test -n "$compiler"
+
+ GCC=$lt_save_GCC
+ CC="$lt_save_CC"
+ CFLAGS="$lt_save_CFLAGS"
+fi # test "$_lt_disable_F77" != yes
+
+AC_LANG_POP
+])# _LT_LANG_F77_CONFIG
+
+
+# _LT_LANG_FC_CONFIG([TAG])
+# -------------------------
+# Ensure that the configuration variables for a Fortran compiler are
+# suitably defined. These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_FC_CONFIG],
+[AC_LANG_PUSH(Fortran)
+
+if test -z "$FC" || test "X$FC" = "Xno"; then
+ _lt_disable_FC=yes
+fi
+
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+_LT_TAGVAR(allow_undefined_flag, $1)=
+_LT_TAGVAR(always_export_symbols, $1)=no
+_LT_TAGVAR(archive_expsym_cmds, $1)=
+_LT_TAGVAR(export_dynamic_flag_spec, $1)=
+_LT_TAGVAR(hardcode_direct, $1)=no
+_LT_TAGVAR(hardcode_direct_absolute, $1)=no
+_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+_LT_TAGVAR(hardcode_libdir_separator, $1)=
+_LT_TAGVAR(hardcode_minus_L, $1)=no
+_LT_TAGVAR(hardcode_automatic, $1)=no
+_LT_TAGVAR(inherit_rpath, $1)=no
+_LT_TAGVAR(module_cmds, $1)=
+_LT_TAGVAR(module_expsym_cmds, $1)=
+_LT_TAGVAR(link_all_deplibs, $1)=unknown
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(reload_flag, $1)=$reload_flag
+_LT_TAGVAR(reload_cmds, $1)=$reload_cmds
+_LT_TAGVAR(no_undefined_flag, $1)=
+_LT_TAGVAR(whole_archive_flag_spec, $1)=
+_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+
+# Source file extension for fc test sources.
+ac_ext=${ac_fc_srcext-f}
+
+# Object file extension for compiled fc test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# No sense in running all these tests if we already determined that
+# the FC compiler isn't working. Some variables (like enable_shared)
+# are currently assumed to apply to all compilers on this platform,
+# and will be corrupted by setting them based on a non-working compiler.
+if test "$_lt_disable_FC" != yes; then
+ # Code to be used in simple compile tests
+ lt_simple_compile_test_code="\
+ subroutine t
+ return
+ end
+"
+
+ # Code to be used in simple link tests
+ lt_simple_link_test_code="\
+ program t
+ end
+"
+
+ # ltmain only uses $CC for tagged configurations so make sure $CC is set.
+ _LT_TAG_COMPILER
+
+ # save warnings/boilerplate of simple test code
+ _LT_COMPILER_BOILERPLATE
+ _LT_LINKER_BOILERPLATE
+
+ # Allow CC to be a program name with arguments.
+ lt_save_CC="$CC"
+ lt_save_GCC=$GCC
+ lt_save_CFLAGS=$CFLAGS
+ CC=${FC-"f95"}
+ CFLAGS=$FCFLAGS
+ compiler=$CC
+ GCC=$ac_cv_fc_compiler_gnu
+
+ _LT_TAGVAR(compiler, $1)=$CC
+ _LT_CC_BASENAME([$compiler])
+
+ if test -n "$compiler"; then
+ AC_MSG_CHECKING([if libtool supports shared libraries])
+ AC_MSG_RESULT([$can_build_shared])
+
+ AC_MSG_CHECKING([whether to build shared libraries])
+ test "$can_build_shared" = "no" && enable_shared=no
+
+ # On AIX, shared libraries and static libraries use the same namespace, and
+ # are all built from PIC.
+ case $host_os in
+ aix3*)
+ test "$enable_shared" = yes && enable_static=no
+ if test -n "$RANLIB"; then
+ archive_cmds="$archive_cmds~\$RANLIB \$lib"
+ postinstall_cmds='$RANLIB $lib'
+ fi
+ ;;
+ aix[[4-9]]*)
+ if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+ test "$enable_shared" = yes && enable_static=no
+ fi
+ ;;
+ esac
+ AC_MSG_RESULT([$enable_shared])
+
+ AC_MSG_CHECKING([whether to build static libraries])
+ # Make sure either enable_shared or enable_static is yes.
+ test "$enable_shared" = yes || enable_static=yes
+ AC_MSG_RESULT([$enable_static])
+
+ _LT_TAGVAR(GCC, $1)="$ac_cv_fc_compiler_gnu"
+ _LT_TAGVAR(LD, $1)="$LD"
+
+ ## CAVEAT EMPTOR:
+ ## There is no encapsulation within the following macros, do not change
+ ## the running order or otherwise move them around unless you know exactly
+ ## what you are doing...
+ _LT_SYS_HIDDEN_LIBDEPS($1)
+ _LT_COMPILER_PIC($1)
+ _LT_COMPILER_C_O($1)
+ _LT_COMPILER_FILE_LOCKS($1)
+ _LT_LINKER_SHLIBS($1)
+ _LT_SYS_DYNAMIC_LINKER($1)
+ _LT_LINKER_HARDCODE_LIBPATH($1)
+
+ _LT_CONFIG($1)
+ fi # test -n "$compiler"
+
+ GCC=$lt_save_GCC
+ CC=$lt_save_CC
+ CFLAGS=$lt_save_CFLAGS
+fi # test "$_lt_disable_FC" != yes
+
+AC_LANG_POP
+])# _LT_LANG_FC_CONFIG
+
+
+# _LT_LANG_GCJ_CONFIG([TAG])
+# --------------------------
+# Ensure that the configuration variables for the GNU Java Compiler compiler
+# are suitably defined. These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_GCJ_CONFIG],
+[AC_REQUIRE([LT_PROG_GCJ])dnl
+AC_LANG_SAVE
+
+# Source file extension for Java test sources.
+ac_ext=java
+
+# Object file extension for compiled Java test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="class foo {}"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }'
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+_LT_TAG_COMPILER
+
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
+
+# Allow CC to be a program name with arguments.
+lt_save_CC=$CC
+lt_save_CFLAGS=$CFLAGS
+lt_save_GCC=$GCC
+GCC=yes
+CC=${GCJ-"gcj"}
+CFLAGS=$GCJFLAGS
+compiler=$CC
+_LT_TAGVAR(compiler, $1)=$CC
+_LT_TAGVAR(LD, $1)="$LD"
+_LT_CC_BASENAME([$compiler])
+
+# GCJ did not exist at the time GCC didn't implicitly link libc in.
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(reload_flag, $1)=$reload_flag
+_LT_TAGVAR(reload_cmds, $1)=$reload_cmds
+
+## CAVEAT EMPTOR:
+## There is no encapsulation within the following macros, do not change
+## the running order or otherwise move them around unless you know exactly
+## what you are doing...
+if test -n "$compiler"; then
+ _LT_COMPILER_NO_RTTI($1)
+ _LT_COMPILER_PIC($1)
+ _LT_COMPILER_C_O($1)
+ _LT_COMPILER_FILE_LOCKS($1)
+ _LT_LINKER_SHLIBS($1)
+ _LT_LINKER_HARDCODE_LIBPATH($1)
+
+ _LT_CONFIG($1)
+fi
+
+AC_LANG_RESTORE
+
+GCC=$lt_save_GCC
+CC=$lt_save_CC
+CFLAGS=$lt_save_CFLAGS
+])# _LT_LANG_GCJ_CONFIG
+
+
+# _LT_LANG_GO_CONFIG([TAG])
+# --------------------------
+# Ensure that the configuration variables for the GNU Go compiler
+# are suitably defined. These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_GO_CONFIG],
+[AC_REQUIRE([LT_PROG_GO])dnl
+AC_LANG_SAVE
+
+# Source file extension for Go test sources.
+ac_ext=go
+
+# Object file extension for compiled Go test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="package main; func main() { }"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='package main; func main() { }'
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+_LT_TAG_COMPILER
+
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
+
+# Allow CC to be a program name with arguments.
+lt_save_CC=$CC
+lt_save_CFLAGS=$CFLAGS
+lt_save_GCC=$GCC
+GCC=yes
+CC=${GOC-"gccgo"}
+CFLAGS=$GOFLAGS
+compiler=$CC
+_LT_TAGVAR(compiler, $1)=$CC
+_LT_TAGVAR(LD, $1)="$LD"
+_LT_CC_BASENAME([$compiler])
+
+# Go did not exist at the time GCC didn't implicitly link libc in.
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(reload_flag, $1)=$reload_flag
+_LT_TAGVAR(reload_cmds, $1)=$reload_cmds
+
+## CAVEAT EMPTOR:
+## There is no encapsulation within the following macros, do not change
+## the running order or otherwise move them around unless you know exactly
+## what you are doing...
+if test -n "$compiler"; then
+ _LT_COMPILER_NO_RTTI($1)
+ _LT_COMPILER_PIC($1)
+ _LT_COMPILER_C_O($1)
+ _LT_COMPILER_FILE_LOCKS($1)
+ _LT_LINKER_SHLIBS($1)
+ _LT_LINKER_HARDCODE_LIBPATH($1)
+
+ _LT_CONFIG($1)
+fi
+
+AC_LANG_RESTORE
+
+GCC=$lt_save_GCC
+CC=$lt_save_CC
+CFLAGS=$lt_save_CFLAGS
+])# _LT_LANG_GO_CONFIG
+
+
+# _LT_LANG_RC_CONFIG([TAG])
+# -------------------------
+# Ensure that the configuration variables for the Windows resource compiler
+# are suitably defined. These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_RC_CONFIG],
+[AC_REQUIRE([LT_PROG_RC])dnl
+AC_LANG_SAVE
+
+# Source file extension for RC test sources.
+ac_ext=rc
+
+# Object file extension for compiled RC test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }'
+
+# Code to be used in simple link tests
+lt_simple_link_test_code="$lt_simple_compile_test_code"
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+_LT_TAG_COMPILER
+
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
+
+# Allow CC to be a program name with arguments.
+lt_save_CC="$CC"
+lt_save_CFLAGS=$CFLAGS
+lt_save_GCC=$GCC
+GCC=
+CC=${RC-"windres"}
+CFLAGS=
+compiler=$CC
+_LT_TAGVAR(compiler, $1)=$CC
+_LT_CC_BASENAME([$compiler])
+_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes
+
+if test -n "$compiler"; then
+ :
+ _LT_CONFIG($1)
+fi
+
+GCC=$lt_save_GCC
+AC_LANG_RESTORE
+CC=$lt_save_CC
+CFLAGS=$lt_save_CFLAGS
+])# _LT_LANG_RC_CONFIG
+
+
+# LT_PROG_GCJ
+# -----------
+AC_DEFUN([LT_PROG_GCJ],
+[m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ],
+ [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ],
+ [AC_CHECK_TOOL(GCJ, gcj,)
+ test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2"
+ AC_SUBST(GCJFLAGS)])])[]dnl
+])
+
+# Old name:
+AU_ALIAS([LT_AC_PROG_GCJ], [LT_PROG_GCJ])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([LT_AC_PROG_GCJ], [])
+
+
+# LT_PROG_GO
+# ----------
+AC_DEFUN([LT_PROG_GO],
+[AC_CHECK_TOOL(GOC, gccgo,)
+])
+
+
+# LT_PROG_RC
+# ----------
+AC_DEFUN([LT_PROG_RC],
+[AC_CHECK_TOOL(RC, windres,)
+])
+
+# Old name:
+AU_ALIAS([LT_AC_PROG_RC], [LT_PROG_RC])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([LT_AC_PROG_RC], [])
+
+
+# _LT_DECL_EGREP
+# --------------
+# If we don't have a new enough Autoconf to choose the best grep
+# available, choose the one first in the user's PATH.
+m4_defun([_LT_DECL_EGREP],
+[AC_REQUIRE([AC_PROG_EGREP])dnl
+AC_REQUIRE([AC_PROG_FGREP])dnl
+test -z "$GREP" && GREP=grep
+_LT_DECL([], [GREP], [1], [A grep program that handles long lines])
+_LT_DECL([], [EGREP], [1], [An ERE matcher])
+_LT_DECL([], [FGREP], [1], [A literal string matcher])
+dnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too
+AC_SUBST([GREP])
+])
+
+
+# _LT_DECL_OBJDUMP
+# --------------
+# If we don't have a new enough Autoconf to choose the best objdump
+# available, choose the one first in the user's PATH.
+m4_defun([_LT_DECL_OBJDUMP],
+[AC_CHECK_TOOL(OBJDUMP, objdump, false)
+test -z "$OBJDUMP" && OBJDUMP=objdump
+_LT_DECL([], [OBJDUMP], [1], [An object symbol dumper])
+AC_SUBST([OBJDUMP])
+])
+
+# _LT_DECL_DLLTOOL
+# ----------------
+# Ensure DLLTOOL variable is set.
+m4_defun([_LT_DECL_DLLTOOL],
+[AC_CHECK_TOOL(DLLTOOL, dlltool, false)
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+_LT_DECL([], [DLLTOOL], [1], [DLL creation program])
+AC_SUBST([DLLTOOL])
+])
+
+# _LT_DECL_SED
+# ------------
+# Check for a fully-functional sed program, that truncates
+# as few characters as possible. Prefer GNU sed if found.
+m4_defun([_LT_DECL_SED],
+[AC_PROG_SED
+test -z "$SED" && SED=sed
+Xsed="$SED -e 1s/^X//"
+_LT_DECL([], [SED], [1], [A sed program that does not truncate output])
+_LT_DECL([], [Xsed], ["\$SED -e 1s/^X//"],
+ [Sed that helps us avoid accidentally triggering echo(1) options like -n])
+])# _LT_DECL_SED
+
+m4_ifndef([AC_PROG_SED], [
+############################################################
+# NOTE: This macro has been submitted for inclusion into #
+# GNU Autoconf as AC_PROG_SED. When it is available in #
+# a released version of Autoconf we should remove this #
+# macro and use it instead. #
+############################################################
+
+m4_defun([AC_PROG_SED],
+[AC_MSG_CHECKING([for a sed that does not truncate output])
+AC_CACHE_VAL(lt_cv_path_SED,
+[# Loop through the user's path and test for sed and gsed.
+# Then use that list of sed's as ones to test for truncation.
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for lt_ac_prog in sed gsed; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then
+ lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext"
+ fi
+ done
+ done
+done
+IFS=$as_save_IFS
+lt_ac_max=0
+lt_ac_count=0
+# Add /usr/xpg4/bin/sed as it is typically found on Solaris
+# along with /bin/sed that truncates output.
+for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do
+ test ! -f $lt_ac_sed && continue
+ cat /dev/null > conftest.in
+ lt_ac_count=0
+ echo $ECHO_N "0123456789$ECHO_C" >conftest.in
+ # Check for GNU sed and select it if it is found.
+ if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then
+ lt_cv_path_SED=$lt_ac_sed
+ break
+ fi
+ while true; do
+ cat conftest.in conftest.in >conftest.tmp
+ mv conftest.tmp conftest.in
+ cp conftest.in conftest.nl
+ echo >>conftest.nl
+ $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break
+ cmp -s conftest.out conftest.nl || break
+ # 10000 chars as input seems more than enough
+ test $lt_ac_count -gt 10 && break
+ lt_ac_count=`expr $lt_ac_count + 1`
+ if test $lt_ac_count -gt $lt_ac_max; then
+ lt_ac_max=$lt_ac_count
+ lt_cv_path_SED=$lt_ac_sed
+ fi
+ done
+done
+])
+SED=$lt_cv_path_SED
+AC_SUBST([SED])
+AC_MSG_RESULT([$SED])
+])#AC_PROG_SED
+])#m4_ifndef
+
+# Old name:
+AU_ALIAS([LT_AC_PROG_SED], [AC_PROG_SED])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([LT_AC_PROG_SED], [])
+
+
+# _LT_CHECK_SHELL_FEATURES
+# ------------------------
+# Find out whether the shell is Bourne or XSI compatible,
+# or has some other useful features.
+m4_defun([_LT_CHECK_SHELL_FEATURES],
+[AC_MSG_CHECKING([whether the shell understands some XSI constructs])
+# Try some XSI features
+xsi_shell=no
+( _lt_dummy="a/b/c"
+ test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \
+ = c,a/b,b/c, \
+ && eval 'test $(( 1 + 1 )) -eq 2 \
+ && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \
+ && xsi_shell=yes
+AC_MSG_RESULT([$xsi_shell])
+_LT_CONFIG_LIBTOOL_INIT([xsi_shell='$xsi_shell'])
+
+AC_MSG_CHECKING([whether the shell understands "+="])
+lt_shell_append=no
+( foo=bar; set foo baz; eval "$[1]+=\$[2]" && test "$foo" = barbaz ) \
+ >/dev/null 2>&1 \
+ && lt_shell_append=yes
+AC_MSG_RESULT([$lt_shell_append])
+_LT_CONFIG_LIBTOOL_INIT([lt_shell_append='$lt_shell_append'])
+
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+ lt_unset=unset
+else
+ lt_unset=false
+fi
+_LT_DECL([], [lt_unset], [0], [whether the shell understands "unset"])dnl
+
+# test EBCDIC or ASCII
+case `echo X|tr X '\101'` in
+ A) # ASCII based system
+ # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr
+ lt_SP2NL='tr \040 \012'
+ lt_NL2SP='tr \015\012 \040\040'
+ ;;
+ *) # EBCDIC based system
+ lt_SP2NL='tr \100 \n'
+ lt_NL2SP='tr \r\n \100\100'
+ ;;
+esac
+_LT_DECL([SP2NL], [lt_SP2NL], [1], [turn spaces into newlines])dnl
+_LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl
+])# _LT_CHECK_SHELL_FEATURES
+
+
+# _LT_PROG_FUNCTION_REPLACE (FUNCNAME, REPLACEMENT-BODY)
+# ------------------------------------------------------
+# In `$cfgfile', look for function FUNCNAME delimited by `^FUNCNAME ()$' and
+# '^} FUNCNAME ', and replace its body with REPLACEMENT-BODY.
+m4_defun([_LT_PROG_FUNCTION_REPLACE],
+[dnl {
+sed -e '/^$1 ()$/,/^} # $1 /c\
+$1 ()\
+{\
+m4_bpatsubsts([$2], [$], [\\], [^\([ ]\)], [\\\1])
+} # Extended-shell $1 implementation' "$cfgfile" > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+])
+
+
+# _LT_PROG_REPLACE_SHELLFNS
+# -------------------------
+# Replace existing portable implementations of several shell functions with
+# equivalent extended shell implementations where those features are available..
+m4_defun([_LT_PROG_REPLACE_SHELLFNS],
+[if test x"$xsi_shell" = xyes; then
+ _LT_PROG_FUNCTION_REPLACE([func_dirname], [dnl
+ case ${1} in
+ */*) func_dirname_result="${1%/*}${2}" ;;
+ * ) func_dirname_result="${3}" ;;
+ esac])
+
+ _LT_PROG_FUNCTION_REPLACE([func_basename], [dnl
+ func_basename_result="${1##*/}"])
+
+ _LT_PROG_FUNCTION_REPLACE([func_dirname_and_basename], [dnl
+ case ${1} in
+ */*) func_dirname_result="${1%/*}${2}" ;;
+ * ) func_dirname_result="${3}" ;;
+ esac
+ func_basename_result="${1##*/}"])
+
+ _LT_PROG_FUNCTION_REPLACE([func_stripname], [dnl
+ # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are
+ # positional parameters, so assign one to ordinary parameter first.
+ func_stripname_result=${3}
+ func_stripname_result=${func_stripname_result#"${1}"}
+ func_stripname_result=${func_stripname_result%"${2}"}])
+
+ _LT_PROG_FUNCTION_REPLACE([func_split_long_opt], [dnl
+ func_split_long_opt_name=${1%%=*}
+ func_split_long_opt_arg=${1#*=}])
+
+ _LT_PROG_FUNCTION_REPLACE([func_split_short_opt], [dnl
+ func_split_short_opt_arg=${1#??}
+ func_split_short_opt_name=${1%"$func_split_short_opt_arg"}])
+
+ _LT_PROG_FUNCTION_REPLACE([func_lo2o], [dnl
+ case ${1} in
+ *.lo) func_lo2o_result=${1%.lo}.${objext} ;;
+ *) func_lo2o_result=${1} ;;
+ esac])
+
+ _LT_PROG_FUNCTION_REPLACE([func_xform], [ func_xform_result=${1%.*}.lo])
+
+ _LT_PROG_FUNCTION_REPLACE([func_arith], [ func_arith_result=$(( $[*] ))])
+
+ _LT_PROG_FUNCTION_REPLACE([func_len], [ func_len_result=${#1}])
+fi
+
+if test x"$lt_shell_append" = xyes; then
+ _LT_PROG_FUNCTION_REPLACE([func_append], [ eval "${1}+=\\${2}"])
+
+ _LT_PROG_FUNCTION_REPLACE([func_append_quoted], [dnl
+ func_quote_for_eval "${2}"
+dnl m4 expansion turns \\\\ into \\, and then the shell eval turns that into \
+ eval "${1}+=\\\\ \\$func_quote_for_eval_result"])
+
+ # Save a `func_append' function call where possible by direct use of '+='
+ sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+ test 0 -eq $? || _lt_function_replace_fail=:
+else
+ # Save a `func_append' function call even when '+=' is not available
+ sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+ test 0 -eq $? || _lt_function_replace_fail=:
+fi
+
+if test x"$_lt_function_replace_fail" = x":"; then
+ AC_MSG_WARN([Unable to substitute extended shell functions in $ofile])
+fi
+])
+
+# _LT_PATH_CONVERSION_FUNCTIONS
+# -----------------------------
+# Determine which file name conversion functions should be used by
+# func_to_host_file (and, implicitly, by func_to_host_path). These are needed
+# for certain cross-compile configurations and native mingw.
+m4_defun([_LT_PATH_CONVERSION_FUNCTIONS],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+AC_MSG_CHECKING([how to convert $build file names to $host format])
+AC_CACHE_VAL(lt_cv_to_host_file_cmd,
+[case $host in
+ *-*-mingw* )
+ case $build in
+ *-*-mingw* ) # actually msys
+ lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32
+ ;;
+ *-*-cygwin* )
+ lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32
+ ;;
+ * ) # otherwise, assume *nix
+ lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32
+ ;;
+ esac
+ ;;
+ *-*-cygwin* )
+ case $build in
+ *-*-mingw* ) # actually msys
+ lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin
+ ;;
+ *-*-cygwin* )
+ lt_cv_to_host_file_cmd=func_convert_file_noop
+ ;;
+ * ) # otherwise, assume *nix
+ lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin
+ ;;
+ esac
+ ;;
+ * ) # unhandled hosts (and "normal" native builds)
+ lt_cv_to_host_file_cmd=func_convert_file_noop
+ ;;
+esac
+])
+to_host_file_cmd=$lt_cv_to_host_file_cmd
+AC_MSG_RESULT([$lt_cv_to_host_file_cmd])
+_LT_DECL([to_host_file_cmd], [lt_cv_to_host_file_cmd],
+ [0], [convert $build file names to $host format])dnl
+
+AC_MSG_CHECKING([how to convert $build file names to toolchain format])
+AC_CACHE_VAL(lt_cv_to_tool_file_cmd,
+[#assume ordinary cross tools, or native build.
+lt_cv_to_tool_file_cmd=func_convert_file_noop
+case $host in
+ *-*-mingw* )
+ case $build in
+ *-*-mingw* ) # actually msys
+ lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32
+ ;;
+ esac
+ ;;
+esac
+])
+to_tool_file_cmd=$lt_cv_to_tool_file_cmd
+AC_MSG_RESULT([$lt_cv_to_tool_file_cmd])
+_LT_DECL([to_tool_file_cmd], [lt_cv_to_tool_file_cmd],
+ [0], [convert $build files to toolchain format])dnl
+])# _LT_PATH_CONVERSION_FUNCTIONS
diff --git a/m4/ltoptions.m4 b/m4/ltoptions.m4
new file mode 100644
index 0000000..5d9acd8
--- /dev/null
+++ b/m4/ltoptions.m4
@@ -0,0 +1,384 @@
+# Helper functions for option handling. -*- Autoconf -*-
+#
+# Copyright (C) 2004, 2005, 2007, 2008, 2009 Free Software Foundation,
+# Inc.
+# Written by Gary V. Vaughan, 2004
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+
+# serial 7 ltoptions.m4
+
+# This is to help aclocal find these macros, as it can't see m4_define.
+AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])])
+
+
+# _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME)
+# ------------------------------------------
+m4_define([_LT_MANGLE_OPTION],
+[[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])])
+
+
+# _LT_SET_OPTION(MACRO-NAME, OPTION-NAME)
+# ---------------------------------------
+# Set option OPTION-NAME for macro MACRO-NAME, and if there is a
+# matching handler defined, dispatch to it. Other OPTION-NAMEs are
+# saved as a flag.
+m4_define([_LT_SET_OPTION],
+[m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl
+m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]),
+ _LT_MANGLE_DEFUN([$1], [$2]),
+ [m4_warning([Unknown $1 option `$2'])])[]dnl
+])
+
+
+# _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET])
+# ------------------------------------------------------------
+# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
+m4_define([_LT_IF_OPTION],
+[m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])])
+
+
+# _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET)
+# -------------------------------------------------------
+# Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME
+# are set.
+m4_define([_LT_UNLESS_OPTIONS],
+[m4_foreach([_LT_Option], m4_split(m4_normalize([$2])),
+ [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option),
+ [m4_define([$0_found])])])[]dnl
+m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3
+])[]dnl
+])
+
+
+# _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST)
+# ----------------------------------------
+# OPTION-LIST is a space-separated list of Libtool options associated
+# with MACRO-NAME. If any OPTION has a matching handler declared with
+# LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about
+# the unknown option and exit.
+m4_defun([_LT_SET_OPTIONS],
+[# Set options
+m4_foreach([_LT_Option], m4_split(m4_normalize([$2])),
+ [_LT_SET_OPTION([$1], _LT_Option)])
+
+m4_if([$1],[LT_INIT],[
+ dnl
+ dnl Simply set some default values (i.e off) if boolean options were not
+ dnl specified:
+ _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no
+ ])
+ _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no
+ ])
+ dnl
+ dnl If no reference was made to various pairs of opposing options, then
+ dnl we run the default mode handler for the pair. For example, if neither
+ dnl `shared' nor `disable-shared' was passed, we enable building of shared
+ dnl archives by default:
+ _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED])
+ _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC])
+ _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC])
+ _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install],
+ [_LT_ENABLE_FAST_INSTALL])
+ ])
+])# _LT_SET_OPTIONS
+
+
+## --------------------------------- ##
+## Macros to handle LT_INIT options. ##
+## --------------------------------- ##
+
+# _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME)
+# -----------------------------------------
+m4_define([_LT_MANGLE_DEFUN],
+[[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])])
+
+
+# LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE)
+# -----------------------------------------------
+m4_define([LT_OPTION_DEFINE],
+[m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl
+])# LT_OPTION_DEFINE
+
+
+# dlopen
+# ------
+LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes
+])
+
+AU_DEFUN([AC_LIBTOOL_DLOPEN],
+[_LT_SET_OPTION([LT_INIT], [dlopen])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you
+put the `dlopen' option into LT_INIT's first parameter.])
+])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], [])
+
+
+# win32-dll
+# ---------
+# Declare package support for building win32 dll's.
+LT_OPTION_DEFINE([LT_INIT], [win32-dll],
+[enable_win32_dll=yes
+
+case $host in
+*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*)
+ AC_CHECK_TOOL(AS, as, false)
+ AC_CHECK_TOOL(DLLTOOL, dlltool, false)
+ AC_CHECK_TOOL(OBJDUMP, objdump, false)
+ ;;
+esac
+
+test -z "$AS" && AS=as
+_LT_DECL([], [AS], [1], [Assembler program])dnl
+
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+_LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl
+
+test -z "$OBJDUMP" && OBJDUMP=objdump
+_LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl
+])# win32-dll
+
+AU_DEFUN([AC_LIBTOOL_WIN32_DLL],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+_LT_SET_OPTION([LT_INIT], [win32-dll])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you
+put the `win32-dll' option into LT_INIT's first parameter.])
+])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], [])
+
+
+# _LT_ENABLE_SHARED([DEFAULT])
+# ----------------------------
+# implement the --enable-shared flag, and supports the `shared' and
+# `disable-shared' LT_INIT options.
+# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'.
+m4_define([_LT_ENABLE_SHARED],
+[m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl
+AC_ARG_ENABLE([shared],
+ [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@],
+ [build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])],
+ [p=${PACKAGE-default}
+ case $enableval in
+ yes) enable_shared=yes ;;
+ no) enable_shared=no ;;
+ *)
+ enable_shared=no
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+ for pkg in $enableval; do
+ IFS="$lt_save_ifs"
+ if test "X$pkg" = "X$p"; then
+ enable_shared=yes
+ fi
+ done
+ IFS="$lt_save_ifs"
+ ;;
+ esac],
+ [enable_shared=]_LT_ENABLE_SHARED_DEFAULT)
+
+ _LT_DECL([build_libtool_libs], [enable_shared], [0],
+ [Whether or not to build shared libraries])
+])# _LT_ENABLE_SHARED
+
+LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])])
+LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])])
+
+# Old names:
+AC_DEFUN([AC_ENABLE_SHARED],
+[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared])
+])
+
+AC_DEFUN([AC_DISABLE_SHARED],
+[_LT_SET_OPTION([LT_INIT], [disable-shared])
+])
+
+AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)])
+AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AM_ENABLE_SHARED], [])
+dnl AC_DEFUN([AM_DISABLE_SHARED], [])
+
+
+
+# _LT_ENABLE_STATIC([DEFAULT])
+# ----------------------------
+# implement the --enable-static flag, and support the `static' and
+# `disable-static' LT_INIT options.
+# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'.
+m4_define([_LT_ENABLE_STATIC],
+[m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl
+AC_ARG_ENABLE([static],
+ [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@],
+ [build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])],
+ [p=${PACKAGE-default}
+ case $enableval in
+ yes) enable_static=yes ;;
+ no) enable_static=no ;;
+ *)
+ enable_static=no
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+ for pkg in $enableval; do
+ IFS="$lt_save_ifs"
+ if test "X$pkg" = "X$p"; then
+ enable_static=yes
+ fi
+ done
+ IFS="$lt_save_ifs"
+ ;;
+ esac],
+ [enable_static=]_LT_ENABLE_STATIC_DEFAULT)
+
+ _LT_DECL([build_old_libs], [enable_static], [0],
+ [Whether or not to build static libraries])
+])# _LT_ENABLE_STATIC
+
+LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])])
+LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])])
+
+# Old names:
+AC_DEFUN([AC_ENABLE_STATIC],
+[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static])
+])
+
+AC_DEFUN([AC_DISABLE_STATIC],
+[_LT_SET_OPTION([LT_INIT], [disable-static])
+])
+
+AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)])
+AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AM_ENABLE_STATIC], [])
+dnl AC_DEFUN([AM_DISABLE_STATIC], [])
+
+
+
+# _LT_ENABLE_FAST_INSTALL([DEFAULT])
+# ----------------------------------
+# implement the --enable-fast-install flag, and support the `fast-install'
+# and `disable-fast-install' LT_INIT options.
+# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'.
+m4_define([_LT_ENABLE_FAST_INSTALL],
+[m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl
+AC_ARG_ENABLE([fast-install],
+ [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@],
+ [optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])],
+ [p=${PACKAGE-default}
+ case $enableval in
+ yes) enable_fast_install=yes ;;
+ no) enable_fast_install=no ;;
+ *)
+ enable_fast_install=no
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+ for pkg in $enableval; do
+ IFS="$lt_save_ifs"
+ if test "X$pkg" = "X$p"; then
+ enable_fast_install=yes
+ fi
+ done
+ IFS="$lt_save_ifs"
+ ;;
+ esac],
+ [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT)
+
+_LT_DECL([fast_install], [enable_fast_install], [0],
+ [Whether or not to optimize for fast installation])dnl
+])# _LT_ENABLE_FAST_INSTALL
+
+LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])])
+LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])])
+
+# Old names:
+AU_DEFUN([AC_ENABLE_FAST_INSTALL],
+[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you put
+the `fast-install' option into LT_INIT's first parameter.])
+])
+
+AU_DEFUN([AC_DISABLE_FAST_INSTALL],
+[_LT_SET_OPTION([LT_INIT], [disable-fast-install])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you put
+the `disable-fast-install' option into LT_INIT's first parameter.])
+])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], [])
+dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], [])
+
+
+# _LT_WITH_PIC([MODE])
+# --------------------
+# implement the --with-pic flag, and support the `pic-only' and `no-pic'
+# LT_INIT options.
+# MODE is either `yes' or `no'. If omitted, it defaults to `both'.
+m4_define([_LT_WITH_PIC],
+[AC_ARG_WITH([pic],
+ [AS_HELP_STRING([--with-pic@<:@=PKGS@:>@],
+ [try to use only PIC/non-PIC objects @<:@default=use both@:>@])],
+ [lt_p=${PACKAGE-default}
+ case $withval in
+ yes|no) pic_mode=$withval ;;
+ *)
+ pic_mode=default
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+ for lt_pkg in $withval; do
+ IFS="$lt_save_ifs"
+ if test "X$lt_pkg" = "X$lt_p"; then
+ pic_mode=yes
+ fi
+ done
+ IFS="$lt_save_ifs"
+ ;;
+ esac],
+ [pic_mode=default])
+
+test -z "$pic_mode" && pic_mode=m4_default([$1], [default])
+
+_LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl
+])# _LT_WITH_PIC
+
+LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])])
+LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])])
+
+# Old name:
+AU_DEFUN([AC_LIBTOOL_PICMODE],
+[_LT_SET_OPTION([LT_INIT], [pic-only])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you
+put the `pic-only' option into LT_INIT's first parameter.])
+])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_PICMODE], [])
+
+## ----------------- ##
+## LTDL_INIT Options ##
+## ----------------- ##
+
+m4_define([_LTDL_MODE], [])
+LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive],
+ [m4_define([_LTDL_MODE], [nonrecursive])])
+LT_OPTION_DEFINE([LTDL_INIT], [recursive],
+ [m4_define([_LTDL_MODE], [recursive])])
+LT_OPTION_DEFINE([LTDL_INIT], [subproject],
+ [m4_define([_LTDL_MODE], [subproject])])
+
+m4_define([_LTDL_TYPE], [])
+LT_OPTION_DEFINE([LTDL_INIT], [installable],
+ [m4_define([_LTDL_TYPE], [installable])])
+LT_OPTION_DEFINE([LTDL_INIT], [convenience],
+ [m4_define([_LTDL_TYPE], [convenience])])
diff --git a/m4/ltsugar.m4 b/m4/ltsugar.m4
new file mode 100644
index 0000000..9000a05
--- /dev/null
+++ b/m4/ltsugar.m4
@@ -0,0 +1,123 @@
+# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*-
+#
+# Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc.
+# Written by Gary V. Vaughan, 2004
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+
+# serial 6 ltsugar.m4
+
+# This is to help aclocal find these macros, as it can't see m4_define.
+AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])])
+
+
+# lt_join(SEP, ARG1, [ARG2...])
+# -----------------------------
+# Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their
+# associated separator.
+# Needed until we can rely on m4_join from Autoconf 2.62, since all earlier
+# versions in m4sugar had bugs.
+m4_define([lt_join],
+[m4_if([$#], [1], [],
+ [$#], [2], [[$2]],
+ [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])])
+m4_define([_lt_join],
+[m4_if([$#$2], [2], [],
+ [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])])
+
+
+# lt_car(LIST)
+# lt_cdr(LIST)
+# ------------
+# Manipulate m4 lists.
+# These macros are necessary as long as will still need to support
+# Autoconf-2.59 which quotes differently.
+m4_define([lt_car], [[$1]])
+m4_define([lt_cdr],
+[m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])],
+ [$#], 1, [],
+ [m4_dquote(m4_shift($@))])])
+m4_define([lt_unquote], $1)
+
+
+# lt_append(MACRO-NAME, STRING, [SEPARATOR])
+# ------------------------------------------
+# Redefine MACRO-NAME to hold its former content plus `SEPARATOR'`STRING'.
+# Note that neither SEPARATOR nor STRING are expanded; they are appended
+# to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked).
+# No SEPARATOR is output if MACRO-NAME was previously undefined (different
+# than defined and empty).
+#
+# This macro is needed until we can rely on Autoconf 2.62, since earlier
+# versions of m4sugar mistakenly expanded SEPARATOR but not STRING.
+m4_define([lt_append],
+[m4_define([$1],
+ m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])])
+
+
+
+# lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...])
+# ----------------------------------------------------------
+# Produce a SEP delimited list of all paired combinations of elements of
+# PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list
+# has the form PREFIXmINFIXSUFFIXn.
+# Needed until we can rely on m4_combine added in Autoconf 2.62.
+m4_define([lt_combine],
+[m4_if(m4_eval([$# > 3]), [1],
+ [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl
+[[m4_foreach([_Lt_prefix], [$2],
+ [m4_foreach([_Lt_suffix],
+ ]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[,
+ [_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])])
+
+
+# lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ])
+# -----------------------------------------------------------------------
+# Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited
+# by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ.
+m4_define([lt_if_append_uniq],
+[m4_ifdef([$1],
+ [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1],
+ [lt_append([$1], [$2], [$3])$4],
+ [$5])],
+ [lt_append([$1], [$2], [$3])$4])])
+
+
+# lt_dict_add(DICT, KEY, VALUE)
+# -----------------------------
+m4_define([lt_dict_add],
+[m4_define([$1($2)], [$3])])
+
+
+# lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE)
+# --------------------------------------------
+m4_define([lt_dict_add_subkey],
+[m4_define([$1($2:$3)], [$4])])
+
+
+# lt_dict_fetch(DICT, KEY, [SUBKEY])
+# ----------------------------------
+m4_define([lt_dict_fetch],
+[m4_ifval([$3],
+ m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]),
+ m4_ifdef([$1($2)], [m4_defn([$1($2)])]))])
+
+
+# lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE])
+# -----------------------------------------------------------------
+m4_define([lt_if_dict_fetch],
+[m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4],
+ [$5],
+ [$6])])
+
+
+# lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...])
+# --------------------------------------------------------------
+m4_define([lt_dict_filter],
+[m4_if([$5], [], [],
+ [lt_join(m4_quote(m4_default([$4], [[, ]])),
+ lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]),
+ [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl
+])
diff --git a/m4/ltversion.m4 b/m4/ltversion.m4
new file mode 100644
index 0000000..07a8602
--- /dev/null
+++ b/m4/ltversion.m4
@@ -0,0 +1,23 @@
+# ltversion.m4 -- version numbers -*- Autoconf -*-
+#
+# Copyright (C) 2004 Free Software Foundation, Inc.
+# Written by Scott James Remnant, 2004
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+
+# @configure_input@
+
+# serial 3337 ltversion.m4
+# This file is part of GNU Libtool
+
+m4_define([LT_PACKAGE_VERSION], [2.4.2])
+m4_define([LT_PACKAGE_REVISION], [1.3337])
+
+AC_DEFUN([LTVERSION_VERSION],
+[macro_version='2.4.2'
+macro_revision='1.3337'
+_LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?])
+_LT_DECL(, macro_revision, 0)
+])
diff --git a/m4/lt~obsolete.m4 b/m4/lt~obsolete.m4
new file mode 100644
index 0000000..c573da9
--- /dev/null
+++ b/m4/lt~obsolete.m4
@@ -0,0 +1,98 @@
+# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*-
+#
+# Copyright (C) 2004, 2005, 2007, 2009 Free Software Foundation, Inc.
+# Written by Scott James Remnant, 2004.
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+
+# serial 5 lt~obsolete.m4
+
+# These exist entirely to fool aclocal when bootstrapping libtool.
+#
+# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN)
+# which have later been changed to m4_define as they aren't part of the
+# exported API, or moved to Autoconf or Automake where they belong.
+#
+# The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN
+# in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us
+# using a macro with the same name in our local m4/libtool.m4 it'll
+# pull the old libtool.m4 in (it doesn't see our shiny new m4_define
+# and doesn't know about Autoconf macros at all.)
+#
+# So we provide this file, which has a silly filename so it's always
+# included after everything else. This provides aclocal with the
+# AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything
+# because those macros already exist, or will be overwritten later.
+# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6.
+#
+# Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here.
+# Yes, that means every name once taken will need to remain here until
+# we give up compatibility with versions before 1.7, at which point
+# we need to keep only those names which we still refer to.
+
+# This is to help aclocal find these macros, as it can't see m4_define.
+AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])])
+
+m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])])
+m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])])
+m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])])
+m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])])
+m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])])
+m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])])
+m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])])
+m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])])
+m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])])
+m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])])
+m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])])
+m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])])
+m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])])
+m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])])
+m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])])
+m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])])
+m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])])
+m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])])
+m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])])
+m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])])
+m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])])
+m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])])
+m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])])
+m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])])
+m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])])
+m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])])
+m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])])
+m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])])
+m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])])
+m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])])
+m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])])
+m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])])
+m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])])
+m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])])
+m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])])
+m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])])
+m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])])
+m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])])
+m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])])
+m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])])
+m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])])
+m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])])
+m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])])
+m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])])
+m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])])
+m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])])
+m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])])
+m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])])
+m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])])
+m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])])
+m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])])
+m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])])
+m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])])
+m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])])
+m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS], [AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])])
+m4_ifndef([_LT_AC_PROG_CXXCPP], [AC_DEFUN([_LT_AC_PROG_CXXCPP])])
+m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS], [AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])])
+m4_ifndef([_LT_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])])
+m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])])
+m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])])
+m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])])
diff --git a/man/Makefile.am b/man/Makefile.am
new file mode 100644
index 0000000..a57af14
--- /dev/null
+++ b/man/Makefile.am
@@ -0,0 +1,189 @@
+# Copyright (c) 2004 MontaVista Software, Inc.
+# Copyright (c) 2009, 2012, 2014 Red Hat, Inc.
+#
+# Authors: Steven Dake (sdake@redhat.com)
+# Fabio M. Di Nitto (fdinitto@redhat.com)
+#
+# All rights reserved.
+#
+# This software licensed under BSD license, the text of which follows:
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# - Redistributions of source code must retain the above copyright notice,
+# this list of conditions and the following disclaimer.
+# - Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+# - Neither the name of the MontaVista Software, Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from this
+# software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+# THE POSSIBILITY OF SUCH DAMAGE.
+
+MAINTAINERCLEANFILES = Makefile.in
+
+xml_man = corosync-xmlproc.8 \
+ corosync.xml.5
+
+corosync_vqsim_man = corosync-vqsim.8
+
+INDEX_HTML = index.html
+
+autogen_man = cpg_context_get.3 \
+ cpg_context_set.3 \
+ cpg_dispatch.3 \
+ cpg_fd_get.3 \
+ cpg_finalize.3 \
+ cpg_initialize.3 \
+ cpg_join.3 \
+ cpg_leave.3 \
+ cpg_local_get.3 \
+ cpg_mcast_joined.3 \
+ cpg_model_initialize.3 \
+ cpg_zcb_mcast_joined.3 \
+ cpg_zcb_alloc.3 \
+ cpg_zcb_free.3 \
+ cpg_membership_get.3 \
+ cpg_iteration_finalize.3 \
+ cpg_iteration_initialize.3 \
+ cpg_iteration_next.3 \
+ quorum_initialize.3 \
+ quorum_model_initialize.3 \
+ quorum_finalize.3 \
+ quorum_fd_get.3 \
+ quorum_dispatch.3 \
+ quorum_context_get.3 \
+ quorum_context_set.3 \
+ quorum_getquorate.3 \
+ quorum_trackstart.3 \
+ quorum_trackstop.3 \
+ votequorum_dispatch.3 \
+ votequorum_fd_get.3 \
+ votequorum_context_get.3 \
+ votequorum_context_set.3 \
+ votequorum_finalize.3 \
+ votequorum_getinfo.3 \
+ votequorum_initialize.3 \
+ votequorum_setexpected.3 \
+ votequorum_setvotes.3 \
+ votequorum_trackstart.3 \
+ votequorum_trackstop.3 \
+ votequorum_qdevice_register.3 \
+ votequorum_qdevice_unregister.3 \
+ votequorum_qdevice_update.3 \
+ votequorum_qdevice_master_wins.3 \
+ votequorum_qdevice_poll.3 \
+ sam_data_getsize.3 \
+ sam_data_restore.3 \
+ sam_data_store.3 \
+ sam_finalize.3 \
+ sam_hc_callback_register.3 \
+ sam_hc_send.3 \
+ sam_initialize.3 \
+ sam_mark_failed.3 \
+ sam_register.3 \
+ sam_start.3 \
+ sam_stop.3 \
+ sam_warn_signal_set.3 \
+ cmap_context_get.3 \
+ cmap_dec.3 \
+ cmap_iter_init.3 \
+ cmap_get.3 \
+ cmap_inc.3 \
+ cmap_set.3 \
+ cmap_iter_next.3 \
+ cmap_delete.3 \
+ cmap_iter_finalize.3 \
+ cmap_finalize.3 \
+ cmap_dispatch.3 \
+ cmap_initialize.3 \
+ cmap_initialize_map.3 \
+ cmap_track_add.3 \
+ cmap_context_set.3 \
+ cmap_fd_get.3 \
+ cmap_track_delete.3
+
+autogen_common = ipc_common.sh.errors
+
+EXTRA_DIST = $(INDEX_HTML) \
+ $(xml_man) \
+ $(corosync_vqsim_man) \
+ $(autogen_man:%=%.in) \
+ $(autogen_common)
+
+man_MANS = $(autogen_man)
+
+dist_man_MANS = corosync.conf.5 \
+ votequorum.5 \
+ corosync.8 \
+ corosync-cmapctl.8 \
+ corosync-blackbox.8 \
+ corosync-keygen.8 \
+ corosync-cfgtool.8 \
+ corosync-cpgtool.8 \
+ corosync-notifyd.8 \
+ corosync-quorumtool.8 \
+ corosync_overview.7 \
+ cpg_overview.3 \
+ quorum_overview.3 \
+ votequorum_overview.3 \
+ sam_overview.3 \
+ cmap_overview.3 \
+ cmap_keys.7
+
+if BUILD_VQSIM
+dist_man_MANS += $(corosync_vqsim_man)
+endif
+
+if INSTALL_XMLCONF
+dist_man_MANS += $(xml_man)
+endif
+
+HTML_DOCS = $(dist_man_MANS:%=%.html) $(man_MANS:%=%.html)
+
+# developer man page generation
+%.3: %.3.in $(autogen_common)
+ @echo Generating $@ man page && \
+ rm -f $@-t-t $@-t $@ && \
+ DATE_FMT="%Y-%m-%d" && \
+ SOURCE_DATE_EPOCH="$${SOURCE_DATE_EPOCH:-$$(date +%s)}" && \
+ date="$$(date -u -d "@$$SOURCE_DATE_EPOCH" "+$$DATE_FMT" 2>/dev/null || date -u -r "$$SOURCE_DATE_EPOCH" "+$$DATE_FMT" 2>/dev/null || date -u "+$$DATE_FMT")" && \
+ $(AWK) "{print}(\$$1 ~ /@COMMONIPCERRORS@/){exit 0}" ${top_srcdir}/man/$@.in > $@-t-t && \
+ cat ${top_srcdir}/man/$(autogen_common) >> $@-t-t && \
+ $(AWK) -v p=0 "(\$$1 ~ /@COMMONIPCERRORS@/){p = 1} {if(p==1)print}" ${top_srcdir}/man/$@.in >> $@-t-t && \
+ cat $@-t-t | \
+ $(SED) -e 's#@BUILDDATE@#'$$date'#g' \
+ -e 's#@COMMONIPCERRORS@##g' \
+ > $@-t && \
+ rm -f $@-t-t && \
+ mv $@-t $@
+
+clean-local:
+ rm -rf $(HTML_DOCS) $(autogen_man)
+
+if BUILD_HTML_DOCS
+%.html: %
+ $(GROFF) -mandoc -Thtml $^ > $@
+
+install-data-local:
+ $(INSTALL) -d $(DESTDIR)/${docdir}/html
+ $(INSTALL) -m 644 ${srcdir}/$(INDEX_HTML) $(HTML_DOCS) $(DESTDIR)/${docdir}/html/
+
+uninstall-local:
+ cd $(DESTDIR)/${docdir}/html && rm -f $(INDEX_HTML) $(HTML_DOCS)
+ rmdir $(DESTDIR)/${docdir}/html 2> /dev/null || :
+
+all-local: $(HTML_DOCS)
+endif
diff --git a/man/Makefile.in b/man/Makefile.in
new file mode 100644
index 0000000..aff09fa
--- /dev/null
+++ b/man/Makefile.in
@@ -0,0 +1,863 @@
+# Makefile.in generated by automake 1.13.4 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+# Copyright (c) 2004 MontaVista Software, Inc.
+# Copyright (c) 2009, 2012, 2014 Red Hat, Inc.
+#
+# Authors: Steven Dake (sdake@redhat.com)
+# Fabio M. Di Nitto (fdinitto@redhat.com)
+#
+# All rights reserved.
+#
+# This software licensed under BSD license, the text of which follows:
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# - Redistributions of source code must retain the above copyright notice,
+# this list of conditions and the following disclaimer.
+# - Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+# - Neither the name of the MontaVista Software, Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from this
+# software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+# THE POSSIBILITY OF SUCH DAMAGE.
+VPATH = @srcdir@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+@BUILD_VQSIM_TRUE@am__append_1 = $(corosync_vqsim_man)
+@INSTALL_XMLCONF_TRUE@am__append_2 = $(xml_man)
+subdir = man
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+ $(dist_man_MANS)
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/lib/libcfg.verso $(top_srcdir)/lib/libcpg.verso \
+ $(top_srcdir)/lib/libquorum.verso \
+ $(top_srcdir)/lib/libsam.verso \
+ $(top_srcdir)/lib/libvotequorum.verso \
+ $(top_srcdir)/lib/libcmap.verso $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/include/corosync/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+SOURCES =
+DIST_SOURCES =
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+man3dir = $(mandir)/man3
+am__installdirs = "$(DESTDIR)$(man3dir)" "$(DESTDIR)$(man5dir)" \
+ "$(DESTDIR)$(man7dir)" "$(DESTDIR)$(man8dir)"
+man5dir = $(mandir)/man5
+man7dir = $(mandir)/man7
+man8dir = $(mandir)/man8
+NROFF = nroff
+MANS = $(dist_man_MANS) $(man_MANS)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALLOCA = @ALLOCA@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUGTOOL = @AUGTOOL@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BASHPATH = @BASHPATH@
+BINDGEN = @BINDGEN@
+CARGO = @CARGO@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFG_SONAME = @CFG_SONAME@
+CFLAGS = @CFLAGS@
+CLIPPY = @CLIPPY@
+CMAP_SONAME = @CMAP_SONAME@
+COROSYSCONFDIR = @COROSYSCONFDIR@
+CPG_SONAME = @CPG_SONAME@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DBUS_CFLAGS = @DBUS_CFLAGS@
+DBUS_LIBS = @DBUS_LIBS@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DOT = @DOT@
+DOXYGEN = @DOXYGEN@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GREP = @GREP@
+GROFF = @GROFF@
+INITCONFIGDIR = @INITCONFIGDIR@
+INITDDIR = @INITDDIR@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBQB_CFLAGS = @LIBQB_CFLAGS@
+LIBQB_LIBS = @LIBQB_LIBS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LINT_FLAGS = @LINT_FLAGS@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LOGDIR = @LOGDIR@
+LOGROTATEDIR = @LOGROTATEDIR@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+QUORUM_SONAME = @QUORUM_SONAME@
+RANLIB = @RANLIB@
+RUSTC = @RUSTC@
+RUSTDOC = @RUSTDOC@
+RUSTFMT = @RUSTFMT@
+RUST_FLAGS = @RUST_FLAGS@
+RUST_TARGET_DIR = @RUST_TARGET_DIR@
+SAM_SONAME = @SAM_SONAME@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SNMPCONFIG = @SNMPCONFIG@
+SNMP_LIBS = @SNMP_LIBS@
+SOMAJOR = @SOMAJOR@
+SOMICRO = @SOMICRO@
+SOMINOR = @SOMINOR@
+SONAME = @SONAME@
+STRIP = @STRIP@
+SYSTEMDDIR = @SYSTEMDDIR@
+VERSCRIPT_LDFLAGS = @VERSCRIPT_LDFLAGS@
+VERSION = @VERSION@
+VOTEQUORUM_SONAME = @VOTEQUORUM_SONAME@
+WITH_LIST = @WITH_LIST@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+corosyncrustver = @corosyncrustver@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+knet_CFLAGS = @knet_CFLAGS@
+knet_LIBS = @knet_LIBS@
+libdir = @libdir@
+libexecdir = @libexecdir@
+libsystemd_CFLAGS = @libsystemd_CFLAGS@
+libsystemd_LIBS = @libsystemd_LIBS@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+nozzle_CFLAGS = @nozzle_CFLAGS@
+nozzle_LIBS = @nozzle_LIBS@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+statgrab_CFLAGS = @statgrab_CFLAGS@
+statgrab_LIBS = @statgrab_LIBS@
+statgrabge090_CFLAGS = @statgrabge090_CFLAGS@
+statgrabge090_LIBS = @statgrabge090_LIBS@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+MAINTAINERCLEANFILES = Makefile.in
+xml_man = corosync-xmlproc.8 \
+ corosync.xml.5
+
+corosync_vqsim_man = corosync-vqsim.8
+INDEX_HTML = index.html
+autogen_man = cpg_context_get.3 \
+ cpg_context_set.3 \
+ cpg_dispatch.3 \
+ cpg_fd_get.3 \
+ cpg_finalize.3 \
+ cpg_initialize.3 \
+ cpg_join.3 \
+ cpg_leave.3 \
+ cpg_local_get.3 \
+ cpg_mcast_joined.3 \
+ cpg_model_initialize.3 \
+ cpg_zcb_mcast_joined.3 \
+ cpg_zcb_alloc.3 \
+ cpg_zcb_free.3 \
+ cpg_membership_get.3 \
+ cpg_iteration_finalize.3 \
+ cpg_iteration_initialize.3 \
+ cpg_iteration_next.3 \
+ quorum_initialize.3 \
+ quorum_model_initialize.3 \
+ quorum_finalize.3 \
+ quorum_fd_get.3 \
+ quorum_dispatch.3 \
+ quorum_context_get.3 \
+ quorum_context_set.3 \
+ quorum_getquorate.3 \
+ quorum_trackstart.3 \
+ quorum_trackstop.3 \
+ votequorum_dispatch.3 \
+ votequorum_fd_get.3 \
+ votequorum_context_get.3 \
+ votequorum_context_set.3 \
+ votequorum_finalize.3 \
+ votequorum_getinfo.3 \
+ votequorum_initialize.3 \
+ votequorum_setexpected.3 \
+ votequorum_setvotes.3 \
+ votequorum_trackstart.3 \
+ votequorum_trackstop.3 \
+ votequorum_qdevice_register.3 \
+ votequorum_qdevice_unregister.3 \
+ votequorum_qdevice_update.3 \
+ votequorum_qdevice_master_wins.3 \
+ votequorum_qdevice_poll.3 \
+ sam_data_getsize.3 \
+ sam_data_restore.3 \
+ sam_data_store.3 \
+ sam_finalize.3 \
+ sam_hc_callback_register.3 \
+ sam_hc_send.3 \
+ sam_initialize.3 \
+ sam_mark_failed.3 \
+ sam_register.3 \
+ sam_start.3 \
+ sam_stop.3 \
+ sam_warn_signal_set.3 \
+ cmap_context_get.3 \
+ cmap_dec.3 \
+ cmap_iter_init.3 \
+ cmap_get.3 \
+ cmap_inc.3 \
+ cmap_set.3 \
+ cmap_iter_next.3 \
+ cmap_delete.3 \
+ cmap_iter_finalize.3 \
+ cmap_finalize.3 \
+ cmap_dispatch.3 \
+ cmap_initialize.3 \
+ cmap_initialize_map.3 \
+ cmap_track_add.3 \
+ cmap_context_set.3 \
+ cmap_fd_get.3 \
+ cmap_track_delete.3
+
+autogen_common = ipc_common.sh.errors
+EXTRA_DIST = $(INDEX_HTML) \
+ $(xml_man) \
+ $(corosync_vqsim_man) \
+ $(autogen_man:%=%.in) \
+ $(autogen_common)
+
+man_MANS = $(autogen_man)
+dist_man_MANS = corosync.conf.5 votequorum.5 corosync.8 \
+ corosync-cmapctl.8 corosync-blackbox.8 corosync-keygen.8 \
+ corosync-cfgtool.8 corosync-cpgtool.8 corosync-notifyd.8 \
+ corosync-quorumtool.8 corosync_overview.7 cpg_overview.3 \
+ quorum_overview.3 votequorum_overview.3 sam_overview.3 \
+ cmap_overview.3 cmap_keys.7 $(am__append_1) $(am__append_2)
+HTML_DOCS = $(dist_man_MANS:%=%.html) $(man_MANS:%=%.html)
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign man/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign man/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+install-man3: $(dist_man_MANS) $(man_MANS)
+ @$(NORMAL_INSTALL)
+ @list1=''; \
+ list2='$(dist_man_MANS) $(man_MANS)'; \
+ test -n "$(man3dir)" \
+ && test -n "`echo $$list1$$list2`" \
+ || exit 0; \
+ echo " $(MKDIR_P) '$(DESTDIR)$(man3dir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(man3dir)" || exit 1; \
+ { for i in $$list1; do echo "$$i"; done; \
+ if test -n "$$list2"; then \
+ for i in $$list2; do echo "$$i"; done \
+ | sed -n '/\.3[a-z]*$$/p'; \
+ fi; \
+ } | while read p; do \
+ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; echo "$$p"; \
+ done | \
+ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^3][0-9a-z]*$$,3,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
+ sed 'N;N;s,\n, ,g' | { \
+ list=; while read file base inst; do \
+ if test "$$base" = "$$inst"; then list="$$list $$file"; else \
+ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man3dir)/$$inst'"; \
+ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man3dir)/$$inst" || exit $$?; \
+ fi; \
+ done; \
+ for i in $$list; do echo "$$i"; done | $(am__base_list) | \
+ while read files; do \
+ test -z "$$files" || { \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man3dir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(man3dir)" || exit $$?; }; \
+ done; }
+
+uninstall-man3:
+ @$(NORMAL_UNINSTALL)
+ @list=''; test -n "$(man3dir)" || exit 0; \
+ files=`{ for i in $$list; do echo "$$i"; done; \
+ l2='$(dist_man_MANS) $(man_MANS)'; for i in $$l2; do echo "$$i"; done | \
+ sed -n '/\.3[a-z]*$$/p'; \
+ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^3][0-9a-z]*$$,3,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
+ dir='$(DESTDIR)$(man3dir)'; $(am__uninstall_files_from_dir)
+install-man5: $(dist_man_MANS) $(man_MANS)
+ @$(NORMAL_INSTALL)
+ @list1=''; \
+ list2='$(dist_man_MANS) $(man_MANS)'; \
+ test -n "$(man5dir)" \
+ && test -n "`echo $$list1$$list2`" \
+ || exit 0; \
+ echo " $(MKDIR_P) '$(DESTDIR)$(man5dir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(man5dir)" || exit 1; \
+ { for i in $$list1; do echo "$$i"; done; \
+ if test -n "$$list2"; then \
+ for i in $$list2; do echo "$$i"; done \
+ | sed -n '/\.5[a-z]*$$/p'; \
+ fi; \
+ } | while read p; do \
+ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; echo "$$p"; \
+ done | \
+ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^5][0-9a-z]*$$,5,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
+ sed 'N;N;s,\n, ,g' | { \
+ list=; while read file base inst; do \
+ if test "$$base" = "$$inst"; then list="$$list $$file"; else \
+ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man5dir)/$$inst'"; \
+ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man5dir)/$$inst" || exit $$?; \
+ fi; \
+ done; \
+ for i in $$list; do echo "$$i"; done | $(am__base_list) | \
+ while read files; do \
+ test -z "$$files" || { \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man5dir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(man5dir)" || exit $$?; }; \
+ done; }
+
+uninstall-man5:
+ @$(NORMAL_UNINSTALL)
+ @list=''; test -n "$(man5dir)" || exit 0; \
+ files=`{ for i in $$list; do echo "$$i"; done; \
+ l2='$(dist_man_MANS) $(man_MANS)'; for i in $$l2; do echo "$$i"; done | \
+ sed -n '/\.5[a-z]*$$/p'; \
+ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^5][0-9a-z]*$$,5,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
+ dir='$(DESTDIR)$(man5dir)'; $(am__uninstall_files_from_dir)
+install-man7: $(dist_man_MANS) $(man_MANS)
+ @$(NORMAL_INSTALL)
+ @list1=''; \
+ list2='$(dist_man_MANS) $(man_MANS)'; \
+ test -n "$(man7dir)" \
+ && test -n "`echo $$list1$$list2`" \
+ || exit 0; \
+ echo " $(MKDIR_P) '$(DESTDIR)$(man7dir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(man7dir)" || exit 1; \
+ { for i in $$list1; do echo "$$i"; done; \
+ if test -n "$$list2"; then \
+ for i in $$list2; do echo "$$i"; done \
+ | sed -n '/\.7[a-z]*$$/p'; \
+ fi; \
+ } | while read p; do \
+ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; echo "$$p"; \
+ done | \
+ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^7][0-9a-z]*$$,7,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
+ sed 'N;N;s,\n, ,g' | { \
+ list=; while read file base inst; do \
+ if test "$$base" = "$$inst"; then list="$$list $$file"; else \
+ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man7dir)/$$inst'"; \
+ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man7dir)/$$inst" || exit $$?; \
+ fi; \
+ done; \
+ for i in $$list; do echo "$$i"; done | $(am__base_list) | \
+ while read files; do \
+ test -z "$$files" || { \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man7dir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(man7dir)" || exit $$?; }; \
+ done; }
+
+uninstall-man7:
+ @$(NORMAL_UNINSTALL)
+ @list=''; test -n "$(man7dir)" || exit 0; \
+ files=`{ for i in $$list; do echo "$$i"; done; \
+ l2='$(dist_man_MANS) $(man_MANS)'; for i in $$l2; do echo "$$i"; done | \
+ sed -n '/\.7[a-z]*$$/p'; \
+ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^7][0-9a-z]*$$,7,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
+ dir='$(DESTDIR)$(man7dir)'; $(am__uninstall_files_from_dir)
+install-man8: $(dist_man_MANS) $(man_MANS)
+ @$(NORMAL_INSTALL)
+ @list1=''; \
+ list2='$(dist_man_MANS) $(man_MANS)'; \
+ test -n "$(man8dir)" \
+ && test -n "`echo $$list1$$list2`" \
+ || exit 0; \
+ echo " $(MKDIR_P) '$(DESTDIR)$(man8dir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(man8dir)" || exit 1; \
+ { for i in $$list1; do echo "$$i"; done; \
+ if test -n "$$list2"; then \
+ for i in $$list2; do echo "$$i"; done \
+ | sed -n '/\.8[a-z]*$$/p'; \
+ fi; \
+ } | while read p; do \
+ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; echo "$$p"; \
+ done | \
+ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
+ sed 'N;N;s,\n, ,g' | { \
+ list=; while read file base inst; do \
+ if test "$$base" = "$$inst"; then list="$$list $$file"; else \
+ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man8dir)/$$inst'"; \
+ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man8dir)/$$inst" || exit $$?; \
+ fi; \
+ done; \
+ for i in $$list; do echo "$$i"; done | $(am__base_list) | \
+ while read files; do \
+ test -z "$$files" || { \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man8dir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(man8dir)" || exit $$?; }; \
+ done; }
+
+uninstall-man8:
+ @$(NORMAL_UNINSTALL)
+ @list=''; test -n "$(man8dir)" || exit 0; \
+ files=`{ for i in $$list; do echo "$$i"; done; \
+ l2='$(dist_man_MANS) $(man_MANS)'; for i in $$l2; do echo "$$i"; done | \
+ sed -n '/\.8[a-z]*$$/p'; \
+ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
+ dir='$(DESTDIR)$(man8dir)'; $(am__uninstall_files_from_dir)
+tags TAGS:
+
+ctags CTAGS:
+
+cscope cscopelist:
+
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+@BUILD_HTML_DOCS_FALSE@all-local:
+all-am: Makefile $(MANS) all-local
+installdirs:
+ for dir in "$(DESTDIR)$(man3dir)" "$(DESTDIR)$(man5dir)" "$(DESTDIR)$(man7dir)" "$(DESTDIR)$(man8dir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+ -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+@BUILD_HTML_DOCS_FALSE@uninstall-local:
+@BUILD_HTML_DOCS_FALSE@install-data-local:
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-local mostlyclean-am
+
+distclean: distclean-am
+ -rm -f Makefile
+distclean-am: clean-am distclean-generic
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-data-local install-man
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man: install-man3 install-man5 install-man7 install-man8
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-local uninstall-man
+
+uninstall-man: uninstall-man3 uninstall-man5 uninstall-man7 \
+ uninstall-man8
+
+.MAKE: install-am install-strip
+
+.PHONY: all all-am all-local check check-am clean clean-generic \
+ clean-libtool clean-local cscopelist-am ctags-am distclean \
+ distclean-generic distclean-libtool distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-data-local install-dvi install-dvi-am \
+ install-exec install-exec-am install-html install-html-am \
+ install-info install-info-am install-man install-man3 \
+ install-man5 install-man7 install-man8 install-pdf \
+ install-pdf-am install-ps install-ps-am install-strip \
+ installcheck installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-generic \
+ mostlyclean-libtool pdf pdf-am ps ps-am tags-am uninstall \
+ uninstall-am uninstall-local uninstall-man uninstall-man3 \
+ uninstall-man5 uninstall-man7 uninstall-man8
+
+
+# developer man page generation
+%.3: %.3.in $(autogen_common)
+ @echo Generating $@ man page && \
+ rm -f $@-t-t $@-t $@ && \
+ DATE_FMT="%Y-%m-%d" && \
+ SOURCE_DATE_EPOCH="$${SOURCE_DATE_EPOCH:-$$(date +%s)}" && \
+ date="$$(date -u -d "@$$SOURCE_DATE_EPOCH" "+$$DATE_FMT" 2>/dev/null || date -u -r "$$SOURCE_DATE_EPOCH" "+$$DATE_FMT" 2>/dev/null || date -u "+$$DATE_FMT")" && \
+ $(AWK) "{print}(\$$1 ~ /@COMMONIPCERRORS@/){exit 0}" ${top_srcdir}/man/$@.in > $@-t-t && \
+ cat ${top_srcdir}/man/$(autogen_common) >> $@-t-t && \
+ $(AWK) -v p=0 "(\$$1 ~ /@COMMONIPCERRORS@/){p = 1} {if(p==1)print}" ${top_srcdir}/man/$@.in >> $@-t-t && \
+ cat $@-t-t | \
+ $(SED) -e 's#@BUILDDATE@#'$$date'#g' \
+ -e 's#@COMMONIPCERRORS@##g' \
+ > $@-t && \
+ rm -f $@-t-t && \
+ mv $@-t $@
+
+clean-local:
+ rm -rf $(HTML_DOCS) $(autogen_man)
+
+@BUILD_HTML_DOCS_TRUE@%.html: %
+@BUILD_HTML_DOCS_TRUE@ $(GROFF) -mandoc -Thtml $^ > $@
+
+@BUILD_HTML_DOCS_TRUE@install-data-local:
+@BUILD_HTML_DOCS_TRUE@ $(INSTALL) -d $(DESTDIR)/${docdir}/html
+@BUILD_HTML_DOCS_TRUE@ $(INSTALL) -m 644 ${srcdir}/$(INDEX_HTML) $(HTML_DOCS) $(DESTDIR)/${docdir}/html/
+
+@BUILD_HTML_DOCS_TRUE@uninstall-local:
+@BUILD_HTML_DOCS_TRUE@ cd $(DESTDIR)/${docdir}/html && rm -f $(INDEX_HTML) $(HTML_DOCS)
+@BUILD_HTML_DOCS_TRUE@ rmdir $(DESTDIR)/${docdir}/html 2> /dev/null || :
+
+@BUILD_HTML_DOCS_TRUE@all-local: $(HTML_DOCS)
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/man/cmap_context_get.3.in b/man/cmap_context_get.3.in
new file mode 100644
index 0000000..8f257b5
--- /dev/null
+++ b/man/cmap_context_get.3.in
@@ -0,0 +1,58 @@
+.\"/*
+.\" * Copyright (c) 2012 Red Hat, Inc.
+.\" *
+.\" * All rights reserved.
+.\" *
+.\" * Author: Jan Friesse (jfriesse@redhat.com)
+.\" *
+.\" * This software licensed under BSD license, the text of which follows:
+.\" *
+.\" * Redistribution and use in source and binary forms, with or without
+.\" * modification, are permitted provided that the following conditions are met:
+.\" *
+.\" * - Redistributions of source code must retain the above copyright notice,
+.\" * this list of conditions and the following disclaimer.
+.\" * - Redistributions in binary form must reproduce the above copyright notice,
+.\" * this list of conditions and the following disclaimer in the documentation
+.\" * and/or other materials provided with the distribution.
+.\" * - Neither the name of the Red Hat, Inc. nor the names of its
+.\" * contributors may be used to endorse or promote products derived from this
+.\" * software without specific prior written permission.
+.\" *
+.\" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+.\" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+.\" * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+.\" * THE POSSIBILITY OF SUCH DAMAGE.
+.\" */
+.TH "CMAP_CONTEXT_GET" 3 "23/01/2012" "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
+
+.SH NAME
+.P
+cmap_context_get \- Gets the context variable for a CMAP instance
+
+.SH SYNOPSIS
+.P
+\fB#include <corosync/cmap.h>\fR
+
+.P
+\fBcs_error_t
+cmap_context_get (cmap_handle_t \fIhandle\fB, const void **\fIcontext\fB);\fR
+
+.SH DESCRIPTION
+.P
+The \fBcmap_context_get\fR function is used to retrieve the context variable previously stored using
+.B cmap_context_set(3).
+
+.SH RETURN VALUE
+This call returns the CS_OK value if successful, otherwise an error is returned.
+
+.SH "SEE ALSO"
+.BR cmap_context_set (3),
+.BR cmap_overview (3)
diff --git a/man/cmap_context_set.3.in b/man/cmap_context_set.3.in
new file mode 100644
index 0000000..734ef0a
--- /dev/null
+++ b/man/cmap_context_set.3.in
@@ -0,0 +1,60 @@
+.\"/*
+.\" * Copyright (c) 2012 Red Hat, Inc.
+.\" *
+.\" * All rights reserved.
+.\" *
+.\" * Author: Jan Friesse (jfriesse@redhat.com)
+.\" *
+.\" * This software licensed under BSD license, the text of which follows:
+.\" *
+.\" * Redistribution and use in source and binary forms, with or without
+.\" * modification, are permitted provided that the following conditions are met:
+.\" *
+.\" * - Redistributions of source code must retain the above copyright notice,
+.\" * this list of conditions and the following disclaimer.
+.\" * - Redistributions in binary form must reproduce the above copyright notice,
+.\" * this list of conditions and the following disclaimer in the documentation
+.\" * and/or other materials provided with the distribution.
+.\" * - Neither the name of the Red Hat, Inc. nor the names of its
+.\" * contributors may be used to endorse or promote products derived from this
+.\" * software without specific prior written permission.
+.\" *
+.\" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+.\" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+.\" * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+.\" * THE POSSIBILITY OF SUCH DAMAGE.
+.\" */
+.TH "CMAP_CONTEXT_SET" 3 "23/01/2012" "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
+
+.SH NAME
+.P
+cmap_context_set \- Sets the context variable for a CMAP instance
+
+.SH SYNOPSIS
+.P
+\fB#include <corosync/cmap.h>\fR
+
+.P
+\fBcs_error_t
+cmap_context_set (cmap_handle_t \fIhandle\fB, const void *\fIcontext\fB);\fR
+
+.SH DESCRIPTION
+.P
+The \fBcmap_context_set\fR function is used to store the context variable for cmap instance.
+It has no meaning inside libcmap itself and will not be touched by the library. It can
+be retrieved using
+.B cmap_context_get(3).
+
+.SH RETURN VALUE
+This call returns the CS_OK value if successful, otherwise an error is returned.
+
+.SH "SEE ALSO"
+.BR cmap_context_get (3),
+.BR cmap_overview (3)
diff --git a/man/cmap_dec.3.in b/man/cmap_dec.3.in
new file mode 100644
index 0000000..83612cb
--- /dev/null
+++ b/man/cmap_dec.3.in
@@ -0,0 +1,92 @@
+.\"/*
+.\" * Copyright (c) 2012 Red Hat, Inc.
+.\" *
+.\" * All rights reserved.
+.\" *
+.\" * Author: Jan Friesse (jfriesse@redhat.com)
+.\" *
+.\" * This software licensed under BSD license, the text of which follows:
+.\" *
+.\" * Redistribution and use in source and binary forms, with or without
+.\" * modification, are permitted provided that the following conditions are met:
+.\" *
+.\" * - Redistributions of source code must retain the above copyright notice,
+.\" * this list of conditions and the following disclaimer.
+.\" * - Redistributions in binary form must reproduce the above copyright notice,
+.\" * this list of conditions and the following disclaimer in the documentation
+.\" * and/or other materials provided with the distribution.
+.\" * - Neither the name of the Red Hat, Inc. nor the names of its
+.\" * contributors may be used to endorse or promote products derived from this
+.\" * software without specific prior written permission.
+.\" *
+.\" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+.\" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+.\" * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+.\" * THE POSSIBILITY OF SUCH DAMAGE.
+.\" */
+.TH "CMAP_DEC" 3 "03/02/2012" "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
+
+.SH NAME
+.P
+cmap_inc \- Decrease already stored value in CMAP
+
+.SH SYNOPSIS
+.P
+\fB#include <corosync/cmap.h>\fR
+
+.P
+\fBcs_error_t
+cmap_dec (cmap_handle_t \fIhandle\fB, const char *\fIkey_name\fB);\fR
+
+.SH DESCRIPTION
+.P
+The
+.B cmap_dec
+function is used to decrease integer value of already stored key inside cmap. The
+.I handle
+argument is connection to CMAP database obtained by calling
+.B cmap_initialize(3)
+function.
+.I key_name
+is name of key to increase value of.
+
+Function is defined only on values where increase makes sense and is well defined,
+so it can be one of:
+.PP
+\fBCMAP_VALUETYPE_INT8\fR - 8-bit signed integer
+.PP
+\fBCMAP_VALUETYPE_UINT8\fR - 8-bit unsigned integer
+.PP
+\fBCMAP_VALUETYPE_INT16\fR - 16-bit signed integer
+.PP
+\fBCMAP_VALUETYPE_UINT16\fR - 16-bit unsigned integer
+.PP
+\fBCMAP_VALUETYPE_INT32\fR - 32-bit signed integer
+.PP
+\fBCMAP_VALUETYPE_UINT32\fR - 32-bit unsigned integer
+.PP
+\fBCMAP_VALUETYPE_INT64\fR - 64-bit signed integer
+.PP
+\fBCMAP_VALUETYPE_UINT64\fR - 64-bit unsigned integer
+
+Overflow/underflow is not detected and it's ignored.
+
+.SH RETURN VALUE
+This call returns the CS_OK value if successful. If value or key_name are unspecified, CS_ERR_INVALID_PARAM
+is returned. CS_ERR_NOT_EXIST error is returned if key doesn't exist (wasn't created by calling
+.B cmap_set(3)
+first). Some of keys may be tagged read-only directly in corosync and setting such key will result in
+CS_ERR_ACCESS error.
+
+.SH "SEE ALSO"
+.BR cmap_get (3),
+.BR cmap_set (3),
+.BR cmap_initialize (3),
+.BR cmap_overview (3)
diff --git a/man/cmap_delete.3.in b/man/cmap_delete.3.in
new file mode 100644
index 0000000..c99f00f
--- /dev/null
+++ b/man/cmap_delete.3.in
@@ -0,0 +1,70 @@
+.\"/*
+.\" * Copyright (c) 2012 Red Hat, Inc.
+.\" *
+.\" * All rights reserved.
+.\" *
+.\" * Author: Jan Friesse (jfriesse@redhat.com)
+.\" *
+.\" * This software licensed under BSD license, the text of which follows:
+.\" *
+.\" * Redistribution and use in source and binary forms, with or without
+.\" * modification, are permitted provided that the following conditions are met:
+.\" *
+.\" * - Redistributions of source code must retain the above copyright notice,
+.\" * this list of conditions and the following disclaimer.
+.\" * - Redistributions in binary form must reproduce the above copyright notice,
+.\" * this list of conditions and the following disclaimer in the documentation
+.\" * and/or other materials provided with the distribution.
+.\" * - Neither the name of the Red Hat, Inc. nor the names of its
+.\" * contributors may be used to endorse or promote products derived from this
+.\" * software without specific prior written permission.
+.\" *
+.\" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+.\" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+.\" * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+.\" * THE POSSIBILITY OF SUCH DAMAGE.
+.\" */
+.TH "CMAP_DELETE" 3 "03/02/2012" "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
+
+.SH NAME
+.P
+cmap_delete \- Delete key/value pair from the CMAP service
+
+.SH SYNOPSIS
+.P
+\fB#include <corosync/cmap.h>\fR
+
+.P
+\fBcs_error_t
+cmap_delete(cmap_handle_t \fIhandle\fB, const char *\fIkey_name\fB);\fR
+
+.SH DESCRIPTION
+.P
+The
+.B cmap_delete
+function is used to delete key from cmap. Key must be previously created by
+.B cmap_set(3)
+function. The
+.I handle
+argument is connection to CMAP database obtained by calling
+.B cmap_initialize(3)
+function.
+.I key_name
+is name of key to delete.
+
+.SH RETURN VALUE
+This call returns the CS_OK value if successful. If key_name is unspecified, CS_ERR_INVALID_PARAM
+is returned. For nonexisting keys, CS_ERR_NOT_EXIST error is returned. Some of keys may be tagged
+read-only directly in corosync and deleting such key will result in CS_ERR_ACCESS error.
+
+.SH "SEE ALSO"
+.BR cmap_initialize (3),
+.BR cmap_set (3),
+.BR cmap_overview (3)
diff --git a/man/cmap_dispatch.3.in b/man/cmap_dispatch.3.in
new file mode 100644
index 0000000..d87e780
--- /dev/null
+++ b/man/cmap_dispatch.3.in
@@ -0,0 +1,91 @@
+.\"/*
+.\" * Copyright (c) 2012 Red Hat, Inc.
+.\" *
+.\" * All rights reserved.
+.\" *
+.\" * Author: Jan Friesse (jfriesse@redhat.com)
+.\" *
+.\" * This software licensed under BSD license, the text of which follows:
+.\" *
+.\" * Redistribution and use in source and binary forms, with or without
+.\" * modification, are permitted provided that the following conditions are met:
+.\" *
+.\" * - Redistributions of source code must retain the above copyright notice,
+.\" * this list of conditions and the following disclaimer.
+.\" * - Redistributions in binary form must reproduce the above copyright notice,
+.\" * this list of conditions and the following disclaimer in the documentation
+.\" * and/or other materials provided with the distribution.
+.\" * - Neither the name of the Red Hat, Inc. nor the names of its
+.\" * contributors may be used to endorse or promote products derived from this
+.\" * software without specific prior written permission.
+.\" *
+.\" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+.\" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+.\" * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+.\" * THE POSSIBILITY OF SUCH DAMAGE.
+.\" */
+.TH "CMAP_DISPATCH" 3 "23/01/2012" "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
+
+.SH NAME
+.P
+cmap_dispatch \- Dispatches callbacks from the CMAP service
+
+.SH SYNOPSIS
+.P
+\fB#include <corosync/cmap.h>\fR
+
+.P
+\fBcs_error_t
+cmap_dispatch (cmap_handle_t \fIhandle\fB, cs_dispatch_flags_t \fIdispatch_types\fB);\fR
+
+.SH DESCRIPTION
+The
+.B cmap_dispatch
+function is used to dispatch configuration changes.
+.PP
+Each application may have several connections to the CMAP API. Each application
+uses the
+.I handle
+argument to uniquely identify the connection.
+.PP
+The
+.I dispatch_types
+argument is used to identify the type of dispatch to execute. The possible types are
+CS_DISPATCH_ONE, CS_DISPATCH_ALL and CS_DISPATCH_BLOCKING.
+
+The dispatch values have the following meanings:
+.TP
+.B CS_DISPATCH_ONE
+Dispatch at least one callback, blocking until the callback is dispatched.
+.TP
+.B CS_DISPATCH_ALL
+Dispatch all waiting callbacks without blocking to wait for any callbacks.
+.TP
+.B CS_DISPATCH_BLOCKING
+Dispatch all callbacks blocking indefinitely. This is used in a threaded
+program where a thread is created, and then cs_dispatch() is called immediately
+from the created thread to execute callbacks.
+.TP
+.B CS_DISPATCH_ONE_NONBLOCKING
+Dispatch at most one callback. If there is no pending callback,
+CS_ERR_TRY_AGAIN is returned.
+.PP
+It's needed to call
+.B cmap_track_add(3)
+to add tracked items and receive callbacks.
+
+.SH RETURN VALUE
+.P
+This call returns the CS_OK value if successful, otherwise an error is returned.
+
+.SH "SEE ALSO"
+.BR cmap_track_add (3),
+.BR cmap_track_delete (3),
+.BR cmap_overview (3)
diff --git a/man/cmap_fd_get.3.in b/man/cmap_fd_get.3.in
new file mode 100644
index 0000000..5af419a
--- /dev/null
+++ b/man/cmap_fd_get.3.in
@@ -0,0 +1,67 @@
+.\"/*
+.\" * Copyright (c) 2012 Red Hat, Inc.
+.\" *
+.\" * All rights reserved.
+.\" *
+.\" * Author: Jan Friesse (jfriesse@redhat.com)
+.\" *
+.\" * This software licensed under BSD license, the text of which follows:
+.\" *
+.\" * Redistribution and use in source and binary forms, with or without
+.\" * modification, are permitted provided that the following conditions are met:
+.\" *
+.\" * - Redistributions of source code must retain the above copyright notice,
+.\" * this list of conditions and the following disclaimer.
+.\" * - Redistributions in binary form must reproduce the above copyright notice,
+.\" * this list of conditions and the following disclaimer in the documentation
+.\" * and/or other materials provided with the distribution.
+.\" * - Neither the name of the Red Hat, Inc. nor the names of its
+.\" * contributors may be used to endorse or promote products derived from this
+.\" * software without specific prior written permission.
+.\" *
+.\" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+.\" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+.\" * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+.\" * THE POSSIBILITY OF SUCH DAMAGE.
+.\" */
+.TH "CMAP_FD_GET" 3 "23/01/2012" "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
+
+.SH NAME
+.P
+cmap_fd_get \- Dispatches callbacks from the CMAP service
+
+.SH SYNOPSIS
+.P
+\fB#include <corosync/cmap.h>\fR
+
+.P
+\fBcs_error_t
+cmap_fd_get (cmap_handle_t \fIhandle\fB, int *\fIfd\fB);\fR
+
+.SH DESCRIPTION
+.P
+The
+.B cmap_fd_get
+function is used to retrieve the file descriptor that may be used with the poll
+system call to determine when
+.B cmap_dispatch(3)
+won't block. The
+.I handle
+argument may not be used directly with
+.B poll
+because it is not the file descriptor, but instead an internal identifier used
+by the CMAP library.
+
+.SH RETURN VALUE
+This call returns the CS_OK value if successful, otherwise an error is returned.
+
+.SH "SEE ALSO"
+.BR cmap_dispatch (3),
+.BR cmap_overview (3)
diff --git a/man/cmap_finalize.3.in b/man/cmap_finalize.3.in
new file mode 100644
index 0000000..4d580fc
--- /dev/null
+++ b/man/cmap_finalize.3.in
@@ -0,0 +1,61 @@
+.\"/*
+.\" * Copyright (c) 2012 Red Hat, Inc.
+.\" *
+.\" * All rights reserved.
+.\" *
+.\" * Author: Jan Friesse (jfriesse@redhat.com)
+.\" *
+.\" * This software licensed under BSD license, the text of which follows:
+.\" *
+.\" * Redistribution and use in source and binary forms, with or without
+.\" * modification, are permitted provided that the following conditions are met:
+.\" *
+.\" * - Redistributions of source code must retain the above copyright notice,
+.\" * this list of conditions and the following disclaimer.
+.\" * - Redistributions in binary form must reproduce the above copyright notice,
+.\" * this list of conditions and the following disclaimer in the documentation
+.\" * and/or other materials provided with the distribution.
+.\" * - Neither the name of the Red Hat, Inc. nor the names of its
+.\" * contributors may be used to endorse or promote products derived from this
+.\" * software without specific prior written permission.
+.\" *
+.\" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+.\" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+.\" * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+.\" * THE POSSIBILITY OF SUCH DAMAGE.
+.\" */
+.TH "CMAP_FINALIZE" 3 "20/01/2012" "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
+
+.SH NAME
+.P
+cmap_finalize \- Finalize connection to CMAP
+
+.SH SYNOPSIS
+.P
+\fB#include <corosync/cmap.h>\fR
+
+.P
+\fBcs_error_t cmap_finalize (cmap_handle_t \fIhandle\fB);\fR
+
+.SH DESCRIPTION
+.P
+The \fBcmap_finalize\fR function is used to to close a connection to the
+CMAP API. Once the connection is finalized, the handle may not be
+used again by applications. No more callbacks will be dispatched from the
+.B cmap_dispatch
+function.
+.SH RETURN VALUE
+This call returns the CS_OK value if successful, otherwise an error is returned.
+CS_ERR_BAD_HANDLE error is returned when handle is invalid.
+
+.SH "SEE ALSO"
+.BR cmap_initialize (3),
+.BR cmap_dispatch (3),
+.BR cmap_overview (3)
diff --git a/man/cmap_get.3.in b/man/cmap_get.3.in
new file mode 100644
index 0000000..939bf86
--- /dev/null
+++ b/man/cmap_get.3.in
@@ -0,0 +1,153 @@
+.\"/*
+.\" * Copyright (c) 2012 Red Hat, Inc.
+.\" *
+.\" * All rights reserved.
+.\" *
+.\" * Author: Jan Friesse (jfriesse@redhat.com)
+.\" *
+.\" * This software licensed under BSD license, the text of which follows:
+.\" *
+.\" * Redistribution and use in source and binary forms, with or without
+.\" * modification, are permitted provided that the following conditions are met:
+.\" *
+.\" * - Redistributions of source code must retain the above copyright notice,
+.\" * this list of conditions and the following disclaimer.
+.\" * - Redistributions in binary form must reproduce the above copyright notice,
+.\" * this list of conditions and the following disclaimer in the documentation
+.\" * and/or other materials provided with the distribution.
+.\" * - Neither the name of the Red Hat, Inc. nor the names of its
+.\" * contributors may be used to endorse or promote products derived from this
+.\" * software without specific prior written permission.
+.\" *
+.\" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+.\" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+.\" * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+.\" * THE POSSIBILITY OF SUCH DAMAGE.
+.\" */
+.TH "CMAP_GET" 3 "03/02/2012" "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
+
+.SH NAME
+.P
+cmap_get \- Retrieve value from CMAP
+
+.SH SYNOPSIS
+.P
+\fB#include <corosync/cmap.h>\fR
+
+.P
+\fBcs_error_t
+cmap_get (cmap_handle_t \fIhandle\fB, const char *\fIkey_name\fB, void *\fIvalue\fB,
+size_t *\fIvalue_len\fB, cmap_value_types_t *\fItype\fB);\fR
+.P
+Also shortcuts for different types are defined
+.P
+\fBcs_error_t cmap_get_int8 (cmap_handle_t \fIhandle\fB, const char *\fIkey_name\fB, int8_t *\fIi8\fB);\fR
+.P
+\fBcs_error_t cmap_get_uint8 (cmap_handle_t \fIhandle\fB, const char *\fIkey_name\fB, uint8_t *\fIu8\fB);\fR
+.P
+\fBcs_error_t cmap_get_int16 (cmap_handle_t \fIhandle\fB, const char *\fIkey_name\fB, int16_t *\fIi16\fB);\fR
+.P
+\fBcs_error_t cmap_get_uint16 (cmap_handle_t \fIhandle\fB, const char *\fIkey_name\fB, uint16_t *\fIu16\fB);\fR
+.P
+\fBcs_error_t cmap_get_int32 (cmap_handle_t \fIhandle\fB, const char *\fIkey_name\fB, int32_t *\fIi32\fB);\fR
+.P
+\fBcs_error_t cmap_get_uint32 (cmap_handle_t \fIhandle\fB, const char *\fIkey_name\fB, uint32_t *\fIu32\fB);\fR
+.P
+\fBcs_error_t cmap_get_int64 (cmap_handle_t \fIhandle\fB, const char *\fIkey_name\fB, int64_t *\fIi64\fB);\fR
+.P
+\fBcs_error_t cmap_get_uint64 (cmap_handle_t \fIhandle\fB, const char *\fIkey_name\fB, uint64_t *\fIu64\fB);\fR
+.P
+\fBcs_error_t cmap_get_float (cmap_handle_t \fIhandle\fB, const char *\fIkey_name\fB, float *\fIflt\fB);\fR
+.P
+\fBcs_error_t cmap_get_double (cmap_handle_t \fIhandle\fB, const char *\fIkey_name\fB, double *\fIdbl\fB);\fR
+.P
+\fBcs_error_t cmap_get_string (cmap_handle_t \fIhandle\fB, const char *\fIkey_name\fB, char **\fIstr\fB);\fR
+
+.SH DESCRIPTION
+.P
+The
+.B cmap_get
+function is used to retrieve key from cmap previously set by
+.B cmap_set(3)
+function. The
+.I handle
+argument is connection to CMAP database obtained by calling
+.B cmap_initialize(3)
+function.
+.I key_name
+is name of key to get value from.
+.I value
+is pointer to preallocated data used as storage for data, but can be also NULL, and then only
+.I value_len
+and/or
+.I type
+is returned (both of them can also be NULL, allowing function to be used only for test of existence of key).
+If
+.I value
+is not NULL, actual length of value in map is checked against
+.I *value_len.
+If
+.I *value_len
+is shorter then length of value in map, error CS_ERR_INVALID_PARAM is returned. After successful copy of
+value,
+.I *value_len
+is set to actual length of value in map. Parameter
+.I type
+is pointer to memory, where type of value is stored after successful return. Pointer can also be NULL and
+then nothing is stored. Type can be one of:
+.PP
+\fBCMAP_VALUETYPE_INT8\fR - 8-bit signed integer
+.PP
+\fBCMAP_VALUETYPE_UINT8\fR - 8-bit unsigned integer
+.PP
+\fBCMAP_VALUETYPE_INT16\fR - 16-bit signed integer
+.PP
+\fBCMAP_VALUETYPE_UINT16\fR - 16-bit unsigned integer
+.PP
+\fBCMAP_VALUETYPE_INT32\fR - 32-bit signed integer
+.PP
+\fBCMAP_VALUETYPE_UINT32\fR - 32-bit unsigned integer
+.PP
+\fBCMAP_VALUETYPE_INT64\fR - 64-bit signed integer
+.PP
+\fBCMAP_VALUETYPE_UINT64\fR - 64-bit unsigned integer
+.PP
+\fBCMAP_VALUETYPE_FLOAT\fR - Float value
+.PP
+\fBCMAP_VALUETYPE_DOUBLE\fR - Double value
+.PP
+\fBCMAP_VALUETYPE_STRING\fR - C-style string
+.PP
+\fBCMAP_VALUETYPE_BINARY\fR - Binary data, byte with zero value has no special meaning
+
+Shortcut functions tests cmap type with it's own type. If type didn't match, CS_ERR_INVALID_PARAM error
+is returned. No conversions are done, so for example
+.B cmap_get_int16
+is not able to return value with
+.B CMAP_VALUETYPE_INT8
+type.
+
+String shortcut function returns newly allocated memory and caller is responsible for freeing that.
+
+.SH RETURN VALUE
+This call returns the CS_OK value if successful. If value or key_name are unspecified, CS_ERR_INVALID_PARAM
+is returned. Same error is also returned if
+.I value
+is specified, and
+.I *value_len
+is too short for store of data. If key doesn't exists (it was not set by calling
+.B cmap_set(3)
+function first) CS_ERR_NOT_EXIST error is returned. For helper functions,
+CS_ERR_INVALID_PARAM is returned if type stored in cmap doesn't match with type of helper function.
+
+.SH "SEE ALSO"
+.BR cmap_set (3),
+.BR cmap_initialize (3),
+.BR cmap_overview (3)
diff --git a/man/cmap_inc.3.in b/man/cmap_inc.3.in
new file mode 100644
index 0000000..06e733a
--- /dev/null
+++ b/man/cmap_inc.3.in
@@ -0,0 +1,92 @@
+.\"/*
+.\" * Copyright (c) 2012 Red Hat, Inc.
+.\" *
+.\" * All rights reserved.
+.\" *
+.\" * Author: Jan Friesse (jfriesse@redhat.com)
+.\" *
+.\" * This software licensed under BSD license, the text of which follows:
+.\" *
+.\" * Redistribution and use in source and binary forms, with or without
+.\" * modification, are permitted provided that the following conditions are met:
+.\" *
+.\" * - Redistributions of source code must retain the above copyright notice,
+.\" * this list of conditions and the following disclaimer.
+.\" * - Redistributions in binary form must reproduce the above copyright notice,
+.\" * this list of conditions and the following disclaimer in the documentation
+.\" * and/or other materials provided with the distribution.
+.\" * - Neither the name of the Red Hat, Inc. nor the names of its
+.\" * contributors may be used to endorse or promote products derived from this
+.\" * software without specific prior written permission.
+.\" *
+.\" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+.\" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+.\" * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+.\" * THE POSSIBILITY OF SUCH DAMAGE.
+.\" */
+.TH "CMAP_INC" 3 "03/02/2012" "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
+
+.SH NAME
+.P
+cmap_inc \- Increase already stored value in CMAP
+
+.SH SYNOPSIS
+.P
+\fB#include <corosync/cmap.h>\fR
+
+.P
+\fBcs_error_t
+cmap_inc (cmap_handle_t \fIhandle\fB, const char *\fIkey_name\fB);\fR
+
+.SH DESCRIPTION
+.P
+The
+.B cmap_inc
+function is used to increase integer value of already stored key inside cmap. The
+.I handle
+argument is connection to CMAP database obtained by calling
+.B cmap_initialize(3)
+function.
+.I key_name
+is name of key to increase value of.
+
+Function is defined only on values where increase makes sense and is well defined,
+so it can be one of:
+.PP
+\fBCMAP_VALUETYPE_INT8\fR - 8-bit signed integer
+.PP
+\fBCMAP_VALUETYPE_UINT8\fR - 8-bit unsigned integer
+.PP
+\fBCMAP_VALUETYPE_INT16\fR - 16-bit signed integer
+.PP
+\fBCMAP_VALUETYPE_UINT16\fR - 16-bit unsigned integer
+.PP
+\fBCMAP_VALUETYPE_INT32\fR - 32-bit signed integer
+.PP
+\fBCMAP_VALUETYPE_UINT32\fR - 32-bit unsigned integer
+.PP
+\fBCMAP_VALUETYPE_INT64\fR - 64-bit signed integer
+.PP
+\fBCMAP_VALUETYPE_UINT64\fR - 64-bit unsigned integer
+
+Overflow/underflow is not detected and it's ignored.
+
+.SH RETURN VALUE
+This call returns the CS_OK value if successful. If value or key_name are unspecified, CS_ERR_INVALID_PARAM
+is returned. CS_ERR_NOT_EXIST error is returned if key doesn't exist (wasn't created by calling
+.B cmap_set(3)
+first). Some of keys may be tagged read-only directly in corosync and setting such key will result in
+CS_ERR_ACCESS error.
+
+.SH "SEE ALSO"
+.BR cmap_get (3),
+.BR cmap_set (3),
+.BR cmap_initialize (3),
+.BR cmap_overview (3)
diff --git a/man/cmap_initialize.3.in b/man/cmap_initialize.3.in
new file mode 100644
index 0000000..6bc9119
--- /dev/null
+++ b/man/cmap_initialize.3.in
@@ -0,0 +1,64 @@
+.\"/*
+.\" * Copyright (c) 2012 Red Hat, Inc.
+.\" *
+.\" * All rights reserved.
+.\" *
+.\" * Author: Jan Friesse (jfriesse@redhat.com)
+.\" *
+.\" * This software licensed under BSD license, the text of which follows:
+.\" *
+.\" * Redistribution and use in source and binary forms, with or without
+.\" * modification, are permitted provided that the following conditions are met:
+.\" *
+.\" * - Redistributions of source code must retain the above copyright notice,
+.\" * this list of conditions and the following disclaimer.
+.\" * - Redistributions in binary form must reproduce the above copyright notice,
+.\" * this list of conditions and the following disclaimer in the documentation
+.\" * and/or other materials provided with the distribution.
+.\" * - Neither the name of the Red Hat, Inc. nor the names of its
+.\" * contributors may be used to endorse or promote products derived from this
+.\" * software without specific prior written permission.
+.\" *
+.\" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+.\" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+.\" * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+.\" * THE POSSIBILITY OF SUCH DAMAGE.
+.\" */
+.TH "CMAP_INITIALIZE" 3 "20/01/2012" "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
+
+.SH NAME
+.P
+cmap_initialize \- Initialize CMAP API
+
+.SH SYNOPSIS
+.P
+\fB#include <corosync/cmap.h>\fR
+
+.P
+\fBcs_error_t cmap_initialize (cmap_handle_t \fI*handle\fB);\fR
+
+.SH DESCRIPTION
+.P
+The \fBcmap_initialize\fR function is used to initialize a connection to
+the Configuration Map API. Each application may have several connections to the CMAP API.
+Each application uses the
+.I handle
+argument to uniquely identify the connection. The
+.I handle
+argument is then used in other function calls to identify the connection to be used
+for communication with the CMAP service.
+
+.SH RETURN VALUE
+This call returns the CS_OK value if successful, otherwise an error is returned.
+
+.SH "SEE ALSO"
+.BR cmap_finalize (3),
+.BR cmap_initialize_map (3),
+.BR cmap_overview (3)
diff --git a/man/cmap_initialize_map.3.in b/man/cmap_initialize_map.3.in
new file mode 100644
index 0000000..423f96d
--- /dev/null
+++ b/man/cmap_initialize_map.3.in
@@ -0,0 +1,73 @@
+.\"/*
+.\" * Copyright (c) 2017 Red Hat, Inc.
+.\" *
+.\" * All rights reserved.
+.\" *
+.\" * Author: Jan Friesse (jfriesse@redhat.com)
+.\" *
+.\" * This software licensed under BSD license, the text of which follows:
+.\" *
+.\" * Redistribution and use in source and binary forms, with or without
+.\" * modification, are permitted provided that the following conditions are met:
+.\" *
+.\" * - Redistributions of source code must retain the above copyright notice,
+.\" * this list of conditions and the following disclaimer.
+.\" * - Redistributions in binary form must reproduce the above copyright notice,
+.\" * this list of conditions and the following disclaimer in the documentation
+.\" * and/or other materials provided with the distribution.
+.\" * - Neither the name of the Red Hat, Inc. nor the names of its
+.\" * contributors may be used to endorse or promote products derived from this
+.\" * software without specific prior written permission.
+.\" *
+.\" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+.\" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+.\" * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+.\" * THE POSSIBILITY OF SUCH DAMAGE.
+.\" */
+.TH "CMAP_INITIALIZE_MAP" 3 "20/07/2017" "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
+
+.SH NAME
+.P
+cmap_initialize_map \- Initialize CMAP API with a specific map
+
+.SH SYNOPSIS
+.P
+\fB#include <corosync/cmap.h>\fR
+
+.P
+\fBcs_error_t cmap_initialize_map (cmap_handle_t \fI*handle\fB, cmap_map_t \fImap\fB);\fR
+
+.SH DESCRIPTION
+.P
+The \fBcmap_initialize_map\fR function is used to initialize a connection to
+the Configuration Map API and specify a particular map to use. Each application may have
+several connections to the CMAP API and to different maps.
+Each application uses the
+.I handle
+argument to uniquely identify the connection. The
+.I handle
+argument is then used in other function calls to identify the connection to be used
+for communication with the CMAP service.
+.P
+The
+.I map
+argument specifies which map to connect to. \fICMAP_MAP_ICMAP\fB is the configuration map
+that contains the current corosyn cconfiguraton and some runtime variables that maybe useful
+to external agents. \fICMAP_MAP_STATS\fB is the statistics map that contains detailed information
+about network and inter-process communications.
+
+
+.SH RETURN VALUE
+This call returns the CS_OK value if successful, otherwise an error is returned.
+
+.SH "SEE ALSO"
+.BR cmap_initialize (3),
+.BR cmap_finalize (3),
+.BR cmap_overview (8)
diff --git a/man/cmap_iter_finalize.3.in b/man/cmap_iter_finalize.3.in
new file mode 100644
index 0000000..e00e05c
--- /dev/null
+++ b/man/cmap_iter_finalize.3.in
@@ -0,0 +1,72 @@
+.\"/*
+.\" * Copyright (c) 2012 Red Hat, Inc.
+.\" *
+.\" * All rights reserved.
+.\" *
+.\" * Author: Jan Friesse (jfriesse@redhat.com)
+.\" *
+.\" * This software licensed under BSD license, the text of which follows:
+.\" *
+.\" * Redistribution and use in source and binary forms, with or without
+.\" * modification, are permitted provided that the following conditions are met:
+.\" *
+.\" * - Redistributions of source code must retain the above copyright notice,
+.\" * this list of conditions and the following disclaimer.
+.\" * - Redistributions in binary form must reproduce the above copyright notice,
+.\" * this list of conditions and the following disclaimer in the documentation
+.\" * and/or other materials provided with the distribution.
+.\" * - Neither the name of the Red Hat, Inc. nor the names of its
+.\" * contributors may be used to endorse or promote products derived from this
+.\" * software without specific prior written permission.
+.\" *
+.\" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+.\" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+.\" * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+.\" * THE POSSIBILITY OF SUCH DAMAGE.
+.\" */
+.TH "CMAP_ITER_FINALIZE" 3 "06/02/2012" "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
+
+.SH NAME
+.P
+cmap_iter_finalize \- Finalize iterator for keys stored in CMAP
+
+.SH SYNOPSIS
+.P
+\fB#include <corosync/cmap.h>\fR
+
+.P
+\fBcs_error_t
+cmap_iter_finalize (cmap_handle_t \fIhandle\fB, cmap_iter_handle_t \fIiter_handle\fB);\fR
+
+.SH DESCRIPTION
+.P
+The
+.B cmap_iter_finalize
+function is used to free up memory associated with iteration obtained by calling of
+.B cmap_iter_init(3)
+function.
+The
+.I handle
+argument is connection to CMAP database obtained by calling
+.B cmap_initialize(3)
+function.
+.I iter_handle
+argument is iterator handle obtained by
+.B cmap_iter_init(3)
+function.
+
+.SH RETURN VALUE
+This call returns the CS_OK value if successful. CS_ERR_BAD_HANDLE error is returned when iter_handle
+is invalid.
+
+.SH "SEE ALSO"
+.BR cmap_iter_init (3),
+.BR cmap_initialize (3),
+.BR cmap_overview (3)
diff --git a/man/cmap_iter_init.3.in b/man/cmap_iter_init.3.in
new file mode 100644
index 0000000..1d369f6
--- /dev/null
+++ b/man/cmap_iter_init.3.in
@@ -0,0 +1,80 @@
+.\"/*
+.\" * Copyright (c) 2012 Red Hat, Inc.
+.\" *
+.\" * All rights reserved.
+.\" *
+.\" * Author: Jan Friesse (jfriesse@redhat.com)
+.\" *
+.\" * This software licensed under BSD license, the text of which follows:
+.\" *
+.\" * Redistribution and use in source and binary forms, with or without
+.\" * modification, are permitted provided that the following conditions are met:
+.\" *
+.\" * - Redistributions of source code must retain the above copyright notice,
+.\" * this list of conditions and the following disclaimer.
+.\" * - Redistributions in binary form must reproduce the above copyright notice,
+.\" * this list of conditions and the following disclaimer in the documentation
+.\" * and/or other materials provided with the distribution.
+.\" * - Neither the name of the Red Hat, Inc. nor the names of its
+.\" * contributors may be used to endorse or promote products derived from this
+.\" * software without specific prior written permission.
+.\" *
+.\" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+.\" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+.\" * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+.\" * THE POSSIBILITY OF SUCH DAMAGE.
+.\" */
+.TH "CMAP_ITER_INIT" 3 "03/02/2012" "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
+
+.SH NAME
+.P
+cmap_iter_init \- Initialize iterator for keys stored in CMAP
+
+.SH SYNOPSIS
+.P
+\fB#include <corosync/cmap.h>\fR
+
+.P
+\fBcs_error_t
+cmap_iter_init (cmap_handle_t \fIhandle\fB, const char *\fIprefix\fB, cmap_iter_handle_t *\fIcmap_iter_handle\fB);\fR
+
+.SH DESCRIPTION
+.P
+The
+.B cmap_iter_init
+function is used to initialize iteration of all keys with given
+.I prefix.
+The
+.I handle
+argument is connection to CMAP database obtained by calling
+.B cmap_initialize(3)
+function.
+.I prefix
+is string, and every returned key must have name with given prefix. This variable can also
+be NULL (or empty string) and then all keys are iterated.
+
+.B cmap_iter_init
+is used only for initialize context for future
+.B cmap_iter_next(3)
+calls and handle needed for that function is returned in
+.I cmap_iter_handle
+variable. When you have finished iteration over objects, call
+.B cmap_iter_finalize(3)
+function to free up memory associated with iteration.
+
+.SH RETURN VALUE
+This call returns the CS_OK value if successful. If there are no items with given prefixes,
+CS_ERR_NO_SECTIONS is returned.
+
+.SH "SEE ALSO"
+.BR cmap_iter_next (3),
+.BR cmap_iter_finalize (3),
+.BR cmap_initialize (3),
+.BR cmap_overview (3)
diff --git a/man/cmap_iter_next.3.in b/man/cmap_iter_next.3.in
new file mode 100644
index 0000000..95eb664
--- /dev/null
+++ b/man/cmap_iter_next.3.in
@@ -0,0 +1,82 @@
+.\"/*
+.\" * Copyright (c) 2012 Red Hat, Inc.
+.\" *
+.\" * All rights reserved.
+.\" *
+.\" * Author: Jan Friesse (jfriesse@redhat.com)
+.\" *
+.\" * This software licensed under BSD license, the text of which follows:
+.\" *
+.\" * Redistribution and use in source and binary forms, with or without
+.\" * modification, are permitted provided that the following conditions are met:
+.\" *
+.\" * - Redistributions of source code must retain the above copyright notice,
+.\" * this list of conditions and the following disclaimer.
+.\" * - Redistributions in binary form must reproduce the above copyright notice,
+.\" * this list of conditions and the following disclaimer in the documentation
+.\" * and/or other materials provided with the distribution.
+.\" * - Neither the name of the Red Hat, Inc. nor the names of its
+.\" * contributors may be used to endorse or promote products derived from this
+.\" * software without specific prior written permission.
+.\" *
+.\" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+.\" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+.\" * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+.\" * THE POSSIBILITY OF SUCH DAMAGE.
+.\" */
+.TH "CMAP_ITER_NEXT" 3 "06/02/2012" "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
+
+.SH NAME
+.P
+cmap_iter_next \- Return next item in iteration in CMAP
+
+.SH SYNOPSIS
+.P
+\fB#include <corosync/cmap.h>\fR
+
+.P
+\fBcs_error_t
+cmap_iter_next(cmap_handle_t \fIhandle\fB, cmap_iter_handle_t \fIiter_handle\fB, char \fIkey_name[]\fB,
+size_t *\fIvalue_len\fB, cmap_value_types_t *\fItype\fB);\fR
+
+.SH DESCRIPTION
+.P
+The
+.B cmap_iter_next
+function is used to get next value in iteration. The
+.I handle
+argument is connection to CMAP database obtained by calling
+.B cmap_initialize(3)
+function.
+.I iter_handle
+argument is iterator handle obtained by
+.B cmap_iter_init(3)
+function. Following key name is stored inside
+.I key_name
+argument, which must be preallocated by caller and its guaranteed maximum size is CMAP_KEYNAME_MAXLEN
+(currently 255).
+.I value_len
+is pointer where length of value is stored, but can be NULL.
+.I type
+is also optional argument (can be NULL) and here type of value is stored (type is one of types described
+in
+.B cmap_get(3)
+function).
+
+.SH RETURN VALUE
+This call returns the CS_OK value if successful. If there are no more items to iterate, CS_NO_SECTION
+error code is returned.
+
+.SH "SEE ALSO"
+.BR cmap_iter_init (3),
+.BR cmap_iter_finalize (3),
+.BR cmap_initialize (3),
+.BR cmap_get (3),
+.BR cmap_overview (3)
diff --git a/man/cmap_keys.7 b/man/cmap_keys.7
new file mode 100644
index 0000000..320917a
--- /dev/null
+++ b/man/cmap_keys.7
@@ -0,0 +1,426 @@
+.\"/*
+.\" * Copyright (c) 2012-2020 Red Hat, Inc.
+.\" *
+.\" * All rights reserved.
+.\" *
+.\" * Author: Jan Friesse (jfriesse@redhat.com)
+.\" *
+.\" * This software licensed under BSD license, the text of which follows:
+.\" *
+.\" * Redistribution and use in source and binary forms, with or without
+.\" * modification, are permitted provided that the following conditions are met:
+.\" *
+.\" * - Redistributions of source code must retain the above copyright notice,
+.\" * this list of conditions and the following disclaimer.
+.\" * - Redistributions in binary form must reproduce the above copyright notice,
+.\" * this list of conditions and the following disclaimer in the documentation
+.\" * and/or other materials provided with the distribution.
+.\" * - Neither the name of the Red Hat, Inc. nor the names of its
+.\" * contributors may be used to endorse or promote products derived from this
+.\" * software without specific prior written permission.
+.\" *
+.\" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+.\" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+.\" * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+.\" * THE POSSIBILITY OF SUCH DAMAGE.
+.\" */
+.TH "CMAP_KEYS" 7 "2018-10-08" "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
+
+.SH NAME
+.P
+cmap_keys \- Overview of keys stored in the Configuration Map
+
+.SH OVERVIEW
+.P
+There are 3 main types of keys stored in CMAP:
+.PP
+* Mapping of values stored in the config file.
+.PP
+* Runtime statistics.
+.PP
+* Other user created values.
+
+In this man page, wild-cards have the usual meaning.
+
+.SH ICMAP KEYS
+These keys are in the icmap (default) map
+.TP
+internal_configuration.*
+Internal configuration data. All keys in this prefix are read only.
+It's only useful for getting a list of loaded services.
+
+.TP
+logging.*
+Values read from the configuration file. It's possible to change them at runtime.
+If subsystem specific configuration is needed, the key must be in the form
+logging.logger_subsys.SERVICE.key, where SERVICE is upper case name of the service and
+key is same as in the configuration file. All values are of string type.
+
+.TP
+nodelist.*
+Values are read from the configuration file only (dynamic updates are not allowed).
+Each node element in the configuration file gets
+assigned its position starting from zero. So the first node from the config file has
+nodelist.node.0. prefix. To be a valid entry, each node must have
+.B ring0_addr
+key.
+To change the
+.B nodeid
+key, use a u32 data type.
+
+Local node position is stored in
+.B local_node_pos
+key (RO), so it's easy to find
+out nodeid/ring addresses of the local node directly from cmap.
+
+.TP
+runtime.blackbox.*
+Trigger keys for storing fplay data. It's recommended that you use the corosync-blackbox command
+to change keys in this prefix.
+
+.TP
+runtime.force_gather
+Set to 'yes' to force the processor to move into the GATHER state. This operation
+is dangerous and is not recommended.
+
+.TP
+runtime.config.*
+Contains the values actually in use by the totem membership protocol.
+Values here are either taken from the Corosync configuration file,
+defaults or computed from entries in the config file. For information
+on individual keys please refer to the man page
+.BR corosync.conf (5).
+
+.TP
+runtime.services.*
+Prefix with statistics for service engines. Each service has its own
+.B service_id
+key in the prefix with the name runtime.services.SERVICE., where SERVICE is the lower case
+name of the service. Inside the service prefix is the number of messages received and sent
+by the corosync engine in the format runtime.services.SERVICE.EXEC_CALL.rx and
+runtime.services.SERVICE.EXEC_CALL.tx, where EXEC_CALL is the internal id of the service
+call (so for example 3 in cpg service is receive of multicast message from other
+nodes).
+
+.TP
+runtime.totem.members.*
+Prefix containing members of the totem single ring protocol. Each member
+keys has format runtime.totem.members.NODEID.KEY, where key is
+one of:
+
+.B config_version
+Config version of the member node.
+
+.TP
+resources.process.PID.*
+Prefix created by applications using SAM with CMAP integration.
+It contains the following keys:
+
+.B recovery
+Recovery policy of the process. Can be one of quit or restart.
+
+.B poll_period
+Value passed in sam_initialize as a time_interval.
+
+.B last_updated
+Last time SAM received a heartbeat from the client.
+
+.B state
+State of the client. Can be one of failed, stopped, running and waiting for quorum.
+
+.TP
+uidgid.*
+Information about users/groups which are allowed to make IPC connections to
+corosync. Entries loaded from configuration file are stored with
+uidgid.config.* prefix and are pruned on configuration file reload. Dynamic
+entries has uidgid.* prefix and a configuration file reload doesn't affect them.
+
+.TP
+quorum.cancel_wait_for_all
+Tells votequorum to cancel waiting for all nodes at cluster startup. Can be used
+to unblock quorum if notes are known to be down. For pcs use only.
+
+.TP
+cfg.shutdown_timeout
+Sets the timeout within which daemons that are registered for cfg callbacks must respond
+to a corosync_cfg_try_shutdown() request. the default is 5000 mS
+
+.TP
+config.reload_in_progress
+This value will be set to 1 (or created) when a corosync.conf reload is started,
+and set to 0 when the reload is completed. This allows interested subsystems
+to do atomic reconfiguration rather than changing each key. Note that
+individual add/change/delete notifications will still be sent during a reload.
+
+.TP
+config.totemconfig_reload_in_progress
+This key is similar to
+.B config.totemconfig_reload_in_progress
+but changed after the totem config trigger is processed. It is useful (mainly)
+for situations when
+.B nodelist.local_node_pos
+must be correctly reinstated before anything else.
+
+.SH STATS KEYS
+These keys are in the stats map. All keys in this map are read-only.
+Modification tracking of individual keys is supported in the stats map, but not
+prefixes. Add/Delete operations are supported on prefixes though so you can track
+for new ipc connections or knet interfaces.
+.TP
+stats.srp.*
+Prefix containing statistics about totem.
+Typical key prefixes:
+
+.B commit_entered
+Number of times the processor entered COMMIT state.
+
+.B commit_token_lost
+Number of times the processor lost token in COMMIT state.
+
+.B consensus_timeouts
+How many times the processor timed out forming a consensus about membership.
+
+.B continuous_gather
+How many times the processor was not able to reach consensus.
+
+.B firewall_enabled_or_nic_failure
+Set to 1 when processor was not able to reach consensus for long time. The usual
+reason is a badly configured firewall or connection failure.
+
+.B gather_entered
+Number of times the processor entered GATHER state.
+
+.B gather_token_lost
+Number of times the processor lost token in GATHER state.
+
+.B mcast_retx
+Number of retransmitted messages.
+
+.B mcast_rx
+Number of received multicast messages.
+
+.B mcast_tx
+Number of transmitted multicast messages.
+
+.B memb_commit_token_rx
+Number of received commit tokens.
+
+.B memb_commit_token_tx
+Number of transmitted commit tokens.
+
+.B memb_join_rx
+Number of received join messages.
+
+.B memb_join_tx
+Number of transmitted join messages.
+
+.B memb_merge_detect_rx
+Number of received member merge messages.
+
+.B memb_merge_detect_tx
+Number of transmitted member merge messages.
+
+.B orf_token_rx
+Number of received orf tokens.
+
+.B orf_token_tx
+Number of transmitted orf tokens.
+
+.B recovery_entered
+Number of times the processor entered recovery.
+
+.B recovery_token_lost
+Number of times the token was lost in recovery state.
+
+.B rx_msg_dropped
+Number of received messages which were dropped because they were not expected
+(as example multicast message in commit state).
+
+.B token_hold_cancel_rx
+Number of received token hold cancel messages.
+
+.B token_hold_cancel_tx
+Number of transmitted token hold cancel messages.
+
+.B mtt_rx_token
+Mean transit time of token in milliseconds. In other words, time between
+two consecutive token receives.
+
+.B avg_token_workload
+Average time in milliseconds of holding time of token on the current processor.
+
+.B avg_backlog_calc
+Average number of not yet sent messages on the current processor.
+
+.TP
+stats.knet.nodeX.linkY.*
+Statistics about the network traffic to and from each node and link when using
+tke kronosnet transport
+
+.B connected
+Whether the link is connected or not
+
+.B up_count
+Number of times this link has changed state to UP
+
+.B down_count
+Number of times this link has changed state to DOWN
+
+.B latency_ave / latency_max / latency_max
+Calculated latencies of this link. Note that if there has been no traffic
+on the link then latency_min will show a very large number.
+
+.B latency_samples
+The number of samples used to calculate the latency figures, so you have
+some idea of their precision.
+
+.B rx_data_packets / tx_data_packets
+The number of packets sent/received on this link
+
+.B rx_data_bytes / tx_data_bytes
+The number of bytes sent/received on this link
+
+.B rx_pmtu_packets / tx_pmtu_packets
+The number of packets sent/received by the PMTUd subsystem
+
+.B rx_pmtu_bytes / tx_pmtu_bytes
+The number of bytes sent/received by the PMTUd subsystem
+
+.B rx_ping_packets / tx_ping_packets
+The number of packets sent/received as pings
+
+.B rx_ping_bytes / tx_ping_bytes
+The number of bytes sent/received as pings
+
+.B rx_pong_packets / tx_pong_packets
+The number of packets sent/received as pongs
+
+.B rx_pong_bytes / tx_pong_bytes
+The number of bytes sent/received as pongs
+
+.B rx_total_packets / tx_total_packets
+The total number of packets sent/received. The aggregate of all of the above packet stats
+
+.B rx_total_bytes / tx_total_bytes
+The total number of bytes sent/received. The aggregate of all of the above bytes stats
+
+.B tx_data_retries / tx_pmtu_retries / tx_ping_retries / tx_pong_retries / tx_total_retries
+Number of times a transmit operation had to be retried due to the socket returning EAGAIN
+
+.TP
+stats.ipcs.*
+There is information about total number of active connections from client programs
+at the time the request was made.
+.B active
+number of closed connections during whole runtime of corosync
+.B closed
+Total number of connections that have been made since corosync was started
+
+.TP
+stats.ipcs.ID.*
+Each IPC connection has a unique ID. This is in the form [[serviceX:][PID:]internal_id.
+
+Typical keys in this prefix are:
+
+.B proc_name
+process name of connected process (unavailable on some platforms)
+
+.B dispatched
+number of dispatched messages.
+
+.B invalid_request
+number of requests made by IPC which are invalid (calling non-existing call, ...).
+
+.B name
+contains short name of the IPC connection (unavailable on some platforms).
+
+.B overload
+is number of requests which were not processed because of overload.
+
+.B queue_size
+contains the number of messages in the queue waiting for send.
+
+.B recv_retries
+is the total number of interrupted receives.
+
+.B requests
+contains the number of requests made by IPC.
+
+.B responses
+is the number of responses sent to the IPC client.
+
+.B send_retries
+contains the total number of interrupted sends.
+
+.B service_id
+contains the ID of service which the IPC is connected to.
+
+
+.TP
+stats.schedmiss.<n>.*
+If corosync is not scheduled after the required period of time it will
+log this event and also write an entry to the stats cmap under this key.
+There can be up to 10 entries (0..9) in here, when an 11th event happens
+the earliest will be removed.
+
+These events will always be in reverse order, so stats.schedmiss.0.* will
+always be the latest event kept and 9 the oldest. If you want to listen
+for notifications then you are recommended to listen for changes
+to stats.schedmiss.0.timestamp or stats.schedmiss.0.delay.
+
+.B timestamp
+The time of the event in ms since the Epoch (ie time_t * 1000 but with
+valid milliseconds).
+
+.B delay
+The time that corosync was paused (in ms, float value).
+
+
+.TP
+stats.clear.*
+These are write-only keys used to clear the stats for various subsystems
+
+.B totem
+Clears the pg & srp totem stats.
+
+.B knet
+Clears the knet stats
+
+.B ipc
+Clears the ipc stats
+
+.B schedmiss
+Clears the schedmiss stats
+
+.B all
+Clears all of the above stats
+
+
+.SH DYNAMIC CHANGE USER/GROUP PERMISSION TO USE COROSYNC IPC
+Is the same as in the configuration file. eg: to add UID 500 use
+
+.br
+# corosync-cmapctl -s uidgid.uid.500 u8 1
+
+GID is similar, so to add a GID use
+
+.br
+# corosync-cmapctl -s uidgid.gid.500 u8 1
+
+For removal of permissions, simply delete the key
+
+.br
+# corosync-cmapctl -d uidgid.gid.500
+
+
+.SH "SEE ALSO"
+.BR corosync_overview (7),
+.BR corosync.conf (5),
+.BR corosync-cmapctl (8)
diff --git a/man/cmap_overview.3 b/man/cmap_overview.3
new file mode 100644
index 0000000..0aa3c14
--- /dev/null
+++ b/man/cmap_overview.3
@@ -0,0 +1,78 @@
+.\"/*
+.\" * Copyright (c) 2012 Red Hat, Inc.
+.\" *
+.\" * All rights reserved.
+.\" *
+.\" * Author: Jan Friesse (jfriesse@redhat.com)
+.\" *
+.\" * This software licensed under BSD license, the text of which follows:
+.\" *
+.\" * Redistribution and use in source and binary forms, with or without
+.\" * modification, are permitted provided that the following conditions are met:
+.\" *
+.\" * - Redistributions of source code must retain the above copyright notice,
+.\" * this list of conditions and the following disclaimer.
+.\" * - Redistributions in binary form must reproduce the above copyright notice,
+.\" * this list of conditions and the following disclaimer in the documentation
+.\" * and/or other materials provided with the distribution.
+.\" * - Neither the name of the Red Hat, Inc. nor the names of its
+.\" * contributors may be used to endorse or promote products derived from this
+.\" * software without specific prior written permission.
+.\" *
+.\" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+.\" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+.\" * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+.\" * THE POSSIBILITY OF SUCH DAMAGE.
+.\" */
+.TH "CMAP_OVERVIEW" 3 "03/02/2012" "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
+
+.SH NAME
+.P
+cmap_overview \- Overview of the Configuration Map
+
+.SH OVERVIEW
+.P
+The CMAP library is used to interact with the configuration & statistics databases used by corosync.
+
+.PP
+The library provides a mechanism to:
+.PP
+* Create of new keys
+.PP
+* Change existing keys
+.PP
+* Remove keys
+.PP
+* Iterate keys with given prefix
+.PP
+* Track changes on keys
+
+Description of most keys created by corosync itself can be found in cmap_keys (7).
+
+.SH BUGS
+.SH "SEE ALSO"
+.BR cmap_initialize (3),
+.BR cmap_initialize_map (3),
+.BR cmap_finalize (3),
+.BR cmap_get (3),
+.BR cmap_set (3),
+.BR cmap_delete (3),
+.BR cmap_inc (3),
+.BR cmap_dec (3),
+.BR cmap_fd_get (3),
+.BR cmap_dispatch (3),
+.BR cmap_context_set (3),
+.BR cmap_context_get (3),
+.BR cmap_iter_init (3),
+.BR cmap_iter_next (3),
+.BR cmap_iter_finalize (3),
+.BR cmap_track_add (3),
+.BR cmap_track_delete (3),
+.BR cmap_keys (7)
diff --git a/man/cmap_set.3.in b/man/cmap_set.3.in
new file mode 100644
index 0000000..de7af1f
--- /dev/null
+++ b/man/cmap_set.3.in
@@ -0,0 +1,127 @@
+.\"/*
+.\" * Copyright (c) 2012 Red Hat, Inc.
+.\" *
+.\" * All rights reserved.
+.\" *
+.\" * Author: Jan Friesse (jfriesse@redhat.com)
+.\" *
+.\" * This software licensed under BSD license, the text of which follows:
+.\" *
+.\" * Redistribution and use in source and binary forms, with or without
+.\" * modification, are permitted provided that the following conditions are met:
+.\" *
+.\" * - Redistributions of source code must retain the above copyright notice,
+.\" * this list of conditions and the following disclaimer.
+.\" * - Redistributions in binary form must reproduce the above copyright notice,
+.\" * this list of conditions and the following disclaimer in the documentation
+.\" * and/or other materials provided with the distribution.
+.\" * - Neither the name of the Red Hat, Inc. nor the names of its
+.\" * contributors may be used to endorse or promote products derived from this
+.\" * software without specific prior written permission.
+.\" *
+.\" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+.\" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+.\" * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+.\" * THE POSSIBILITY OF SUCH DAMAGE.
+.\" */
+.TH "CMAP_SET" 3 "23/01/2012" "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
+
+.SH NAME
+.P
+cmap_set \- Store value in CMAP
+
+.SH SYNOPSIS
+.P
+\fB#include <corosync/cmap.h>\fR
+
+.P
+\fBcs_error_t
+cmap_set (cmap_handle_t \fIhandle\fB, const char *\fIkey_name\fB, const void *\fIvalue\fB,
+size_t \fIvalue_len\fB, cmap_value_types_t \fItype\fB);\fR
+.P
+Also shortcuts for different types are defined
+.P
+\fBcs_error_t cmap_set_int8(cmap_handle_t \fIhandle\fB, const char *\fIkey_name\fB, int8_t \fIvalue\fB);\fR
+.P
+\fBcs_error_t cmap_set_uint8(cmap_handle_t \fIhandle\fB, const char *\fIkey_name\fB, uint8_t \fIvalue\fB);\fR
+.P
+\fBcs_error_t cmap_set_int16(cmap_handle_t \fIhandle\fB, const char *\fIkey_name\fB, int16_t \fIvalue\fB);\fR
+.P
+\fBcs_error_t cmap_set_uint16(cmap_handle_t \fIhandle\fB, const char *\fIkey_name\fB, uint16_t \fIvalue\fB);\fR
+.P
+\fBcs_error_t cmap_set_int32(cmap_handle_t \fIhandle\fB, const char *\fIkey_name\fB, int32_t \fIvalue\fB);\fR
+.P
+\fBcs_error_t cmap_set_uint32(cmap_handle_t \fIhandle\fB, const char *\fIkey_name\fB, uint32_t \fIvalue\fB);\fR
+.P
+\fBcs_error_t cmap_set_int64(cmap_handle_t \fIhandle\fB, const char *\fIkey_name\fB, int64_t \fIvalue\fB);\fR
+.P
+\fBcs_error_t cmap_set_uint64(cmap_handle_t \fIhandle\fB, const char *\fIkey_name\fB, uint64_t \fIvalue\fB);\fR
+.P
+\fBcs_error_t cmap_set_float(cmap_handle_t \fIhandle\fB, const char *\fIkey_name\fB, float \fIvalue\fB);\fR
+.P
+\fBcs_error_t cmap_set_double(cmap_handle_t \fIhandle\fB, const char *\fIkey_name\fB, double \fIvalue\fB);\fR
+.P
+\fBcs_error_t cmap_set_string(cmap_handle_t \fIhandle\fB, const char *\fIkey_name\fB, const char *\fIvalue\fB);\fR
+
+.SH DESCRIPTION
+.P
+The
+.B cmap_set
+function is used to store key inside cmap. The
+.I handle
+argument is connection to CMAP database obtained by calling
+.B cmap_initialize(3)
+function.
+.I key_name
+is name of key to set value. Key name is limited by minimal (CMAP_KEYNAME_MINLEN, currently 3) and
+maximal (CMAP_KEYNAME_MAXLEN, currently 255) length. Also key can contain only limited set of characters expressed
+by regexp [a-zA-Z0-9._-/:]*.
+.I value
+is pointer to allocated data which will be stored inside CMAP. Length of value (number of bytes) is supplied
+as
+.I value_len
+parameter. Last parameter is
+.I type
+which gives type of value. It may be one of:
+.PP
+\fBCMAP_VALUETYPE_INT8\fR - 8-bit signed integer
+.PP
+\fBCMAP_VALUETYPE_UINT8\fR - 8-bit unsigned integer
+.PP
+\fBCMAP_VALUETYPE_INT16\fR - 16-bit signed integer
+.PP
+\fBCMAP_VALUETYPE_UINT16\fR - 16-bit unsigned integer
+.PP
+\fBCMAP_VALUETYPE_INT32\fR - 32-bit signed integer
+.PP
+\fBCMAP_VALUETYPE_UINT32\fR - 32-bit unsigned integer
+.PP
+\fBCMAP_VALUETYPE_INT64\fR - 64-bit signed integer
+.PP
+\fBCMAP_VALUETYPE_UINT64\fR - 64-bit unsigned integer
+.PP
+\fBCMAP_VALUETYPE_FLOAT\fR - Float value
+.PP
+\fBCMAP_VALUETYPE_DOUBLE\fR - Double value
+.PP
+\fBCMAP_VALUETYPE_STRING\fR - C-style string
+.PP
+\fBCMAP_VALUETYPE_BINARY\fR - Binary data, byte with zero value has no special meaning
+
+
+.SH RETURN VALUE
+This call returns the CS_OK value if successful. If value or key_name are unspecified, CS_ERR_INVALID_PARAM
+is returned. Too short or too long key_name returns CS_ERR_NAME_TOO_LONG error code. Some of keys may
+be tagged read-only directly in corosync and setting such key will result in CS_ERR_ACCESS error.
+
+.SH "SEE ALSO"
+.BR cmap_get (3),
+.BR cmap_initialize (3),
+.BR cmap_overview (3)
diff --git a/man/cmap_track_add.3.in b/man/cmap_track_add.3.in
new file mode 100644
index 0000000..02e07c3
--- /dev/null
+++ b/man/cmap_track_add.3.in
@@ -0,0 +1,170 @@
+.\"/*
+.\" * Copyright (c) 2012 Red Hat, Inc.
+.\" *
+.\" * All rights reserved.
+.\" *
+.\" * Author: Jan Friesse (jfriesse@redhat.com)
+.\" *
+.\" * This software licensed under BSD license, the text of which follows:
+.\" *
+.\" * Redistribution and use in source and binary forms, with or without
+.\" * modification, are permitted provided that the following conditions are met:
+.\" *
+.\" * - Redistributions of source code must retain the above copyright notice,
+.\" * this list of conditions and the following disclaimer.
+.\" * - Redistributions in binary form must reproduce the above copyright notice,
+.\" * this list of conditions and the following disclaimer in the documentation
+.\" * and/or other materials provided with the distribution.
+.\" * - Neither the name of the Red Hat, Inc. nor the names of its
+.\" * contributors may be used to endorse or promote products derived from this
+.\" * software without specific prior written permission.
+.\" *
+.\" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+.\" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+.\" * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+.\" * THE POSSIBILITY OF SUCH DAMAGE.
+.\" */
+.TH "CMAP_TRACK_ADD" 3 "06/02/2012" "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
+
+.SH NAME
+.P
+cmap_track_add \- Set tracking function for values in CMAP
+
+.SH SYNOPSIS
+.P
+\fB#include <corosync/cmap.h>\fR
+
+.P
+\fBcs_error_t
+cmap_track_add (cmap_handle_t \fIhandle\fB, const char *\fIkey_name\fB, int32_t \fItrack_type\fB,
+cmap_notify_fn_t \fInotify_fn\fB, void *\fIuser_data\fB, cmap_track_handle_t *\fIcmap_track_handle\fB);\fR
+
+.SH DESCRIPTION
+.P
+The
+.B cmap_track_add
+function is used to set function which tracks changes in CMAP. One CMAP connection can
+track multiple keys and also it's possible to track one key multiple times. The
+.I handle
+argument is connection to CMAP database obtained by calling
+.B cmap_initialize(3)
+function.
+.I key_name
+argument is ether exact key name or prefix of key name to track changes on.
+.I track_type
+is bitfield which may consist of following values:
+.PP
+\fBCMAP_TRACK_ADD\fR - track addition of new key (or key added in callback)
+.PP
+\fBCMAP_TRACK_DELETE\fR - track deletion of key (or key deleted in callback)
+.PP
+\fBCMAP_TRACK_MODIFY\fR - track modification of key (or key modified in callback)
+.PP
+\fBCMAP_TRACK_PREFIX\fR - whole prefix is tracked, instead of key only, so "totem." tracking means
+that "totem.nodeid", "totem.version", ... applies (this value is never returned
+in callback)
+.PP
+.I notify_fn
+is pointer to function which is called when value is changed. It's definition and meaning of parameters
+is discussed below.
+.I user_data
+argument is passed directly to
+.I notify_fn
+without any changes.
+.I cmap_track_handle
+is used for removing of tracking when no longer needed by calling
+.B cmap_track_delete(3)
+function.
+
+Callback function is defined as:
+.IP
+.RS
+.ne 18
+.nf
+.PP
+typedef void (*cmap_notify_fn_t) (
+ cmap_handle_t cmap_handle,
+ cmap_track_handle_t cmap_track_handle,
+ int32_t event,
+ const char *key_name,
+ struct cmap_notify_value new_value,
+ struct cmap_notify_value old_value,
+ void *user_data);
+.ta
+.fi
+.RE
+.IP
+.PP
+where
+.I cmap_handle
+is handle used in registration of track function.
+.I cmap_track_handle
+is handle returned by
+.B cmap_track_add
+function.
+.I event
+is one of \fBCMAP_TRACK_ADD\fR, \fBCMAP_TRACK_DELETE\fR or \fBCMAP_TRACK_MODIFY\fR.
+.I key_name
+is name of changed key.
+.I new_value
+is new value of key, or unset if
+.I event
+is \fBCMAP_TRACK_DELETE\fR.
+.I old_value
+is previous value of key or unset if
+.I event
+is \fBCMAP_TRACK_ADD\fR or for some special keys set directly by Corosync due to speed optimizations.
+Both
+.I new_value
+and
+.I old_value
+are structures defined as:
+.IP
+.RS
+.ne 18
+.nf
+.PP
+struct cmap_notify_value {
+ cmap_value_types_t type;
+ size_t len;
+ const void *data;
+};
+.ta
+.fi
+.RE
+.IP
+.PP
+If value is unset, all fields are set to 0. Otherwise
+.I type
+is one of cmap types (as described in
+.B cmap_get(3)
+function),
+.I len
+is length of value in cmap and
+.I data
+is pointer to value of item. Data storage is dynamically allocated by caller and notify function must not try to
+free it.
+
+.SH RETURN VALUE
+This call returns the CS_OK value if successful. It can return CS_ERR_INVALID_PARAM if
+notify_fn is NULL or track_type is invalid value.
+
+.SH NOTES
+Modification tracking of individual keys is supported in the stats map, but not
+prefixes. Add/Delete operations are supported on prefixes though so you can track
+for new ipc connections or knet interfaces.
+In the icmap map, prefix tracking is fully supported.
+
+.SH "SEE ALSO"
+.BR cmap_track_delete (3),
+.BR cmap_initialize (3),
+.BR cmap_get (3),
+.BR cmap_dispatch (3),
+.BR cmap_overview (3)
diff --git a/man/cmap_track_delete.3.in b/man/cmap_track_delete.3.in
new file mode 100644
index 0000000..81946a3
--- /dev/null
+++ b/man/cmap_track_delete.3.in
@@ -0,0 +1,70 @@
+.\"/*
+.\" * Copyright (c) 2012 Red Hat, Inc.
+.\" *
+.\" * All rights reserved.
+.\" *
+.\" * Author: Jan Friesse (jfriesse@redhat.com)
+.\" *
+.\" * This software licensed under BSD license, the text of which follows:
+.\" *
+.\" * Redistribution and use in source and binary forms, with or without
+.\" * modification, are permitted provided that the following conditions are met:
+.\" *
+.\" * - Redistributions of source code must retain the above copyright notice,
+.\" * this list of conditions and the following disclaimer.
+.\" * - Redistributions in binary form must reproduce the above copyright notice,
+.\" * this list of conditions and the following disclaimer in the documentation
+.\" * and/or other materials provided with the distribution.
+.\" * - Neither the name of the Red Hat, Inc. nor the names of its
+.\" * contributors may be used to endorse or promote products derived from this
+.\" * software without specific prior written permission.
+.\" *
+.\" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+.\" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+.\" * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+.\" * THE POSSIBILITY OF SUCH DAMAGE.
+.\" */
+.TH "CMAP_TRACK_DELETE" 3 "06/02/2012" "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
+
+.SH NAME
+.P
+cmap_track_delete \- Remove tracking of values in CMAP
+
+.SH SYNOPSIS
+.P
+\fB#include <corosync/cmap.h>\fR
+
+.P
+\fBcs_error_t
+cmap_track_delete (cmap_handle_t \fIhandle\fB, cmap_track_handle_t \fItrack_handle\fB);\fR
+
+.SH DESCRIPTION
+.P
+The
+.B cmap_track_delte
+function is used to remove tracking of values changed in CMAP.
+The
+.I handle
+argument is connection to CMAP database obtained by calling
+.B cmap_initialize(3)
+function.
+.I track_handle
+argument is iterator handle obtained by
+.B cmap_track_add(3)
+function.
+
+.SH RETURN VALUE
+This call returns the CS_OK value if successful. CS_ERR_BAD_HANDLE error is returned when track_handle
+is invalid.
+
+.SH "SEE ALSO"
+.BR cmap_track_add (3),
+.BR cmap_initialize (3),
+.BR cmap_overview (3)
diff --git a/man/corosync-blackbox.8 b/man/corosync-blackbox.8
new file mode 100644
index 0000000..75d3806
--- /dev/null
+++ b/man/corosync-blackbox.8
@@ -0,0 +1,69 @@
+.\"/*
+.\" * Copyright (C) 2010 Red Hat, Inc.
+.\" *
+.\" * All rights reserved.
+.\" *
+.\" * Author: Angus Salkeld <asalkeld@redhat.com>
+.\" *
+.\" * This software licensed under BSD license, the text of which follows:
+.\" *
+.\" * Redistribution and use in source and binary forms, with or without
+.\" * modification, are permitted provided that the following conditions are met:
+.\" *
+.\" * - Redistributions of source code must retain the above copyright notice,
+.\" * this list of conditions and the following disclaimer.
+.\" * - Redistributions in binary form must reproduce the above copyright notice,
+.\" * this list of conditions and the following disclaimer in the documentation
+.\" * and/or other materials provided with the distribution.
+.\" * - Neither the name of Red Hat, Inc. nor the names of its
+.\" * contributors may be used to endorse or promote products derived from this
+.\" * software without specific prior written permission.
+.\" *
+.\" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+.\" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+.\" * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+.\" * THE POSSIBILITY OF SUCH DAMAGE.
+.\" */
+.TH COROSYNC-BLACKBOX 8 2010-05-30
+.SH NAME
+corosync-blackbox \- Dump live "flight data" from the corosync "blackbox".
+.SH SYNOPSIS
+.B "corosync-blackbox"
+.SH DESCRIPTION
+.B corosync-blackbox
+Trigger corosync to write it's "flight data" out to file and then run
+.B qb-blackbox
+which prints it out.
+.SH EXAMPLES
+.TP
+Print the current "flight data".
+.br
+$ corosync-blackbox
+.br
+Starting replay: head [74205] tail [0]
+.br
+rec=[1] Log Message=Corosync Cluster Engine ('1.2.1'): started and ready to provide service.
+.br
+[...]
+.br
+rec=[2607] Log Message=Delivering MCAST message with seq a to pending delivery queue
+.br
+rec=[2608] Log Message=downlist received left_list: 2
+.br
+rec=[2609] Log Message=chosen downlist from node r(0) ip(192.168.100.11)
+.br
+Finishing replay: records found [2609]
+.br
+.SH SEE ALSO
+.BR qb-blackbox (8),
+.BR corosync-cmapctl (8)
+.SH AUTHOR
+Angus Salkeld
+.PP
diff --git a/man/corosync-cfgtool.8 b/man/corosync-cfgtool.8
new file mode 100644
index 0000000..bcfb900
--- /dev/null
+++ b/man/corosync-cfgtool.8
@@ -0,0 +1,139 @@
+.\"
+.\" * Copyright (C) 2010-2020 Red Hat, Inc.
+.\" *
+.\" * All rights reserved.
+.\" *
+.\" * Author: Angus Salkeld <asalkeld@redhat.com>
+.\" *
+.\" * This software licensed under BSD license, the text of which follows:
+.\" *
+.\" * Redistribution and use in source and binary forms, with or without
+.\" * modification, are permitted provided that the following conditions are met:
+.\" *
+.\" * - Redistributions of source code must retain the above copyright notice,
+.\" * this list of conditions and the following disclaimer.
+.\" * - Redistributions in binary form must reproduce the above copyright notice,
+.\" * this list of conditions and the following disclaimer in the documentation
+.\" * and/or other materials provided with the distribution.
+.\" * - Neither the name of the MontaVista Software, Inc. nor the names of its
+.\" * contributors may be used to endorse or promote products derived from this
+.\" * software without specific prior written permission.
+.\" *
+.\" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+.\" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+.\" * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+.\" * THE POSSIBILITY OF SUCH DAMAGE.
+.\" */
+.TH "COROSYNC-CFGTOOL" "8" "2020-06-02" "" ""
+.SH "NAME"
+corosync-cfgtool \- An administrative tool for corosync.
+.SH "SYNOPSIS"
+.B corosync\-cfgtool [[\-i IP_address] [\-b] [\-s] [\-n] [\-R] [\-L] [\-k nodeid] [\-a nodeid] [\-h] [\-H] [\--force]
+.SH "DESCRIPTION"
+.B corosync\-cfgtool
+A tool for displaying and configuring active parameters within corosync.
+.SH "OPTIONS"
+.TP
+.B -i
+Finds only information about the specified interface IP address or link id with -s.
+.TP
+.B -s
+Displays the status of the current links on this node for UDP/UDPU, with extended status
+for KNET.
+After each link, the nodes on that link are displayed in order with their status,
+for example there are 3 nodes with KNET transport:
+
+LINK ID 0
+ addr = 192.168.100.80
+ status:
+ nodeid 1: localhost
+ nodeid 2: connected
+ nodeid 3: connected
+
+Please note that only one link is returned for a single node cluster configuration,
+no matter how many links are configured.
+.TP
+.B -b
+Displays the brief status of the current links on this node when used
+with "-s". If any interfaces are faulty, 1 is returned by the binary. If all interfaces
+are active 0 is returned to the shell.
+After each link, the nodes on that link are displayed in order with their status
+encoded into a single digit, or characters 'n', 'd' and '?' with special meaning.
+1=link enabled, 2=link connected, So a 3 in a node position indicates that the
+link is both enabled and connected. Status represented by character 'n' is used for
+localhost link. Character '?' means that Corosync was unable to get status of link from knet (log
+should contain more information). Character 'd' shouldn't appear and it means that Corosync
+was unable to configure a link and it is result of some error which should have been logged.
+
+The output will be:
+
+LINK ID 0
+ addr = 192.168.100.80
+ status = n33
+.TP
+.B -n
+Displays the status of the current nodes in the system with their link status(es).
+.P
+.nf
+Local node ID 1, transport knet
+nodeid: 2 reachable onwire (min/max/cur): 0, 1, 1
+ LINK: 0 (192.168.1.101->192.168.1.102) enabled connected mtu: 1397
+ LINK: 1 (192.168.4.1->192.168.4.2) enabled mtu: 469
+ LINK: 2 (192.168.9.1->192.168.9.2) enabled mtu: 469
+.fi
+.P
+Only reachable nodes are displayed so "reachable" should always be there.
+.br
+\(oqonwire\(cq versions are the knet on-wire versions that are supported/in use (where appropriate).
+.br
+IP addresses are the local and remote IP addresses (for UDP[U] only the local IP address is shown)
+.br
+enabled - means the link has been brought up
+.br
+connected - means that the link is connected to the remote node
+.br
+dynconnected - is not currently implemented
+.br
+mtu - shows the size of data packets. Should be the link packet size less a small amount
+for protocol overheads and encryption
+.TP
+.B -R
+Tell all instances of corosync in this cluster to reload corosync.conf.
+
+Running corosync-cfgtool -R where nodes are running different versions
+of corosync (including minor versions) is unsupported and may result in undefined
+behaviour.
+.TP
+.B -L
+Tell corosync to reopen all logging files. In contrast to other subcommands,
+nothing is displayed on terminal if call is successful.
+.TP
+.B -k
+Kill a node identified by node id.
+.TP
+.B -a
+Display the IP address(es) of a node.
+.TP
+.B -h
+Print basic usage.
+.TP
+.B -H
+Shutdown corosync cleanly on this node.
+corosync-cfgtool -H will request a shutdown from corosync, which means it will
+consult any interested daemons before shutting down and the shutdown maybe vetoed if a
+daemon regards the shutdown as inappropriate.
+If --force is added to the command line then corosync will shutdown regardless
+of the daemons' opinions on the matter.
+
+.SH "SEE ALSO"
+.BR corosync_overview (7),
+.SH "AUTHOR"
+Angus Salkeld
+.PP
diff --git a/man/corosync-cmapctl.8 b/man/corosync-cmapctl.8
new file mode 100644
index 0000000..8826503
--- /dev/null
+++ b/man/corosync-cmapctl.8
@@ -0,0 +1,99 @@
+.\"/*
+.\" * Copyright (C) 2010 Red Hat, Inc.
+.\" *
+.\" * All rights reserved.
+.\" *
+.\" * Author: Angus Salkeld <asalkeld@redhat.com>
+.\" *
+.\" * This software licensed under BSD license, the text of which follows:
+.\" *
+.\" * Redistribution and use in source and binary forms, with or without
+.\" * modification, are permitted provided that the following conditions are met:
+.\" *
+.\" * - Redistributions of source code must retain the above copyright notice,
+.\" * this list of conditions and the following disclaimer.
+.\" * - Redistributions in binary form must reproduce the above copyright notice,
+.\" * this list of conditions and the following disclaimer in the documentation
+.\" * and/or other materials provided with the distribution.
+.\" * - Neither the name of the MontaVista Software, Inc. nor the names of its
+.\" * contributors may be used to endorse or promote products derived from this
+.\" * software without specific prior written permission.
+.\" *
+.\" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+.\" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+.\" * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+.\" * THE POSSIBILITY OF SUCH DAMAGE.
+.\" */
+.TH COROSYNC-CMAP 8 2012-01-23
+.SH NAME
+corosync-cmapctl: \- A tool for accessing the object database.
+.SH DESCRIPTION
+usage: corosync\-cmapctl [\-b] [\-DdghsTt] [\-m map] [\-p filename] [params...]
+.HP
+\fB\-b\fR show binary values
+.HP
+\fB\-m\fR select map to use
+.IP
+The default map is 'icmap' which contains configuration information and some runtime variables
+used by corosync. A 'stats' map is also available which displays network statistics - in
+great detail when knet is used as the transport. Tracking of individual keys (but not prefixes)
+works on the stats map but notifications are sent on a timer, and not every time a value changes.
+
+.SS "Set key:"
+.IP
+corosync\-cmapctl \fB\-s\fR key_name type value
+.IP
+where type is one of ([i|u][8|16|32|64] | flt | dbl | str | bin)
+for bin, value is file name (or \- for stdin)
+.SS "Load settings from a file:"
+.IP
+corosync\-cmapctl \fB\-p\fR filename
+.IP
+the format of the file is:
+[^[^]]<key_name>[ <type> <value>]
+.IP
+Keys prefixed with single caret ('^') are deleted (see \fB\-d\fR).
+.IP
+Keys (actually prefixes) prefixed with double caret ('^^') are deleted by prefix (see \fB\-D\fR).
+.IP
+<type> and <value> are optional (not checked) in above cases.
+.IP
+Other keys are set (see \fB\-s\fR) so both <type> and <value> are required.
+.SS "Delete key:"
+.IP
+corosync\-cmapctl \fB\-d\fR key_name...
+.SS "Delete multiple keys with prefix:"
+.IP
+corosync\-cmapctl \fB\-D\fR key_prefix...
+.SS "Get key:"
+.IP
+corosync\-cmapctl [\-b] \fB\-g\fR key_name...
+.SS "Quiet output:"
+.IP
+corosync\-cmapctl [\-b] \fB\-q\fR \fB\-g\fR key_name...
+.SS "Display all keys:"
+.IP
+corosync\-cmapctl [\-b]
+.SS "Display keys with prefix key_name:"
+.IP
+corosync\-cmapctl [\-b] key_name...
+.SS "Track changes on keys with key_name:"
+.IP
+corosync\-cmapctl [\-b] \fB\-t\fR key_name
+.SS "Track changes on keys with key prefix:"
+.IP
+corosync\-cmapctl [\-b] \fB\-T\fR key_prefix
+.SS "Clear statistics (-mstats is implied)"
+.IP
+corosync\-cmapctl \fB\-C\fR [ipc|totem|knet|all]
+
+.SH "SEE ALSO"
+.BR cmap_overview (3),
+.BR cmap_keys (7)
diff --git a/man/corosync-cpgtool.8 b/man/corosync-cpgtool.8
new file mode 100644
index 0000000..c2b1fd1
--- /dev/null
+++ b/man/corosync-cpgtool.8
@@ -0,0 +1,85 @@
+.\"/*
+.\" * Copyright (C) 2010 Red Hat, Inc.
+.\" *
+.\" * All rights reserved.
+.\" *
+.\" * Author: Angus Salkeld <asalkeld@redhat.com>
+.\" *
+.\" * This software licensed under BSD license, the text of which follows:
+.\" *
+.\" * Redistribution and use in source and binary forms, with or without
+.\" * modification, are permitted provided that the following conditions are met:
+.\" *
+.\" * - Redistributions of source code must retain the above copyright notice,
+.\" * this list of conditions and the following disclaimer.
+.\" * - Redistributions in binary form must reproduce the above copyright notice,
+.\" * this list of conditions and the following disclaimer in the documentation
+.\" * and/or other materials provided with the distribution.
+.\" * - Neither the name of the MontaVista Software, Inc. nor the names of its
+.\" * contributors may be used to endorse or promote products derived from this
+.\" * software without specific prior written permission.
+.\" *
+.\" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+.\" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+.\" * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+.\" * THE POSSIBILITY OF SUCH DAMAGE.
+.\" */
+.TH COROSYNC-CPGTOOL 8 2010-05-30
+.SH NAME
+corosync-cpgtool \- A tool for displaying cpg groups and members.
+.SH SYNOPSIS
+.B "corosync-cpgtool [\-d delimiter] [\-e] [\-n] [\-h]"
+.SH DESCRIPTION
+.B corosync-cpgtool
+A tool for displaying cpg groups and members.
+.SH OPTIONS
+.TP
+.B -d
+Delimiter between fields.
+.TP
+.B -e
+Don't escape unprintable characters in group name.
+.TP
+.B -n
+Display only all existing group names.
+.TP
+.B -h
+Display this help.
+.SH EXAMPLES
+.TP
+Display the groups and process that belong to those cpg groups.
+$ corosync-cpgtool
+.br
+Group Name PID Node ID
+.br
+example-group
+.br
+ 2515 191146176 (192.168.100.11)
+.br
+ 2471 207923392 (192.168.100.12)
+.TP
+Get a comma-delimited list.
+$ corosync-cpgtool -d ","
+.br
+GRP_NAME,PID,NODEID
+.br
+example-group,2515,191146176
+.br
+example-group,2471,207923392
+.TP
+Just get the group names
+$ corosync-cpgtool -n
+.br
+example-group
+.SH SEE ALSO
+.BR corosync_overview (7),
+.SH AUTHOR
+Angus Salkeld
+.PP
diff --git a/man/corosync-keygen.8 b/man/corosync-keygen.8
new file mode 100644
index 0000000..8767ddc
--- /dev/null
+++ b/man/corosync-keygen.8
@@ -0,0 +1,118 @@
+.\"/*
+.\" * Copyright (C) 2010-2019 Red Hat, Inc.
+.\" *
+.\" * All rights reserved.
+.\" *
+.\" * Author: Angus Salkeld <asalkeld@redhat.com>
+.\" *
+.\" * This software licensed under BSD license, the text of which follows:
+.\" *
+.\" * Redistribution and use in source and binary forms, with or without
+.\" * modification, are permitted provided that the following conditions are met:
+.\" *
+.\" * - Redistributions of source code must retain the above copyright notice,
+.\" * this list of conditions and the following disclaimer.
+.\" * - Redistributions in binary form must reproduce the above copyright notice,
+.\" * this list of conditions and the following disclaimer in the documentation
+.\" * and/or other materials provided with the distribution.
+.\" * - Neither the name of the MontaVista Software, Inc. nor the names of its
+.\" * contributors may be used to endorse or promote products derived from this
+.\" * software without specific prior written permission.
+.\" *
+.\" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+.\" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+.\" * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+.\" * THE POSSIBILITY OF SUCH DAMAGE.
+.\" */
+.TH COROSYNC-KEYGEN 8 2019-04-09
+.SH NAME
+corosync-keygen \- Generate an authentication key for Corosync.
+.SH SYNOPSIS
+.B "corosync-keygen [\-k <filename>] [-m <randomfile>] [\-s size] [\-l] [\-h]"
+.SH DESCRIPTION
+
+If you want to configure corosync to use cryptographic techniques to ensure authenticity
+and privacy of the messages, you will need to generate a private key.
+.PP
+.B corosync-keygen
+creates this key and writes it to /etc/corosync/authkey or to file specified by
+-k option.
+.PP
+This private key must be copied to every processor in the cluster. If the
+private key isn't the same for every node, those nodes with nonmatching private
+keys will not be able to join the same configuration.
+.PP
+Copy the key to some security transportable storage or use ssh to transmit the
+key from node to node. Then install the key with the command:
+.PP
+unix#: install -D --group=0 --owner=0 --mode=0400 /path_to_authkey/authkey /etc/corosync/authkey
+.PP
+If a message "Invalid digest" appears from the corosync executive, the keys
+are not consistent between processors.
+.PP
+.SH OPTIONS
+.TP
+.B -k <filename>
+This specifies the fully qualified path to the shared key to create.
+.br
+The default is /etc/corosync/authkey.
+.TP
+.B -r
+Random number source file. Default is /dev/urandom. As an example /dev/random may be
+used when really superb randomness is needed.
+.TP
+.B -s size
+Size of the generated key in bytes. Default is 256 bytes. Allowed range is <128, 4096>.
+.TP
+.TP
+.B -l
+Option is not used and it's kept only for compatibility.
+.TP
+.B -h
+Print basic usage.
+
+.SH EXAMPLES
+.TP
+Generate the key.
+.nf
+# corosync-keygen
+Corosync Cluster Engine Authentication key generator.
+Gathering 2048 bits for key from /dev/urandom.
+Writing corosync key to /etc/corosync/authkey
+.fi
+
+.TP
+Generate longer key and store it in the /tmp/authkey file.
+.nf
+$ corosync-keygen -s 2048 -k /tmp/authkey
+Corosync Cluster Engine Authentication key generator.
+Gathering 16384 bits for key from /dev/urandom.
+Writing corosync key to /tmp/authkey.
+.fi
+
+.TP
+Generate superb key using /dev/random
+.nf
+# corosync-keygen -r /dev/random
+Gathering 2048 bits for key from /dev/random.
+Press keys on your keyboard to generate entropy.
+Press keys on your keyboard to generate entropy (1128 bits still needed).
+Press keys on your keyboard to generate entropy (504 bits still needed).
+Press keys on your keyboard to generate entropy (128 bits still needed).
+Press keys on your keyboard to generate entropy (32 bits still needed).
+Writing corosync key to /etc/corosync/authkey.
+.fi
+
+.SH SEE ALSO
+.BR corosync_overview (7),
+.BR corosync.conf (5),
+.SH AUTHOR
+Angus Salkeld
+.PP
diff --git a/man/corosync-notifyd.8 b/man/corosync-notifyd.8
new file mode 100644
index 0000000..05a91a2
--- /dev/null
+++ b/man/corosync-notifyd.8
@@ -0,0 +1,148 @@
+.\"/*
+.\" * Copyright (C) 2010 Red Hat, Inc.
+.\" *
+.\" * All rights reserved.
+.\" *
+.\" * Author: Angus Salkeld <asalkeld@redhat.com>
+.\" *
+.\" * This software licensed under BSD license, the text of which follows:
+.\" *
+.\" * Redistribution and use in source and binary forms, with or without
+.\" * modification, are permitted provided that the following conditions are met:
+.\" *
+.\" * - Redistributions of source code must retain the above copyright notice,
+.\" * this list of conditions and the following disclaimer.
+.\" * - Redistributions in binary form must reproduce the above copyright notice,
+.\" * this list of conditions and the following disclaimer in the documentation
+.\" * and/or other materials provided with the distribution.
+.\" * - Neither the name of Red Hat, Inc. nor the names of its
+.\" * contributors may be used to endorse or promote products derived from this
+.\" * software without specific prior written permission.
+.\" *
+.\" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+.\" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+.\" * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+.\" * THE POSSIBILITY OF SUCH DAMAGE.
+.\" */
+.TH COROSYNC-NOTIFYD 8 2011-01-14
+.SH NAME
+corosync-notifyd \- Listen for important corosync events and send dbus and/or snmp traps.
+.SH SYNOPSIS
+.B "corosync-notifyd [\-f] [\-l] [\-o] [\-s] [\-m manager] [\-d] [-h]"
+.SH DESCRIPTION
+.B corosync-notifyd
+uses corosync API to listen for important cluster events and can log them,
+generate dbus signals or generate snmp traps.
+.SH OPTIONS
+.TP
+.B -f
+Start application in foreground.
+.TP
+.B -l
+Log all events.
+.TP
+.B -o
+Print events to stdout (turns on -l).
+.TP
+.B -s
+Send SNMP traps on all events.
+.TP
+.B -m
+Set the SNMP Manager IP address (defaults to localhost).
+.TP
+.B -n
+No reverse DNS lookup on cmap member change events.
+.TP
+.B -d
+Send DBUS signals on all events.
+.TP
+.B -h
+Print this help.
+.SH EXAMPLES
+.br
+$ corosync-notifyd -o
+.br
+corosync-notifyd[18505]: troll[23374016] corosync-notify:18505:12 is now connected to corosync
+.br
+corosync-notifyd[18505]: troll[23374016] corosync-notify:18505:13 is now disconnected from corosync
+.br
+corosync-notifyd[18505]: troll[23374016] is now quorate
+.br
+corosync-notifyd[18505]: r2[1550100672] ip:192.168.100.92 joined
+.br
+corosync-notifyd[18505]: r2[1550100672] ip:192.168.100.92 left
+.br
+
+.br
+$ corosync-notifyd -d
+.br
+
+Note this output below is from "dbus-monitor --system"
+
+.br
+signal sender=:1.216 -> dest=(null destination) serial=2 path=/com/redhat/cluster/corosync;
+ interface=com.redhat.cluster.corosync; member=ConnectionStateChange
+.br
+ string "troll"
+.br
+ uint32 23374016
+.br
+ string "corosync-notify:18900:12"
+.br
+ string "connected"
+.br
+signal sender=:1.216 -> dest=(null destination) serial=3 path=/com/redhat/cluster/corosync;
+ interface=com.redhat.cluster.corosync; member=ConnectionStateChange
+.br
+ string "troll"
+.br
+ uint32 23374016
+.br
+ string "corosync-notify:18900:13"
+.br
+ string "disconnected"
+.br
+signal sender=:1.216 -> dest=(null destination) serial=4 path=/com/redhat/cluster/corosync;
+ interface=com.redhat.cluster.corosync; member=QorumStateChange
+.br
+ string "troll"
+.br
+ uint32 23374016
+.br
+ string "quorate"
+.br
+signal sender=:1.216 -> dest=(null destination) serial=5 path=/com/redhat/cluster/corosync;
+ interface=com.redhat.cluster.corosync; member=NodeStateChange
+.br
+ string "r2"
+.br
+ uint32 1550100672
+.br
+ string "192.168.100.92"
+.br
+ string "joined"
+.br
+signal sender=:1.216 -> dest=(null destination) serial=6 path=/com/redhat/cluster/corosync;
+ interface=com.redhat.cluster.corosync; member=NodeStateChange
+.br
+ string "r2"
+.br
+ uint32 1550100672
+.br
+ string "192.168.100.92"
+.br
+ string "left"
+.SH SEE ALSO
+.BR corosync (8),
+.BR corosync-cmapctl (8),
+.BR dbus-monitor (1),
+.SH AUTHOR
+Angus Salkeld
+.PP
diff --git a/man/corosync-quorumtool.8 b/man/corosync-quorumtool.8
new file mode 100644
index 0000000..24c9112
--- /dev/null
+++ b/man/corosync-quorumtool.8
@@ -0,0 +1,112 @@
+.\"/*
+.\" * Copyright (C) 2010,2014 Red Hat, Inc.
+.\" *
+.\" * All rights reserved.
+.\" *
+.\" * Author: Angus Salkeld <asalkeld@redhat.com>
+.\" *
+.\" * This software licensed under BSD license, the text of which follows:
+.\" *
+.\" * Redistribution and use in source and binary forms, with or without
+.\" * modification, are permitted provided that the following conditions are met:
+.\" *
+.\" * - Redistributions of source code must retain the above copyright notice,
+.\" * this list of conditions and the following disclaimer.
+.\" * - Redistributions in binary form must reproduce the above copyright notice,
+.\" * this list of conditions and the following disclaimer in the documentation
+.\" * and/or other materials provided with the distribution.
+.\" * - Neither the name of the MontaVista Software, Inc. nor the names of its
+.\" * contributors may be used to endorse or promote products derived from this
+.\" * software without specific prior written permission.
+.\" *
+.\" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+.\" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+.\" * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+.\" * THE POSSIBILITY OF SUCH DAMAGE.
+.\" */
+.TH COROSYNC-QUORUMTOOL 8 2019-02-14
+.SH NAME
+corosync-quorumtool \- Set and display quorum settings.
+.SH SYNOPSIS
+.B "corosync-quorumtool [\-s] [\-m] [\-l] [\-p] [\-v votes] [\-n nodeid] [\-e expected] [\-H] [\-i] [\-o <a|n|i>] [\-a] [\-f] [\-h] [\-V]"
+.SH DESCRIPTION
+Display the current state of quorum in the cluster and set vote quorum options.
+.SH OPTIONS
+.TP
+.B -s
+show quorum status
+.TP
+.B -m
+constantly monitor quorum status
+.TP
+.B -l
+list nodes
+.TP
+.B -p
+when used with -s or -l, generates machine parsable output
+.TP
+.B -v <votes>
+change the number of votes for a node *
+.TP
+.B -n <nodeid>
+optional nodeid of node for -v
+.TP
+.B -e <expected>
+change expected votes for the cluster *
+.TP
+.B -H
+show nodeids in hexadecimal rather than decimal
+.TP
+.B -i
+show node IP addresses instead of the resolved name
+.TP
+.B -p
+when used with -s or -l, generates machine parsable output
+.TP
+.B -o <a|n|i>
+Orders the output of the nodes list. By default or with -oa nodes are listed in IP address
+order: as they come from corosync. -on will order the nodes based on their name,
+and -oi will order them based on their node ID.
+.TP
+.B -a
+Show the name or IP address (see -i above) of all interfaces in use on the nodes, rather than
+just the first one.
+.TP
+.B -f
+forcefully unregister a quorum device *DANGEROUS* *
+.TP
+.B -h (if no other argument)
+show this help text
+.TP
+.B -V
+show version and exit
+.PP
+* Starred items only work if votequorum is the quorum provider for corosync
+.SH EXIT STATUS
+corosync-quorumtool may return one of several error codes if it encounters problems.
+.TP
+0
+No problems occurred (quorate for
+.B -s
+operation).
+.TP
+1
+Generic error code.
+.TP
+2
+Not quorate (returned only for
+.B -s
+operation).
+.SH SEE ALSO
+.BR corosync_overview (7),
+.BR votequorum_overview (3),
+.SH AUTHOR
+Angus Salkeld
+.PP
diff --git a/man/corosync-vqsim.8 b/man/corosync-vqsim.8
new file mode 100644
index 0000000..26a6468
--- /dev/null
+++ b/man/corosync-vqsim.8
@@ -0,0 +1,94 @@
+.\"/*
+.\" * Copyright (C) 2019 Red Hat, Inc.
+.\" *
+.\" * All rights reserved.
+.\" *
+.\" * Author: Christine Caulfield <ccaulfie@redhat.com>
+.\" *
+.\" * This software licensed under BSD license, the text of which follows:
+.\" *
+.\" * Redistribution and use in source and binary forms, with or without
+.\" * modification, are permitted provided that the following conditions are met:
+.\" *
+.\" * - Redistributions of source code must retain the above copyright notice,
+.\" * this list of conditions and the following disclaimer.
+.\" * - Redistributions in binary form must reproduce the above copyright notice,
+.\" * this list of conditions and the following disclaimer in the documentation
+.\" * and/or other materials provided with the distribution.
+.\" * - Neither the name of the MontaVista Software, Inc. nor the names of its
+.\" * contributors may be used to endorse or promote products derived from this
+.\" * software without specific prior written permission.
+.\" *
+.\" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+.\" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+.\" * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+.\" * THE POSSIBILITY OF SUCH DAMAGE.
+.\" */
+.TH COROSYNC-VQSIM 8 2019-05-10
+.SH NAME
+corosync-vqsim \- The votequorum simulator
+.SH SYNOPSIS
+.B "corosync-vqsim [\-c config_file] [\-o output file] [\-n] [\-h]"
+.SH DESCRIPTION
+.B corosync-vqsim
+simulates the quorum functions of corosync in a single program. it can simulate
+multiple nodes, network splits and a basic quorum device.
+
+By default vqsim will build a virtual cluster of all the nodes in the corosync.conf file,
+each 'node' running in a forked subprocess (and thus asynchronously). It then provides a
+command-line interface to add (up) or remove (down) nodes, and cause network splits and
+rejoins. After each event it shows the new quorum status for all nodes.
+
+Nodes in vqsim are always referred to by their nodeid (the IP address is meaningless) and
+optionally by a 'partition' which precedes the nodeid with a colon. By default all nodes
+are in partition 0. Nodes can be moved between partitions using the split and join commands.
+Multiple nodes can be split and joined at the same time.
+
+To script vqsim you must send input to it via a pipe rather than just redirecting STDIN. This
+is because it runs asynchronously to enable the virtual 'nodes' to report status when needed.
+(eg if you kill a subprocess using the 'kill(1)' command it gets removed from the cluster).
+
+By default vqsim will wait for all nodes in all partitions to reach the same
+ring sequence number before returning a prompt,
+there is a timeout associated with this in case of a 'node' failure and exceeding this timeout
+can (optionally) quit the program signalling an error.
+
+You can disable waiting using the 'sync off' command or the -n command-line option. This can easily
+cause unexpected behaviour so use it with care.
+
+The number of votes per node is read from corosync.conf. New nodes added using the 'up' command
+will copy their number of votes from the first node in corosync.conf. This may not be what you
+expect and I might fix it in future. As most clusters have only 1 vote per node (and this is
+strongly recommended) then this should rarely be a problem.
+
+Once you have the 'vqsim> ' prompt you can type 'help' and get a list of sub-commands.
+
+.SH OPTIONS
+.TP
+.B -c
+This specifies the fully qualified path to the corosync configuration file.
+
+The default is /etc/corosync/corosync.conf.
+.TP
+.B -o
+Specifies the output destination. STDOUT by default.
+.TP
+.B -n
+Don't pause after each command, come straight back to a prompt. Use with care!
+
+.TP
+.B -h
+Display a brief help message
+.SH SEE ALSO
+.BR corosync (9),
+.BR corosync.conf (5),
+.SH AUTHOR
+Christine Caulfield
+.PP
diff --git a/man/corosync-xmlproc.8 b/man/corosync-xmlproc.8
new file mode 100644
index 0000000..dc4d4bd
--- /dev/null
+++ b/man/corosync-xmlproc.8
@@ -0,0 +1,57 @@
+.\"/*
+.\" * Copyright (C) 2011 Red Hat, Inc.
+.\" *
+.\" * All rights reserved.
+.\" *
+.\" * Author: Jan Friesse <jfriesse@redhat.com>
+.\" *
+.\" * This software licensed under BSD license, the text of which follows:
+.\" *
+.\" * Redistribution and use in source and binary forms, with or without
+.\" * modification, are permitted provided that the following conditions are met:
+.\" *
+.\" * - Redistributions of source code must retain the above copyright notice,
+.\" * this list of conditions and the following disclaimer.
+.\" * - Redistributions in binary form must reproduce the above copyright notice,
+.\" * this list of conditions and the following disclaimer in the documentation
+.\" * and/or other materials provided with the distribution.
+.\" * - Neither the name of Red Hat, Inc. nor the names of its
+.\" * contributors may be used to endorse or promote products derived from this
+.\" * software without specific prior written permission.
+.\" *
+.\" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+.\" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+.\" * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+.\" * THE POSSIBILITY OF SUCH DAMAGE.
+.\" */
+.TH COROSYNC-XMLPROC 8 2011-12-16
+.SH NAME
+corosync-xmlproc \- Converts corosync.xml to the Corosync configuration file.
+.SH SYNOPSIS
+.B "corosync-xmlproc input_xml [output_file]"
+.SH DESCRIPTION
+.B corosync-xmlproc
+Converts valid corosync.xml file to the Corosync configuration file format. Command internally
+uses
+.B
+xsltproc
+for XML conversion.
+.SH OPTIONS
+.TP
+.B input_xml
+Valid XML file to convert.
+.TP
+.B output_file
+Destination file name. If parameter is - or omitted, output is written to standard output.
+.SH SEE ALSO
+.BR corosync.xml (5)
+.SH AUTHOR
+Jan Friesse
+.PP
diff --git a/man/corosync.8 b/man/corosync.8
new file mode 100644
index 0000000..5d219b1
--- /dev/null
+++ b/man/corosync.8
@@ -0,0 +1,70 @@
+.\"/*
+.\" * Copyright (C) 2010-2021 Red Hat, Inc.
+.\" *
+.\" * All rights reserved.
+.\" *
+.\" * Author: Angus Salkeld <asalkeld@redhat.com>
+.\" *
+.\" * This software licensed under BSD license, the text of which follows:
+.\" *
+.\" * Redistribution and use in source and binary forms, with or without
+.\" * modification, are permitted provided that the following conditions are met:
+.\" *
+.\" * - Redistributions of source code must retain the above copyright notice,
+.\" * this list of conditions and the following disclaimer.
+.\" * - Redistributions in binary form must reproduce the above copyright notice,
+.\" * this list of conditions and the following disclaimer in the documentation
+.\" * and/or other materials provided with the distribution.
+.\" * - Neither the name of the MontaVista Software, Inc. nor the names of its
+.\" * contributors may be used to endorse or promote products derived from this
+.\" * software without specific prior written permission.
+.\" *
+.\" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+.\" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+.\" * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+.\" * THE POSSIBILITY OF SUCH DAMAGE.
+.\" */
+.TH COROSYNC 8 2021-04-09
+.SH NAME
+corosync \- The Corosync Cluster Engine.
+.SH SYNOPSIS
+.B "corosync [\-c config_file] [\-f] [\-t] [\-v]"
+.SH DESCRIPTION
+.B corosync
+Corosync provides clustering infrastructure such as membership, messaging and quorum.
+.SH OPTIONS
+.TP
+.B -c
+This specifies the fully qualified path to the corosync configuration file. Also used
+as a base directory for uidgid files.
+
+The default is /etc/corosync/corosync.conf.
+.TP
+.B -f
+Start application in foreground.
+.TP
+.B -t
+Test configuration and then exit.
+.TP
+.B -v
+Display version, git revision, compiled features and available crypto and compression
+models and exit.
+
+.SH SEE ALSO
+.BR corosync_overview (7),
+.BR corosync.conf (5),
+.BR cpg_overview (3),
+.BR votequorum_overview (3),
+.BR sam_overview (3),
+.BR cmap_overview (3),
+.BR quorum_overview (3)
+.SH AUTHOR
+Angus Salkeld
+.PP
diff --git a/man/corosync.conf.5 b/man/corosync.conf.5
new file mode 100644
index 0000000..e76d64e
--- /dev/null
+++ b/man/corosync.conf.5
@@ -0,0 +1,1061 @@
+.\"/*
+.\" * Copyright (c) 2005 MontaVista Software, Inc.
+.\" * Copyright (c) 2006-2022 Red Hat, Inc.
+.\" *
+.\" * All rights reserved.
+.\" *
+.\" * Author: Steven Dake (sdake@redhat.com)
+.\" *
+.\" * This software licensed under BSD license, the text of which follows:
+.\" *
+.\" * Redistribution and use in source and binary forms, with or without
+.\" * modification, are permitted provided that the following conditions are met:
+.\" *
+.\" * - Redistributions of source code must retain the above copyright notice,
+.\" * this list of conditions and the following disclaimer.
+.\" * - Redistributions in binary form must reproduce the above copyright notice,
+.\" * this list of conditions and the following disclaimer in the documentation
+.\" * and/or other materials provided with the distribution.
+.\" * - Neither the name of the MontaVista Software, Inc. nor the names of its
+.\" * contributors may be used to endorse or promote products derived from this
+.\" * software without specific prior written permission.
+.\" *
+.\" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+.\" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+.\" * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+.\" * THE POSSIBILITY OF SUCH DAMAGE.
+.\" */
+.TH COROSYNC_CONF 5 2022-10-20 "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
+.SH NAME
+corosync.conf - corosync executive configuration file
+
+.SH SYNOPSIS
+/etc/corosync/corosync.conf
+
+.SH DESCRIPTION
+The corosync.conf instructs the corosync executive about various parameters
+needed to control the corosync executive. Empty lines and lines starting with
+# character are ignored. The configuration file consists of bracketed top level
+directives. The possible directive choices are:
+
+.TP
+totem { }
+This top level directive contains configuration options for the totem protocol.
+.TP
+logging { }
+This top level directive contains configuration options for logging.
+.TP
+quorum { }
+This top level directive contains configuration options for quorum.
+.TP
+nodelist { }
+This top level directive contains configuration options for nodes in cluster.
+.TP
+system { }
+This top level directive contains configuration options related to system.
+.TP
+resources { }
+This top level directive contains configuration options for resources.
+.TP
+nozzle { }
+This top level directive contains configuration options for a libnozzle device.
+
+.PP
+The
+.B interface sub-directive of totem is optional for UDP and knet transports.
+
+For knet, multiple interface subsections define parameters for each knet link on the
+system.
+
+For UDPU an interface section is not needed and it is recommended that the nodelist
+is used to define cluster nodes.
+
+.TP
+linknumber
+This specifies the link number for the interface. When using the knet
+protocol, each interface should specify separate link numbers to uniquely
+identify to the membership protocol which interface to use for which link.
+The linknumber must start at 0. For UDP the only supported linknumber is 0.
+
+.TP
+knet_link_priority
+This specifies the priority for the link when knet is used in 'passive'
+mode. (see link_mode below)
+
+.TP
+knet_ping_interval
+This specifies the interval between knet link pings.
+knet_ping_interval and knet_ping_timeout
+are a pair, if one is specified the other should be too, otherwise one will be calculated from
+the token timeout and one will be taken from the config file.
+(default is token timeout / (knet_pong_count*2))
+
+.TP
+knet_ping_timeout
+If no ping is received within this time, the knet link is declared dead.
+knet_ping_interval and knet_ping_timeout
+are a pair, if one is specified the other should be too, otherwise one will be calculated from
+the token timeout and one will be taken from the config file.
+(default is token timeout / knet_pong_count)
+
+.TP
+knet_ping_precision
+How many values of latency are used to calculate
+the average link latency. (default 2048 samples)
+
+.TP
+knet_pong_count
+How many valid ping/pongs before a link is marked UP. (default 2)
+.TP
+
+knet_transport
+Which IP transport knet should use. valid values are "sctp" or "udp". (default: udp)
+
+.TP
+bindnetaddr (udp only)
+This specifies the network address the corosync executive should bind
+to when using udp.
+
+bindnetaddr (udp only)
+should be an IP address configured on the system, or a network
+address.
+
+For example, if the local interface is 192.168.5.92 with netmask
+255.255.255.0, you should set bindnetaddr to 192.168.5.92 or 192.168.5.0.
+If the local interface is 192.168.5.92 with netmask 255.255.255.192,
+set bindnetaddr to 192.168.5.92 or 192.168.5.64, and so forth.
+
+This may also be an IPV6 address, in which case IPV6 networking will be used.
+In this case, the exact address must be specified and there is no automatic
+selection of the network interface within a specific subnet as with IPv4.
+
+If IPv6 networking is used, the nodeid field in nodelist must be specified.
+
+.TP
+broadcast (udp only)
+This is optional and can be set to yes. If it is set to yes, the broadcast
+address will be used for communication. If this option is set, mcastaddr
+should not be set.
+
+.TP
+mcastaddr (udp only)
+This is the multicast address used by corosync executive. The default
+should work for most networks, but the network administrator should be queried
+about a multicast address to use. Avoid 224.x.x.x because this is a "config"
+multicast address.
+
+This may also be an IPV6 multicast address, in which case IPV6 networking
+will be used. If IPv6 networking is used, the nodeid field in nodelist must
+be specified.
+
+It's not necessary to use this option if cluster_name option is used. If both options
+are used, mcastaddr has higher priority.
+
+.TP
+mcastport (udp only)
+This specifies the UDP port number. It is possible to use the same multicast
+address on a network with the corosync services configured for different
+UDP ports.
+Please note corosync uses two UDP ports mcastport (for mcast receives) and
+mcastport - 1 (for mcast sends).
+If you have multiple clusters on the same network using the same mcastaddr
+please configure the mcastports with a gap.
+
+.TP
+ttl (udp only)
+This specifies the Time To Live (TTL). If you run your cluster on a routed
+network then the default of "1" will be too small. This option provides
+a way to increase this up to 255. The valid range is 0..255.
+
+.PP
+.PP
+Within the
+.B totem
+directive, there are seven configuration options of which one is required,
+five are optional, and one is required when IPV6 is configured in the interface
+subdirective. The required directive controls the version of the totem
+configuration. The optional option unless using IPV6 directive controls
+identification of the processor. The optional options control secrecy and
+authentication, the network mode of operation and maximum network MTU
+field.
+
+.TP
+version
+This specifies the version of the configuration file. Currently the only
+valid version for this directive is 2.
+
+.TP
+clear_node_high_bit
+This configuration option is optional and is only relevant when no nodeid is
+specified. Some corosync clients require a signed 32 bit nodeid that is greater
+than zero however by default corosync uses all 32 bits of the IPv4 address space
+when generating a nodeid. Set this option to yes to force the high bit to be
+zero and therefore ensure the nodeid is a positive signed 32 bit integer.
+
+WARNING: Cluster behavior is undefined if this option is enabled on only
+a subset of the cluster (for example during a rolling upgrade).
+
+.TP
+crypto_model
+This specifies which cryptographic library should be used by knet.
+Supported values depend on the libknet build and on the installed
+cryptography libraries. Typically nss and openssl will be available
+but gcrypt and others could also be allowed.
+
+The default is nss.
+
+.TP
+crypto_hash
+This specifies which HMAC authentication should be used to authenticate all
+messages. Valid values are none (no authentication), md5, sha1, sha256,
+sha384 and sha512. Encrypted transmission is only supported for
+the knet transport.
+
+The default is none.
+
+.TP
+crypto_cipher
+This specifies which cipher should be used to encrypt all messages.
+Valid values are none (no encryption), aes256, aes192 and aes128.
+Enabling crypto_cipher, requires also enabling of crypto_hash. Encrypted
+transmission is only supported for the knet transport.
+
+The default is none.
+
+.TP
+secauth
+This implies crypto_cipher=aes256 and crypto_hash=sha256, unless those options
+are explicitly set. Encrypted transmission is only supported for the knet
+transport.
+
+The default is off.
+
+.TP
+keyfile
+This specifies the fully qualified path to the shared key used to
+authenticate and encrypt data used within the Totem protocol.
+
+The default is /etc/corosync/authkey.
+
+.TP
+key
+Shared key stored in configuration instead of authkey file. This option
+has lower precedence than keyfile option so it's
+used only when keyfile is not specified.
+Using this option is not recommended for security reasons.
+
+.TP
+link_mode
+This specifies the Kronosnet mode, which may be passive, active, or
+rr (round-robin).
+.B passive:
+the active link with the highest priority (highest number) will be used. If one or more
+links share the same priority the one with the lowest link ID will
+be used.
+.B active:
+All active links will be used simultaneously to send traffic.
+link priority is ignored.
+.B rr:
+Round-Robin policy. Each packet will be sent to the next active link in
+order.
+
+If only one interface directive is specified, passive is automatically chosen.
+
+The maximum number of interface directives that is allowed with Kronosnet
+is 8. For other transports it is 1.
+
+.TP
+netmtu
+This specifies maximum packet length sent by corosync. It's mainly for the UDPU
+(and UDP) transport, where it specifies the network maximum transmit size, but
+can be used also with the KNET transport, where it defines the maximum length of packets
+passed to the knet layer. To specify the network MTU manually for KNET, use the
+.B knet_mtu
+option.
+
+For UDPU (and UDP), setting this value beyond 1500, the regular frame MTU,
+requires ethernet devices that support large, or
+also called jumbo, frames. If any device in the network doesn't support large
+frames, the protocol will not operate properly. The hosts must also have their
+mtu size set from 1500 to whatever frame size is specified here.
+
+Please note while some NICs or switches claim large frame support, they support
+9000 MTU as the maximum frame size including the IP header. Setting the netmtu
+and host MTUs to 9000 will cause totem to use the full 9000 bytes of the frame.
+Then Linux will add a 18 byte header moving the full frame size to 9018. As a
+result some hardware will not operate properly with this size of data. A netmtu
+of 8982 seems to work for the few large frame devices that have been tested.
+Some manufacturers claim large frame support when in fact they support frame
+sizes of 4500 bytes.
+
+When sending multicast traffic, if the network frequently reconfigures, chances are
+that some device in the network doesn't support large frames.
+
+Choose hardware carefully if intending to use large frame support.
+
+The default is 1500 for UDPU (and UDP) and 65536 for the KNET transport.
+
+.TP
+transport
+This directive controls the transport mechanism used.
+The default is knet. The transport type can also be set to udpu or udp.
+Only knet allows crypto or multiple interfaces per node.
+
+.TP
+cluster_name
+This specifies the name of cluster and it's used for automatic generating
+of multicast address.
+
+.TP
+config_version
+This specifies version of config file. This is converted to unsigned 64-bit int.
+By default it's 0. Option is used to prevent joining old nodes with not
+up-to-date configuration. If value is not 0, and node is going for first time
+(only for first time, join after split doesn't follow this rules)
+from single-node membership to multiple nodes membership, other nodes
+config_versions are collected. If current node config_version is not
+equal to highest of collected versions, corosync is terminated.
+
+.TP
+ip_version
+This specifies version of IP to ask DNS resolver for.
+The value can be one of
+.B ipv4
+(look only for an IPv4 address)
+,
+.B ipv6
+(check only IPv6 address)
+,
+.B ipv4-6
+(look for all address families and use first IPv4 address found in the list if there is such address,
+otherwise use first IPv6 address) and
+.B ipv6-4
+(look for all address families and use first IPv6 address found in the list if there is such address,
+otherwise use first IPv4 address).
+
+Default (if unspecified) is
+.B ipv6-4
+for knet and udpu transports and
+.B ipv4
+for udp.
+
+The knet transport supports IPv4 and IPv6 addresses concurrently,
+provided they are consistent on each link.
+
+Within the
+.B totem
+directive, there are several configuration options which are used to control
+the operation of the protocol. It is generally not recommended to change any
+of these values without proper guidance and sufficient testing. Some networks
+may require larger values if suffering from frequent reconfigurations. Some
+applications may require faster failure detection times which can be achieved
+by reducing the token timeout.
+
+.TP
+token
+This timeout is used directly or as a base for real token timeout calculation (explained in
+.B token_coefficient
+section). Token timeout specifies in milliseconds until a token loss is declared after not
+receiving a token. This is the time spent detecting a failure of a processor
+in the current configuration. Reforming a new configuration takes about 50
+milliseconds in addition to this timeout.
+
+For real token timeout used by totem it's possible to read cmap value of
+.B runtime.config.totem.token
+key.
+
+Be careful to use the same timeout values on each of the nodes in the cluster
+or unpredictable results may occur.
+
+The default is 3000 milliseconds.
+
+.TP
+token_warning
+Specifies the interval between warnings that the token has not been received. The
+value is a percentage of the token timeout and can be set to 0 to disable
+warnings.
+
+The default is 75%.
+
+.TP
+token_coefficient
+This value is used only when
+.B nodelist
+section is specified and contains at least 3 nodes. If so, real token timeout
+is then computed as token + (number_of_nodes - 2) * token_coefficient.
+This allows cluster to scale without manually changing token timeout
+every time new node is added. This value can be set to 0 resulting
+in effective removal of this feature.
+
+The default is 650 milliseconds.
+
+.TP
+token_retransmit
+This timeout specifies in milliseconds after how long before receiving a token
+the token is retransmitted. This will be automatically calculated if token
+is modified. It is not recommended to alter this value without guidance from
+the corosync community.
+
+The minimum is 30 milliseconds. If not set and error occur, make sure
+token / (token_retransmits_before_loss_const + 0.2) is more than 30.
+
+The default is 238 milliseconds for two nodes cluster. Three or more nodes reference
+.B token_coefficient.
+
+.TP
+knet_compression_model
+Type of compression used by Kronosnet. Supported values depend on
+the libknet build and on the installed compression libraries. Typically zlib and lz4 will be available
+but bzip2 and others could also be allowed. The default is 'none'.
+
+.TP
+knet_compression_threshold
+Tells knet to NOT compress any packets that are smaller than the value
+indicated. Default 100 bytes.
+
+Set to 0 to reset to the default.
+Set to 1 to compress everything.
+
+.TP
+knet_compression_level
+Many compression libraries allow tuning of compression parameters. For example
+0 or 1 ... 9 are commonly used to determine the level of compression. This value
+is passed unmodified to the compression library so it is recommended to consult
+the library's documentation for more detailed information.
+
+.TP
+hold
+This timeout specifies in milliseconds how long the token should be held by
+the representative when the protocol is under low utilization. It is not
+recommended to alter this value without guidance from the corosync community.
+
+The default is 180 milliseconds.
+
+.TP
+token_retransmits_before_loss_const
+This value identifies how many token retransmits should be attempted before
+forming a new configuration. It is also used for token_retransmit
+and hold calculations.
+
+The default is 4 retransmissions.
+
+.TP
+join
+This timeout specifies in milliseconds how long to wait for join messages in
+the membership protocol.
+
+The default is 50 milliseconds.
+
+.TP
+send_join
+This timeout specifies in milliseconds an upper range between 0 and send_join
+to wait before sending a join message. For configurations with less than
+32 nodes, this parameter is not necessary. For larger rings, this parameter
+is necessary to ensure the NIC is not overflowed with join messages on
+formation of a new ring. A reasonable value for large rings (128 nodes) would
+be 80msec. Other timer values must also change if this value is changed. Seek
+advice from the corosync mailing list if trying to run larger configurations.
+
+The default is 0 milliseconds.
+
+.TP
+consensus
+This timeout specifies in milliseconds how long to wait for consensus to be
+achieved before starting a new round of membership configuration. The minimum
+value for consensus must be 1.2 * token. This value will be automatically
+calculated at 1.2 * token if the user doesn't specify a consensus value.
+
+For two node clusters, a consensus larger than the join timeout but less than
+token is safe. For three node or larger clusters, consensus should be larger
+than token. There is an increasing risk of odd membership changes, which still
+guarantee virtual synchrony, as node count grows if consensus is less than
+token.
+
+The default is 3600 milliseconds.
+
+.TP
+merge
+This timeout specifies in milliseconds how long to wait before checking for
+a partition when no multicast traffic is being sent. If multicast traffic
+is being sent, the merge detection happens automatically as a function of
+the protocol.
+
+The default is 200 milliseconds.
+
+.TP
+downcheck
+This timeout specifies in milliseconds how long to wait before checking
+that a network interface is back up after it has been downed.
+
+The default is 1000 milliseconds.
+
+.TP
+fail_recv_const
+This constant specifies how many rotations of the token without receiving any
+of the messages when messages should be received may occur before a new
+configuration is formed.
+
+The default is 2500 failures to receive a message.
+
+.TP
+seqno_unchanged_const
+This constant specifies how many rotations of the token without any multicast
+traffic should occur before the hold timer is started.
+
+The default is 30 rotations.
+
+.TP
+heartbeat_failures_allowed
+[HeartBeating mechanism]
+Configures the optional HeartBeating mechanism for faster failure detection. Keep in
+mind that engaging this mechanism in lossy networks could cause faulty loss declaration
+as the mechanism relies on the network for heartbeating.
+
+So as a rule of thumb use this mechanism if you require improved failure in low to
+medium utilized networks.
+
+This constant specifies the number of heartbeat failures the system should tolerate
+before declaring heartbeat failure e.g 3. Also if this value is not set or is 0 then the
+heartbeat mechanism is not engaged in the system and token rotation is the method
+of failure detection
+
+The default is 0 (disabled).
+
+.TP
+max_network_delay
+[HeartBeating mechanism]
+This constant specifies in milliseconds the approximate delay that your network takes
+to transport one packet from one machine to another. This value is to be set by system
+engineers and please don't change if not sure as this effects the failure detection
+mechanism using heartbeat.
+
+The default is 50 milliseconds.
+
+.TP
+window_size
+This constant specifies the maximum number of messages that may be sent on one
+token rotation. If all processors perform equally well, this value could be
+large (300), which would introduce higher latency from origination to delivery
+for very large rings. To reduce latency in large rings(16+), the defaults are
+a safe compromise. If 1 or more slow processor(s) are present among fast
+processors, window_size should be no larger than 256000 / netmtu to avoid
+overflow of the kernel receive buffers. The user is notified of this by
+the display of a retransmit list in the notification logs. There is no loss
+of data, but performance is reduced when these errors occur.
+
+The default is 50 messages.
+
+.TP
+max_messages
+This constant specifies the maximum number of messages that may be sent by one
+processor on receipt of the token. The max_messages parameter is limited to
+256000 / netmtu to prevent overflow of the kernel transmit buffers.
+
+The default is 17 messages.
+
+.TP
+miss_count_const
+This constant defines the maximum number of times on receipt of a token
+a message is checked for retransmission before a retransmission occurs. This
+parameter is useful to modify for switches that delay multicast packets
+compared to unicast packets. The default setting works well for nearly all
+modern switches.
+
+The default is 5 messages.
+
+.TP
+knet_pmtud_interval
+How often the knet PMTUd runs to look for network MTU changes.
+Value in seconds, default: 30
+
+.TP
+knet_mtu
+Switch between manual and automatic MTU discovery. A value of 0 means
+automatic, other values set a manual MTU.
+In a setup with multiple interfaces, please specify
+the lowest MTU of the selected interfaces.
+
+The default value is 0.
+
+.TP
+block_unlisted_ips
+Allow UDPU and KNET to drop packets from IP addresses that are not known
+(nodes which don't exist in the nodelist) to corosync.
+Value is yes or no.
+
+This feature is mainly to protect against the joining of nodes
+with outdated configurations after a cluster split.
+Another use case is to allow the atomic merge of two independent clusters.
+
+Changing the default value is not recommended, the overhead is tiny and
+an existing cluster may fail if corosync is started on an unlisted node
+with an old configuration.
+
+The default value is yes.
+
+.TP
+cancel_token_hold_on_retransmit
+Allows Corosync to hold token by representative when there is too much
+retransmit messages. This allows network to process increased load without
+overloading it. Used mechanism is same as described for
+.B hold
+directive.
+
+Some deployments may prefer to never hold token when there is
+retransmit messages. If so, option should be set to yes.
+
+The default value is no.
+
+.PP
+Within the
+.B logging
+directive, there are several configuration options which are all optional.
+
+.PP
+The following 3 options are valid only for the top level logging directive:
+
+.TP
+timestamp
+This specifies that a timestamp is placed on all log messages. It can be one
+of off (no timestamp), on (second precision timestamp) or
+hires (millisecond precision timestamp - only when supported by LibQB).
+
+The default is hires (or on if hires is not supported).
+
+.TP
+fileline
+This specifies that file and line should be printed.
+
+The default is off.
+
+.TP
+function_name
+This specifies that the code function name should be printed.
+
+The default is off.
+
+.TP
+blackbox
+This specifies that blackbox functionality should be enabled.
+
+The default is on.
+
+.PP
+The following options are valid both for top level logging directive
+and they can be overridden in logger_subsys entries.
+
+.TP
+to_stderr
+.TP
+to_logfile
+.TP
+to_syslog
+These specify the destination of logging output. Any combination of
+these options may be specified. Valid options are
+.B yes
+and
+.B no.
+
+The default is syslog and stderr.
+
+Please note, if you are using to_logfile and want to rotate the file, use logrotate(8)
+with the option
+.B
+copytruncate.
+eg.
+.ne 18
+.RS
+.nf
+.ft CW
+/var/log/corosync.log {
+ missingok
+ compress
+ notifempty
+ daily
+ rotate 7
+ copytruncate
+}
+.ft
+.fi
+.RE
+
+.TP
+logfile
+If the
+.B to_logfile
+directive is set to
+.B yes
+, this option specifies the pathname of the log file.
+
+No default.
+
+.TP
+logfile_priority
+This specifies the logfile priority for this particular subsystem. Ignored if debug is on.
+Possible values are: alert, crit, debug (same as debug = on), emerg, err, info, notice, warning.
+
+The default is: info.
+
+.TP
+syslog_facility
+This specifies the syslog facility type that will be used for any messages
+sent to syslog. options are daemon, local0, local1, local2, local3, local4,
+local5, local6 & local7.
+
+The default is daemon.
+
+.TP
+syslog_priority
+This specifies the syslog level for this particular subsystem. Ignored if debug is on.
+Possible values are: alert, crit, debug (same as debug = on), emerg, err, info, notice, warning.
+
+The default is: info.
+
+.TP
+debug
+This specifies whether debug output is logged for this particular logger. Also can contain
+value trace, what is highest level of debug information.
+
+The default is off.
+
+.PP
+Within the
+.B logging
+directive, logger_subsys directives are optional.
+
+.PP
+Within the
+.B logger_subsys
+sub-directive, all of the above logging configuration options are valid and
+can be used to override the default settings.
+The subsys entry, described below, is mandatory to identify the subsystem.
+
+.TP
+subsys
+This specifies the subsystem identity (name) for which logging is specified. This is the
+name used by a service in the log_init() call. E.g. 'CPG'. This directive is
+required.
+
+.PP
+Within the
+.B quorum
+directive it is possible to specify the quorum algorithm to use with the
+
+.TP
+provider
+directive. At the time of writing only corosync_votequorum is supported.
+See votequorum(5) for configuration options.
+
+.PP
+Within the
+.B nodelist
+directive it is possible to specify specific information about nodes in cluster. Directive
+can contain only
+.B node
+sub-directive, which specifies every node that should be a member of the membership, and where
+non-default options are needed. Every node must have at least ring0_addr field filled.
+
+Every node that should be a member of the membership must be specified.
+
+Possible options are:
+.TP
+ringX_addr
+This specifies IP or network hostname address of the particular node.
+X is a link number.
+
+.TP
+nodeid
+This configuration option is required for each node for Kronosnet mode.
+It is a 32 bit value specifying the node identifier delivered to the
+cluster membership service. The node identifier value of zero is
+reserved and should not be used. If knet is set, this field must be set.
+
+.TP
+name
+This option is used mainly with knet transport to identify local node.
+It's also used by client software (pacemaker).
+Algorithm for identifying local node is following:
+.RS
+.IP 1.
+Looks up $HOSTNAME in the nodelist
+.IP 2.
+If this fails strip the domain name from $HOSTNAME and looks up
+that in the nodelist
+.IP 3.
+If this fails look in the nodelist for a fully-qualified name whose
+short version matches the short version of $HOSTNAME
+.IP 4.
+If all this fails then search the interfaces list for an address that
+matches a name in the nodelist
+.RE
+
+.PP
+Within the
+.B system
+directive it is possible to specify system options.
+
+Possible options are:
+.TP
+qb_ipc_type
+This specifies type of IPC to use. Can be one of native (default), shm and socket.
+Native means one of shm or socket, depending on what is supported by OS. On systems
+with support for both, SHM is selected. SHM is generally faster, but need to allocate
+ring buffer file in /dev/shm.
+
+.TP
+sched_rr
+Should be set to yes (default) if corosync should try to set round robin realtime
+scheduling with maximal priority to itself. When setting of scheduler fails, fallback to set
+maximal priority.
+
+.TP
+priority
+Set priority of corosync process. Valid only when sched_rr is set to no.
+Can be ether numeric value with similar meaning as
+.BR nice (1)
+or
+.B max
+/
+.B min
+meaning maximal / minimal priority (so minimal / maximal nice value).
+
+.TP
+move_to_root_cgroup
+Can be one of
+.B yes
+(Corosync always moves itself to root cgroup),
+.B no
+(Corosync never tries to move itself to root cgroup) or
+.B auto
+(Corosync first checks if sched_rr is enabled, and if
+so, it tries to set round robin realtime scheduling with maximal priority to itself.
+If setting of priority fails, corosync tries to move itself to root
+cgroup and retries setting of priority).
+
+This feature is available only for systems with cgroups v1 with RT
+sched enabled (Linux with CONFIG_RT_GROUP_SCHED kernel option) and cgroups v2.
+
+It's worth noting that currently (May 3 2021) cgroup2 doesn’t yet
+support control of realtime processes and the cpu controller can only be
+enabled when all RT processes are in the root cgroup (applies only for kernel
+with CONFIG_RT_GROUP_SCHED enabled). So when move_to_root_cgroup
+is disabled, kernel is compiled with CONFIG_RT_GROUP_SCHED and systemd is used,
+it may be impossible to make systemd options
+like CPUQuota working correctly until corosync is stopped.
+
+Also when moving to root cgroup is enforced and used together with cgroup2 and systemd
+it makes impossible (most of the time) for journald to add systemd specific
+metadata (most importantly _SYSTEMD_UNIT) properly, because corosync is
+moved out of cgroup created by systemd. This means
+it is not possible to filter corosync logged messages based on these metadata
+(for example using -u or _SYSTEMD_UNIT=UNIT pattern) and also running
+systemctl status doesn't display (all) corosync log messages.
+The problem is even worse because journald caches pid for some time
+(approx. 5 sec) so initial corosync messages have correct metadata.
+
+.TP
+allow_knet_handle_fallback
+If knet handle creation fails using privileged operations, allow fallback to
+creating knet handle using unprivileged operations. Defaults to no, meaning
+if privileged knet handle creation fails, corosync will refuse to start.
+
+The knet handle will always be created using privileged operations if possible,
+setting this to yes only allows fallback to unprivileged operations. This fallback
+may result in performance issues, but if running in an unprivileged environment,
+e.g. as a normal user or in unprivileged container, this may be required.
+
+.TP
+state_dir
+Existing directory where corosync should chdir into. Corosync stores
+important state files and blackboxes there.
+
+The default is /var/lib/corosync.
+
+.PP
+Within the
+.B resources
+directive it is possible to specify options for resources.
+
+Possible option is:
+.TP
+watchdog_device
+(Valid only if Corosync was compiled with watchdog support.)
+.br
+Watchdog device to use, for example /dev/watchdog.
+If unset, empty or "off", no watchdog is used.
+.IP
+In a cluster with properly configured power fencing a watchdog
+provides no additional value. On the other hand, slow watchdog
+communication may incur multi-second delays in the Corosync main loop,
+potentially breaking down membership. IPMI watchdogs are particularly
+notorious in this regard: read about kipmid_max_busy_us in IPMI.txt in
+the Linux kernel documentation.
+
+
+.PP
+Within the
+.B nozzle
+directive it is possible to specify options for a libnozzle device. This is a pseudo
+ethernet device that routes network traffic through a channel on the corosync knet network
+(NOT cpg or any corosync internal service) to other nodes in the cluster. This allows
+applications to take advantage of knet features such as multipathing, automatic failover,
+link switching etc. Note that libnozzle is not a reliable transport, but you can tunnel TCP
+through it for reliable communications.
+.br
+libnozzle also supports optional interface up/down scripts that are kept under a
+/etc/corosync/updown.d/ directory. See the knet documentation for more information.
+.br
+Only one nozzle device is allowed.
+.br
+The nozzle stanza takes several options:
+.TP
+name
+The name of the network device to be created. On Linux this may be any name at all, other
+platforms have restrictions on the name.
+.TP
+ipaddr
+The IP address (IPv6 or IPv4) of the interface. The bottom part of this address will be replaced
+by the local node's nodeid in conjunction with ipprefix. so, eg
+ipaddr: 192.168.1.0
+ipprefix: 24
+will make nodeids 1,2,5 use IP addresses 192.168.1.1, 192.168.1.2 & 192.168.1.5.
+If a prefix length of 16 is used then the bottom two bytes will be filled in with nodeid numbers.
+IPv6 addresses must end in '::', the nodeid will be added after the two colons to make the
+local IP address.
+Only one IP address is currently supported in the corosync.conf file. Additional IP addresses
+can be added in the ifup script if necessary.
+.TP
+ipprefix
+specifies the IP address prefix for the nozzle device (see above)
+.TP
+macaddr
+Specifies the MAC address prefix for the nozzle device. As for the IP address, the bottom part
+of the MAC address will be filled in with the node id. In this case no prefix applies, the bottom
+two bytes of the MAC address will always be overwritten with the node id. So specifying
+macaddr: 54:54:12:24:12:12 on nodeid 1 will result in it having a MAC address of 54:54:12:24:00:01
+
+.SH "TO ADD A NEW NODE TO THE CLUSTER"
+For example to add a node with address 10.24.38.108 with nodeid 3. The node has the name NEW
+(in DNS or /etc/hosts) and is not currently running corosync. The current corosync.conf nodelist
+looks like this:
+.PP
+.nf
+.RS
+nodelist {
+ node {
+ nodeid: 1
+ ring0_addr: 10.24.38.101
+ name: node1
+ }
+ node {
+ nodeid: 2
+ ring0_addr: 10.24.38.102
+ name: node2
+
+ }
+}
+.RE
+.fi
+.PP
+Add a new entry for the node below the existing nodes. Node entries don't have
+to be in nodeid order, but it will help keep you sane. So the nodelist now looks like this:
+.PP
+.nf
+.RS
+nodelist {
+ node {
+ nodeid: 1
+ ring0_addr: 10.24.38.101
+ name: node1
+ }
+ node {
+ nodeid: 2
+ ring0_addr: 10.24.38.102
+ name: node2
+
+ }
+ node {
+ nodeid: 3
+ ring0_addr: 10.24.38.108
+ name: NEW
+
+ }
+}
+.RE
+.fi
+.PP
+
+.PP
+This file must then be copied onto all three nodes - the existing two nodes, and the new one.
+On one of the existing corosync nodes, tell corosync to re-read the updated config file into memory:
+.PP
+.nf
+.RS
+corosync-cfgtool -R
+.RE
+.fi
+.PP
+This command only needs to be run on one node in the cluster. You may then start corosync on the NEW node
+and it should join the cluster. If this doesn't work as expected then check the communications between all
+three nodes is working, and check the syslog files on all nodes for more information. It's important to note
+that the key bit of information about a node failing to join might be on a different node than you expect.
+
+.SH "TO REMOVE A NODE FROM THE CLUSTER"
+This is the reverse procedure to 'Adding a node' above. First you need to shut down the node you will
+be removing from the cluster.
+.PP
+.nf
+.RS
+corosync-cfgtool -H
+.RE
+.fi
+
+
+.PP
+Then delete the nodelist stanza from corosync.conf and finally update corosync on the remaining nodes by
+running
+.PP
+.nf
+.RS
+corosync-cfgtool -R
+.RE
+.fi
+.TP
+on one of them.
+
+.SH "ADDRESS RESOLUTION"
+corosync resolves ringX_addr names/IP addresses using the getaddrinfo(3) call with respect
+of totem.ip_version setting.
+
+getaddrinfo() function uses a sophisticated algorithm to sort node addresses into a preferred
+order and corosync always chooses the first address in that list of the required family.
+As such it is essential that your DNS or /etc/hosts files are correctly configured so that
+all addresses for ringX appear on the same network (or are reachable with minimal hops)
+and over the same IP protocol. If this is not the case then some nodes might not be able
+to join the cluster. It is possible to override the search order used
+by getaddrinfo() using the configuration file /etc/gai.conf(5) if necessary,
+but this is not recommended.
+
+If there is any doubt about the order of addresses returned from getaddrinfo() then it might be simpler to use
+IP addresses (v4 or v6) in the ringX_addr field.
+
+.SH "FILES"
+.TP
+/etc/corosync/corosync.conf
+The corosync executive configuration file.
+
+.SH "SEE ALSO"
+.BR corosync_overview (7),
+.BR votequorum (5),
+.BR corosync-qdevice (8),
+.BR logrotate (8)
+.BR getaddrinfo (3)
+.BR gai.conf (5)
+.PP
diff --git a/man/corosync.xml.5 b/man/corosync.xml.5
new file mode 100644
index 0000000..a63889a
--- /dev/null
+++ b/man/corosync.xml.5
@@ -0,0 +1,72 @@
+.\"/*
+.\" * Copyright (c) 2011 Red Hat, Inc.
+.\" *
+.\" * All rights reserved.
+.\" *
+.\" * Author: Jan Friesse (jfriesse@redhat.com)
+.\" *
+.\" * This software licensed under BSD license, the text of which follows:
+.\" *
+.\" * Redistribution and use in source and binary forms, with or without
+.\" * modification, are permitted provided that the following conditions are met:
+.\" *
+.\" * - Redistributions of source code must retain the above copyright notice,
+.\" * this list of conditions and the following disclaimer.
+.\" * - Redistributions in binary form must reproduce the above copyright notice,
+.\" * this list of conditions and the following disclaimer in the documentation
+.\" * and/or other materials provided with the distribution.
+.\" * - Neither the name of the Red Hat, Inc. nor the names of its
+.\" * contributors may be used to endorse or promote products derived from this
+.\" * software without specific prior written permission.
+.\" *
+.\" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+.\" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+.\" * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+.\" * THE POSSIBILITY OF SUCH DAMAGE.
+.\" */
+.TH COROSYNC_XML 5 2011-12-16 "corosync XML config Man Page" "Corosync Cluster Engine Programmer's Manual"
+.SH NAME
+corosync.xml - XML version of corosync executive configuration file
+
+.SH SYNOPSIS
+/etc/corosync/corosync.xml
+
+.SH DESCRIPTION
+The corosync.xml is XML version of corosync.conf file. It is processed by
+.B corosync-xmlproc (8)
+to generate valid conf file.
+
+File must be valid XML. File starts with root element
+.B corosync
+which can contain same arguments as described in
+.B corosync.conf (5).
+
+Within corosync tag are other tags which are processed as follows:
+.TP
+- Every tag is start of new directive
+.TP
+- Every tag attribute is one of options in directive
+.TP
+- Directive is automatically closed
+.TP
+- Sub-tags are processed same and stays within directive
+.PP
+For example, see /etc/corosync/corosync.xml.example
+
+.SH "FILES"
+.TP
+/etc/corosync/corosync.xml
+XML version of the corosync executive configuration file.
+
+.SH "SEE ALSO"
+.BR corosync_overview (7),
+.BR corosync.conf (5),
+.BR corosync-xmlproc (8)
+.PP
diff --git a/man/corosync_overview.7 b/man/corosync_overview.7
new file mode 100644
index 0000000..fbe52a1
--- /dev/null
+++ b/man/corosync_overview.7
@@ -0,0 +1,176 @@
+.\"/*
+.\" * Copyright (c) 2005 MontaVista Software, Inc.
+.\" * Copyright (c) 2006-2023 Red Hat, Inc.
+.\" *
+.\" * All rights reserved.
+.\" *
+.\" * Author: Steven Dake (sdake@redhat.com)
+.\" *
+.\" * This software licensed under BSD license, the text of which follows:
+.\" *
+.\" * Redistribution and use in source and binary forms, with or without
+.\" * modification, are permitted provided that the following conditions are met:
+.\" *
+.\" * - Redistributions of source code must retain the above copyright notice,
+.\" * this list of conditions and the following disclaimer.
+.\" * - Redistributions in binary form must reproduce the above copyright notice,
+.\" * this list of conditions and the following disclaimer in the documentation
+.\" * and/or other materials provided with the distribution.
+.\" * - Neither the name of the MontaVista Software, Inc. nor the names of its
+.\" * contributors may be used to endorse or promote products derived from this
+.\" * software without specific prior written permission.
+.\" *
+.\" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+.\" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+.\" * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+.\" * THE POSSIBILITY OF SUCH DAMAGE.
+.\" */
+.TH COROSYNC_OVERVIEW 7 2018-11-13 "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
+.SH NAME
+corosync_overview \- Corosync overview
+.SH OVERVIEW
+The corosync project's purpose is to implement and support a production quality
+Revised BSD licensed implementation of a high performance low overhead high
+availability development toolkit.
+
+Faults occur for various reasons:
+.PP
+* Application Faults
+.PP
+* Middleware Faults
+.PP
+* Operating System Faults
+.PP
+* Hardware Faults
+
+The major focus of high availability in the past has been to mask hardware
+faults. Faults in other components of the system have gone unsolved until
+Corosync. Corosync is designed for applications to replicate their state to
+up to 16 processors. The processors all contain a replica of the application
+state.
+
+The corosync project provides a group message API called CPG.
+The project developers recommend CPG be used for most applications. The CPG
+service implements a closed group messaging model presenting extended virtual
+synchrony guarantees.
+
+To manage conditions where the process executing the CPG application exchange
+fails, we provide the Simple Availability Manager (sam) to provide simple
+application restart.
+
+.SH QUICKSTART
+The corosync executive must be configured. In the directory conf in the
+source distribution are several files that must be copied to the /etc/corosync
+directory. If corosync is packaged by a distro, this may be complete.
+
+The directory contains the file corosync.conf. Please read the corosync.conf(5)
+man page for details on the configuration options. The corosync project will
+work out of the box with the default configuration options, although the
+administrator may desire different options.
+
+The corosync executive uses cryptographic techniques to ensure authenticity
+and privacy of the messages. In order for corosync to be secure and operate,
+a private key must be generated and shared to all processors.
+
+First generate the key on one of the nodes:
+
+.nf
+unix# corosync-keygen
+Corosync Cluster Engine Authentication key generator.
+Gathering 2048 bits for key from /dev/urandom.
+Writing corosync key to /etc/corosync/authkey.
+.fi
+
+After this operation, a private key will be in the file /etc/corosync/authkey.
+This private key must be copied to every processor in the cluster. If the
+private key isn't the same for every node, those nodes with nonmatching private
+keys will not be able to join the same configuration.
+
+Copy the key to some security transportable storage or use ssh to transmit the
+key from node to node. Then install the key with the command:
+
+unix#: install -D --group=0 --owner=0 --mode=0400 /path_to_authkey/authkey /etc/corosync/authkey
+
+If a message "Invalid digest" appears from the corosync executive, the keys
+are not consistent between processors.
+
+Finally run the corosync executive. If corosync is packaged from a distro, it
+may be set to start on system start. It may also be turned off by default in
+which case the init script for corosync must be enabled.
+
+.SH USING LIBRARIES
+The corosync libraries have header files which must be included in the
+developer's application. Once the header file is included, the developer can
+reference the corosync interfaces.
+
+The corosync project recommends that distros place include files in
+/usr/include/corosync.
+
+.SH IPv6
+The corosync project supports both IPv4 and IPv6 network addresses. When using
+knet as the transport each link should have the same IP family, but different links
+can have different families (eg link 0 could be all IPv4, and link 1 all IPv6).
+When using UDP/UDPU the single link should use the same family on all nodes.
+
+To configure a host for IPv6, use the ifconfig program to add interfaces:
+box20: ifconfig eth0 add fec0::1:a800:4ff:fe00:20/64
+box30: ifconfig eth0 add fec0::1:a800:4ff:fe00:30/64
+
+If the /64 is not specified, a route for the IPv6 network will not be configured
+which will cause significant problems. Make sure a route is available for
+IPv6 traffic.
+
+.SH ARCHITECTURE
+The corosync libraries are a thin IPC interface to the corosync executive. The
+corosync executive implements the functionality of the corosync APIs for
+distributed computing.
+
+The corosync executive uses the Totem extended virtual synchrony protocol. The
+advantage to the end user is excellent performance characteristics and a proven
+protocol with excellent reliability. This protocol connects the processors
+in a configuration together so they may communicate.
+
+.SH SECURITY
+The corosync executive optionally encrypts and signs all messages sent
+over the network. For more details see
+.B crypto_model,
+.B crypto_hash
+and
+.B crypto_cipher
+options in the
+.BR corosync.conf (5).
+
+If membership messages can be captured by intruders, it is possible to execute
+a denial of service attack on the cluster. In this scenario, the cluster is
+likely already compromised and a DoS attack is the least of the administration's
+worries.
+
+The security in corosync does not offer perfect forward secrecy because the keys
+are reused. It may be possible for an intruder to determine the shared key by
+capturing packets in an automated fashion. No such automated attack has
+been published as of yet. In this scenario, the cluster is likely already
+compromised to allow the long-term capture of transmitted data.
+
+For security reasons, the corosync executive binary should NEVER
+be setuid or setgid in the filesystem.
+
+.SH BUGS
+None that are known.
+
+.SH "SEE ALSO"
+.BR corosync.conf (5),
+.BR corosync-keygen (8),
+.BR corosync_quorumtool (8),
+.BR corosync_cfgtool (8),
+.BR corosync_cpgtool (8),
+.BR corosync_cmaptool (8),
+.BR cpg_overview (3),
+.BR sam_overview (3)
+.PP
diff --git a/man/cpg_context_get.3.in b/man/cpg_context_get.3.in
new file mode 100644
index 0000000..712fe75
--- /dev/null
+++ b/man/cpg_context_get.3.in
@@ -0,0 +1,68 @@
+.\"/*
+.\" * Copyright (c) 2007 Red Hat, Inc.
+.\" *
+.\" * All rights reserved.
+.\" *
+.\" * Author: Patrick Caulfield <pcaulfie@redhat.com>
+.\" *
+.\" * This software licensed under BSD license, the text of which follows:
+.\" *
+.\" * Redistribution and use in source and binary forms, with or without
+.\" * modification, are permitted provided that the following conditions are met:
+.\" *
+.\" * - Redistributions of source code must retain the above copyright notice,
+.\" * this list of conditions and the following disclaimer.
+.\" * - Redistributions in binary form must reproduce the above copyright notice,
+.\" * this list of conditions and the following disclaimer in the documentation
+.\" * and/or other materials provided with the distribution.
+.\" * - Neither the name of the MontaVista Software, Inc. nor the names of its
+.\" * contributors may be used to endorse or promote products derived from this
+.\" * software without specific prior written permission.
+.\" *
+.\" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+.\" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+.\" * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+.\" * THE POSSIBILITY OF SUCH DAMAGE.
+.\" */
+.TH CPG_CONTEXT_GET 3 2004-08-31 "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
+.SH NAME
+cpg_context_get \- Gets the context variable for a CPG instance
+.SH SYNOPSIS
+.B #include <corosync/cpg.h>
+.sp
+.BI "int cpg_context_get(cpg_handle_t " handle ", void **" context ");
+.SH DESCRIPTION
+The
+.B cpg_context_get
+function is used to retrieve the context variable previously stored using
+.B cpg_context_set(3)
+.SH RETURN VALUE
+This call returns the CS_OK value if successful, otherwise an error is returned.
+.PP
+.SH ERRORS
+The errors are undocumented.
+.SH "SEE ALSO"
+.BR cpg_overview (3),
+.BR cpg_initialize (3),
+.BR cpg_finalize (3),
+.BR cpg_fd_get (3),
+.BR cpg_dispatch (3),
+.BR cpg_join (3),
+.BR cpg_leave (3),
+.BR cpg_mcast_joined (3),
+.BR cpg_membership_get (3)
+.BR cpg_zcb_alloc (3)
+.BR cpg_zcb_free (3)
+.BR cpg_zcb_mcast_joined (3)
+.BR cpg_context_get (3)
+.BR cpg_context_set (3)
+.BR cpg_local_get (3)
+
+.PP
diff --git a/man/cpg_context_set.3.in b/man/cpg_context_set.3.in
new file mode 100644
index 0000000..7c373a4
--- /dev/null
+++ b/man/cpg_context_set.3.in
@@ -0,0 +1,69 @@
+.\"/*
+.\" * Copyright (c) 2007 Red Hat, Inc.
+.\" *
+.\" * All rights reserved.
+.\" *
+.\" * Author: Patrick Caulfield <pcaulfie@redhat.com>
+.\" *
+.\" * This software licensed under BSD license, the text of which follows:
+.\" *
+.\" * Redistribution and use in source and binary forms, with or without
+.\" * modification, are permitted provided that the following conditions are met:
+.\" *
+.\" * - Redistributions of source code must retain the above copyright notice,
+.\" * this list of conditions and the following disclaimer.
+.\" * - Redistributions in binary form must reproduce the above copyright notice,
+.\" * this list of conditions and the following disclaimer in the documentation
+.\" * and/or other materials provided with the distribution.
+.\" * - Neither the name of the MontaVista Software, Inc. nor the names of its
+.\" * contributors may be used to endorse or promote products derived from this
+.\" * software without specific prior written permission.
+.\" *
+.\" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+.\" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+.\" * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+.\" * THE POSSIBILITY OF SUCH DAMAGE.
+.\" */
+.TH CPG_CONTEXT_SET 3 2004-08-31 "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
+.SH NAME
+cpg_context_set \- Sets the context variable for a CPG instance
+.SH SYNOPSIS
+.B #include <corosync/cpg.h>
+.sp
+.BI "int cpg_context_set(cpg_handle_t " handle ", void *" context ");
+.SH DESCRIPTION
+The
+.B cpg_context_set
+function is used to set the context variable for a cpg instance. It has no
+meaning inside libcpg itself and will not be touched by the library. It can
+be retrieved using
+.B cpg_context_get(3)
+.SH RETURN VALUE
+This call returns the CS_OK value if successful, otherwise an error is returned.
+.PP
+.SH ERRORS
+The errors are undocumented.
+.SH "SEE ALSO"
+.BR cpg_overview (3),
+.BR cpg_initialize (3),
+.BR cpg_finalize (3),
+.BR cpg_fd_get (3),
+.BR cpg_dispatch (3),
+.BR cpg_join (3),
+.BR cpg_leave (3),
+.BR cpg_mcast_joined (3),
+.BR cpg_membership_get (3)
+.BR cpg_zcb_alloc (3)
+.BR cpg_zcb_free (3)
+.BR cpg_zcb_mcast_joined (3)
+.BR cpg_context_get (3)
+.BR cpg_context_set (3)
+.BR cpg_local_get (3)
+.PP
diff --git a/man/cpg_dispatch.3.in b/man/cpg_dispatch.3.in
new file mode 100644
index 0000000..66f4606
--- /dev/null
+++ b/man/cpg_dispatch.3.in
@@ -0,0 +1,111 @@
+.\"/*
+.\" * Copyright (c) 2006 Red Hat, Inc.
+.\" *
+.\" * All rights reserved.
+.\" *
+.\" * Author: Patrick Caulfield <pcaulfie@redhat.com>
+.\" *
+.\" * This software licensed under BSD license, the text of which follows:
+.\" *
+.\" * Redistribution and use in source and binary forms, with or without
+.\" * modification, are permitted provided that the following conditions are met:
+.\" *
+.\" * - Redistributions of source code must retain the above copyright notice,
+.\" * this list of conditions and the following disclaimer.
+.\" * - Redistributions in binary form must reproduce the above copyright notice,
+.\" * this list of conditions and the following disclaimer in the documentation
+.\" * and/or other materials provided with the distribution.
+.\" * - Neither the name of the MontaVista Software, Inc. nor the names of its
+.\" * contributors may be used to endorse or promote products derived from this
+.\" * software without specific prior written permission.
+.\" *
+.\" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+.\" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+.\" * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+.\" * THE POSSIBILITY OF SUCH DAMAGE.
+.\" */
+.TH CPG_DISPATCH 3 2004-08-31 "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
+.SH NAME
+cpg_dispatch \- Dispatches callbacks from the CPG service
+.SH SYNOPSIS
+.B #include <corosync/cpg.h>
+.sp
+.BI "int cpg_dispatch(cpg_handle_t " handle ", cpg_dispatch_t *" dispatch_types ");
+.SH DESCRIPTION
+The
+.B cpg_dispatch
+function is used to dispatch configuration changes or messages from the
+closed process groups API.
+.PP
+Each application may have several connections to the CPG API. Each application
+uses the
+.I handle
+argument to uniquely identify the connection.
+.PP
+The
+.I dispatch_types
+argument is used to identify the type of dispatch to execute. The possible types are
+defined by the structure:
+
+.IP
+.RS
+.ne 18
+.nf
+.ta 4n 30n 33n
+typedef enum {
+ CS_DISPATCH_ONE,
+ CS_DISPATCH_ALL,
+ CS_DISPATCH_BLOCKING
+} cpg_dispatch_t;
+.ta
+.fi
+.RE
+.IP
+.PP
+.PP
+The dispatch values have the following meanings:
+.TP
+.B CS_DISPATCH_ONE
+Dispatch atleast one callback, blocking until the callback is dispatched.
+.TP
+.B CS_DISPATCH_ALL
+Dispatch all waiting callbacks without blocking to wait for any callbacks.
+.TP
+.B CS_DISPATCH_BLOCKING
+Dispatch all callbacks, blocking indefinitely. This is used in a threaded
+program where a thread is created, and then cpg_dispatch() is called immediately
+from the created thread to execute callbacks.
+.TP
+.B CS_DISPATCH_ONE_NONBLOCKING
+Dispatch at most one callback. If there is no pending callback,
+CS_ERR_TRY_AGAIN is returned.
+
+.SH RETURN VALUE
+This call returns the CS_OK value if successful, otherwise an error is returned.
+.PP
+.SH ERRORS
+The errors are undocumented.
+.SH "SEE ALSO"
+.BR cpg_overview (3),
+.BR cpg_initialize (3),
+.BR cpg_finalize (3),
+.BR cpg_fd_get (3),
+.BR cpg_dispatch (3),
+.BR cpg_join (3),
+.BR cpg_leave (3),
+.BR cpg_mcast_joined (3),
+.BR cpg_membership_get (3)
+.BR cpg_zcb_alloc (3)
+.BR cpg_zcb_free (3)
+.BR cpg_zcb_mcast_joined (3)
+.BR cpg_context_get (3)
+.BR cpg_context_set (3)
+.BR cpg_local_get (3)
+.PP
diff --git a/man/cpg_fd_get.3.in b/man/cpg_fd_get.3.in
new file mode 100644
index 0000000..ce087d4
--- /dev/null
+++ b/man/cpg_fd_get.3.in
@@ -0,0 +1,75 @@
+.\"/*
+.\" * Copyright (c) 2006 Red Hat, Inc.
+.\" *
+.\" * All rights reserved.
+.\" *
+.\" * Author: Patrick Caulfield <pcaulfie@redhat.com>
+.\" *
+.\" * This software licensed under BSD license, the text of which follows:
+.\" *
+.\" * Redistribution and use in source and binary forms, with or without
+.\" * modification, are permitted provided that the following conditions are met:
+.\" *
+.\" * - Redistributions of source code must retain the above copyright notice,
+.\" * this list of conditions and the following disclaimer.
+.\" * - Redistributions in binary form must reproduce the above copyright notice,
+.\" * this list of conditions and the following disclaimer in the documentation
+.\" * and/or other materials provided with the distribution.
+.\" * - Neither the name of the MontaVista Software, Inc. nor the names of its
+.\" * contributors may be used to endorse or promote products derived from this
+.\" * software without specific prior written permission.
+.\" *
+.\" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+.\" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+.\" * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+.\" * THE POSSIBILITY OF SUCH DAMAGE.
+.\" */
+.TH CPG_FD_GET 3 2004-08-31 "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
+.SH NAME
+cpg_fd_get \- Dispatches callbacks from the CPG service
+.SH SYNOPSIS
+.B #include <corosync/cpg.h>
+.sp
+.BI "int cpg_fd_get(cpg_handle_t " handle ", int *" fd ");
+.SH DESCRIPTION
+The
+.B cpg_fd_get
+function is used to retrieve the file descriptor that may be used with the poll
+system call to determine when
+.B cpg_dispatch(3)
+won't block. The
+.I handle
+argument may not be used directly with
+.B poll
+because it is not the file descriptor, but instead an internal identifier used
+by the CPG library.
+.SH RETURN VALUE
+This call returns the CS_OK value if successful, otherwise an error is returned.
+.PP
+.SH ERRORS
+The errors are undocumented.
+.SH "SEE ALSO"
+.BR cpg_overview (3),
+.BR cpg_initialize (3),
+.BR cpg_finalize (3),
+.BR cpg_fd_get (3),
+.BR cpg_dispatch (3),
+.BR cpg_join (3),
+.BR cpg_leave (3),
+.BR cpg_mcast_joined (3),
+.BR cpg_membership_get (3)
+.BR cpg_zcb_alloc (3)
+.BR cpg_zcb_free (3)
+.BR cpg_zcb_mcast_joined (3)
+.BR cpg_context_get (3)
+.BR cpg_context_set (3)
+.BR cpg_local_get (3)
+
+.PP
diff --git a/man/cpg_finalize.3.in b/man/cpg_finalize.3.in
new file mode 100644
index 0000000..215c701
--- /dev/null
+++ b/man/cpg_finalize.3.in
@@ -0,0 +1,71 @@
+.\"/*
+.\" * Copyright (c) 2006 Red Hat, Inc.
+.\" *
+.\" * All rights reserved.
+.\" *
+.\" * Author: Patrick Caulfield <pcaulfie@redhat.com>
+.\" *
+.\" * This software licensed under BSD license, the text of which follows:
+.\" *
+.\" * Redistribution and use in source and binary forms, with or without
+.\" * modification, are permitted provided that the following conditions are met:
+.\" *
+.\" * - Redistributions of source code must retain the above copyright notice,
+.\" * this list of conditions and the following disclaimer.
+.\" * - Redistributions in binary form must reproduce the above copyright notice,
+.\" * this list of conditions and the following disclaimer in the documentation
+.\" * and/or other materials provided with the distribution.
+.\" * - Neither the name of the MontaVista Software, Inc. nor the names of its
+.\" * contributors may be used to endorse or promote products derived from this
+.\" * software without specific prior written permission.
+.\" *
+.\" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+.\" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+.\" * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+.\" * THE POSSIBILITY OF SUCH DAMAGE.
+.\" */
+.TH CPG_FINALIZE 3 2004-08-31 "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
+.SH NAME
+cpg_finalize \- Terminate a connection to the CPG service
+.SH SYNOPSIS
+.B #include <corosync/cpg.h>
+.sp
+.BI "int cpg_finalize(cpg_handle_t " handle ");
+.SH DESCRIPTION
+The
+.B cpg_finalize
+function is used to close a connection to the closed process group API.
+Once the connection is finalized, the handle may not be used again by applications.
+No more callbacks will be dispatched from the
+.B cpg_dispatch function.
+.PP
+.SH RETURN VALUE
+This call returns the CS_OK value if successful, otherwise an error is returned.
+.PP
+.SH ERRORS
+The errors are undocumented.
+.SH "SEE ALSO"
+.BR cpg_overview (3),
+.BR cpg_initialize (3),
+.BR cpg_finalize (3),
+.BR cpg_fd_get (3),
+.BR cpg_dispatch (3),
+.BR cpg_join (3),
+.BR cpg_leave (3),
+.BR cpg_mcast_joined (3),
+.BR cpg_membership_get (3)
+.BR cpg_zcb_alloc (3)
+.BR cpg_zcb_free (3)
+.BR cpg_zcb_mcast_joined (3)
+.BR cpg_context_get (3)
+.BR cpg_context_set (3)
+.BR cpg_local_get (3)
+
+.PP
diff --git a/man/cpg_initialize.3.in b/man/cpg_initialize.3.in
new file mode 100644
index 0000000..38c7de5
--- /dev/null
+++ b/man/cpg_initialize.3.in
@@ -0,0 +1,177 @@
+.\"/*
+.\" * Copyright (c) 2006-2019 Red Hat, Inc.
+.\" *
+.\" * All rights reserved.
+.\" *
+.\" * Author: Christine Caulfield <ccaulfie@redhat.com>
+.\" *
+.\" * This software licensed under BSD license, the text of which follows:
+.\" *
+.\" * Redistribution and use in source and binary forms, with or without
+.\" * modification, are permitted provided that the following conditions are met:
+.\" *
+.\" * - Redistributions of source code must retain the above copyright notice,
+.\" * this list of conditions and the following disclaimer.
+.\" * - Redistributions in binary form must reproduce the above copyright notice,
+.\" * this list of conditions and the following disclaimer in the documentation
+.\" * and/or other materials provided with the distribution.
+.\" * - Neither the name of the MontaVista Software, Inc. nor the names of its
+.\" * contributors may be used to endorse or promote products derived from this
+.\" * software without specific prior written permission.
+.\" *
+.\" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+.\" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+.\" * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+.\" * THE POSSIBILITY OF SUCH DAMAGE.
+.\" */
+.TH CPG_INITIALIZE 3 2019-04-16 "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
+.SH NAME
+cpg_initialize \- Create a new connection to the CPG service
+.SH SYNOPSIS
+.B #include <corosync/cpg.h>
+.sp
+.BI "int cpg_initialize(cpg_handle_t *" handle ", cpg_callbacks_t *" callbacks ");
+.SH DESCRIPTION
+The
+.B cpg_initialize
+function is used to initialize a connection to the closed process groups API. This function is deprecated
+and
+.B cpg_model_initialize
+should be used in newly written code.
+.PP
+Each application may have several connections to the CPG API. Each application
+uses the
+.I handle
+argument to uniquely identify the connection. The
+.I handle
+argument is then used in other function calls to identify the connection to be used
+for communication with the CPG service.
+.PP
+Every time an CPG event occurs within the joined group, one of the callbacks specified by the argument
+.I callbacks
+is called. The callback functions are described by the following type definitions:
+.PP
+.PP
+.IP
+.RS
+.ne 18
+.nf
+.ta 4n 20n 32n
+
+typedef void (*cpg_deliver_fn_t) (
+ cpg_handle_t handle,
+ const struct cpg_name *group_name,
+ uint32_t nodeid,
+ uint32_t pid,
+ const void *msg,
+ size_t msg_len);
+
+
+typedef void (*cpg_confchg_fn_t) (
+ cpg_handle_t handle,
+ const struct cpg_name *group_name,
+ const struct cpg_address *member_list, size_t member_list_entries,
+ const struct cpg_address *left_list, size_t left_list_entries,
+ const struct cpg_address *joined_list, size_t joined_list_entries);
+
+.ta
+.fi
+.RE
+.IP
+.PP
+.PP
+The
+.I callbacks
+argument is of the type:
+.IP
+.RS
+.ne 18
+.nf
+.PP
+typedef struct {
+ cpg_deliver_fn_t cpg_deliver_fn;
+ cpg_confchg_fn_t cpg_confchg_fn;
+} cpg_callbacks_t;
+.ta
+.fi
+.RE
+.IP
+.PP
+When a configuration change occurs or a message is to be delivered one of the callbacks
+is called from the
+.B cpg_dispatch()
+function. If a configuration change occurs,
+.I cpg_confchg_fn
+is called. If a delivery of a message occurs,
+.I cpg_deliver_fn
+is called.
+
+The
+.I cpg_address
+structure is defined
+.IP
+.RS
+.ne 18
+.nf
+.PP
+struct cpg_address {
+ unsigned int nodeid;
+ unsigned int pid;
+ unsigned int reason;
+};
+.ta
+.fi
+.RE
+.IP
+.PP
+where nodeid is a 32 bit unique node identifier, pid is the process ID of the process that has joined/left the group
+or sent the message, and reason is an integer code indicating why the node joined/left the group (this value is not
+set for the member_list items).
+.PP
+.IP
+.RS
+.ne 18
+.nf
+.PP
+CPG_REASON_JOIN - the process joined a group using cpg_join().
+CPG_REASON_LEAVE - the process left a group using cpg_leave()
+CPG_REASON_NODEDOWN - the process left a group because the node left the cluster.
+CPG_REASON_NODEUP - the process joined a group because it was already a member of a group on a node that has just joined the cluster
+CPG_REASON_PROCDOWN - the process left a group without calling cpg_leave()
+CPG_REASON_UNDEFINED - a special value used for the member_list items
+.ta
+.fi
+.RE
+.IP
+.PP
+.SH RETURN VALUE
+This call returns the CS_OK value if successful, otherwise an error is returned.
+.PP
+.SH ERRORS
+The errors are undocumented.
+.SH "SEE ALSO"
+.BR cpg_overview (3),
+.BR cpg_initialize (3),
+.BR cpg_finalize (3),
+.BR cpg_fd_get (3),
+.BR cpg_dispatch (3),
+.BR cpg_join (3),
+.BR cpg_leave (3),
+.BR cpg_mcast_joined (3),
+.BR cpg_membership_get (3)
+.BR cpg_zcb_alloc (3)
+.BR cpg_zcb_free (3)
+.BR cpg_zcb_mcast_joined (3)
+.BR cpg_context_get (3)
+.BR cpg_context_set (3)
+.BR cpg_local_get (3)
+.BR cpg_model_initialize (3)
+
+.PP
diff --git a/man/cpg_iteration_finalize.3.in b/man/cpg_iteration_finalize.3.in
new file mode 100644
index 0000000..af1b3b3
--- /dev/null
+++ b/man/cpg_iteration_finalize.3.in
@@ -0,0 +1,67 @@
+.\"/*
+.\" * Copyright (c) 2012 Red Hat, Inc.
+.\" *
+.\" * All rights reserved.
+.\" *
+.\" * Author: Jan Friesse (jfriesse@redhat.com)
+.\" *
+.\" * This software licensed under BSD license, the text of which follows:
+.\" *
+.\" * Redistribution and use in source and binary forms, with or without
+.\" * modification, are permitted provided that the following conditions are met:
+.\" *
+.\" * - Redistributions of source code must retain the above copyright notice,
+.\" * this list of conditions and the following disclaimer.
+.\" * - Redistributions in binary form must reproduce the above copyright notice,
+.\" * this list of conditions and the following disclaimer in the documentation
+.\" * and/or other materials provided with the distribution.
+.\" * - Neither the name of the Red Hat, Inc. nor the names of its
+.\" * contributors may be used to endorse or promote products derived from this
+.\" * software without specific prior written permission.
+.\" *
+.\" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+.\" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+.\" * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+.\" * THE POSSIBILITY OF SUCH DAMAGE.
+.\" */
+.TH "CPG_ITERATION_FINALIZE" 3 "05/03/2012" "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
+
+.SH NAME
+.P
+cpg_iteration_finalize \- Finalize iterator for members of CPG
+
+.SH SYNOPSIS
+.P
+\fB#include <corosync/cpg.h>\fR
+
+.P
+\fBcs_error_t
+cpg_iteration_finalize (cpg_iteration_handle_t \fIhandle\fB);\fR
+
+.SH DESCRIPTION
+.P
+The
+.B cpg_iteration_finalize
+function is used to free up memory associated with iteration obtained by calling of
+.B cpg_iteration_initialize(3)
+function.
+The
+.I handle
+argument is iterator handle obtained by
+.B cpg_iteration_initialize(3)
+function.
+
+.SH RETURN VALUE
+This call returns the CS_OK value if successful. CS_ERR_BAD_HANDLE error is returned when handle
+is invalid.
+
+.SH "SEE ALSO"
+.BR cpg_iteration_initialize (3),
+.BR cpg_overview (3)
diff --git a/man/cpg_iteration_initialize.3.in b/man/cpg_iteration_initialize.3.in
new file mode 100644
index 0000000..3f0f439
--- /dev/null
+++ b/man/cpg_iteration_initialize.3.in
@@ -0,0 +1,96 @@
+.\"/*
+.\" * Copyright (c) 2012 Red Hat, Inc.
+.\" *
+.\" * All rights reserved.
+.\" *
+.\" * Author: Jan Friesse (jfriesse@redhat.com)
+.\" *
+.\" * This software licensed under BSD license, the text of which follows:
+.\" *
+.\" * Redistribution and use in source and binary forms, with or without
+.\" * modification, are permitted provided that the following conditions are met:
+.\" *
+.\" * - Redistributions of source code must retain the above copyright notice,
+.\" * this list of conditions and the following disclaimer.
+.\" * - Redistributions in binary form must reproduce the above copyright notice,
+.\" * this list of conditions and the following disclaimer in the documentation
+.\" * and/or other materials provided with the distribution.
+.\" * - Neither the name of the Red Hat, Inc. nor the names of its
+.\" * contributors may be used to endorse or promote products derived from this
+.\" * software without specific prior written permission.
+.\" *
+.\" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+.\" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+.\" * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+.\" * THE POSSIBILITY OF SUCH DAMAGE.
+.\" */
+.TH "CPG_ITERATION_INITIALIZE" 3 "05/03/2012" "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
+
+.SH NAME
+.P
+cpg_iteration_initialize \- Initialize iterator for members of CPG
+
+.SH SYNOPSIS
+.P
+\fB#include <corosync/cpg.h>\fR
+
+.P
+\fBcs_error_t
+cpg_iteration_initialize (cpg_handle_t \fIhandle\fB, cpg_iteration_type_t \fIiteration_type\fB,
+const struct cpg_name *\fIgroup\fB, cpg_iteration_handle_t *\fIcpg_iteration_handle\fB);\fR
+
+.SH DESCRIPTION
+.P
+The
+.B cpg_iteration_initialize
+function is used to initialize iteration of CPG members.
+The
+.I handle
+argument is connection to CPG database obtained by calling
+.B cpg_initialize(3)
+function.
+.I iteration_type
+is used for limit number of returned items and can be one of:
+.PP
+\fBCPG_ITERATION_NAME_ONLY\fR - only name of used groups are returned
+.PP
+\fBCPG_ITERATION_ONE_GROUP\fR - only members group with name \fIgroup\fR are returned
+.PP
+\fBCPG_ITERATION_ALL\fR - all members are returned
+
+The
+.I group
+parameter is used only with \fBCPG_ITERATION_ONE_GROUP\fR and it's name of group with
+members to iterate. For other \fIiteration_type\fR, this parameter must be NULL.
+
+.B cpg_iteration_initialize
+is used only for initialize context for future
+.B cpg_iteration_next(3)
+calls and handle needed for that function is returned in
+.I cpg_iteration_handle
+variable. When you have finished iteration over objects, call
+.B cpg_iteration_finalize(3)
+function to free up memory associated with iteration.
+
+.SH RETURN VALUE
+This call returns the CS_OK value if successful. If \fIcpg_iteration_handle\fR is NULL,
+\fBCS_ERR_INVALID_PARAM\fR error is returned. Same error is returned when \fIiteration_type\fR
+is \fBCPG_ITERATION_ONE_GROUP\fR, but \fIgroup\fR is NULL, or when \fIgroup\fR is not NULL and
+\fIiteration_type\fR is not \fBCPG_ITERATION_ONE_GROUP\fR. If there is not enough memory
+for internal store of data, \fBCS_ERR_NO_MEMORY\fR is returned. \fBCS_ERR_BAD_HANDLE\fR can
+be returned, if \fIhandle\fR is not valid handle.
+
+.SH COMMON IPC ERRORS
+@COMMONIPCERRORS@
+.SH "SEE ALSO"
+.BR cpg_iteration_next (3),
+.BR cpg_iteration_finalize (3),
+.BR cpg_initialize (3),
+.BR cpg_overview (3)
diff --git a/man/cpg_iteration_next.3.in b/man/cpg_iteration_next.3.in
new file mode 100644
index 0000000..c618802
--- /dev/null
+++ b/man/cpg_iteration_next.3.in
@@ -0,0 +1,85 @@
+.\"/*
+.\" * Copyright (c) 2012 Red Hat, Inc.
+.\" *
+.\" * All rights reserved.
+.\" *
+.\" * Author: Jan Friesse (jfriesse@redhat.com)
+.\" *
+.\" * This software licensed under BSD license, the text of which follows:
+.\" *
+.\" * Redistribution and use in source and binary forms, with or without
+.\" * modification, are permitted provided that the following conditions are met:
+.\" *
+.\" * - Redistributions of source code must retain the above copyright notice,
+.\" * this list of conditions and the following disclaimer.
+.\" * - Redistributions in binary form must reproduce the above copyright notice,
+.\" * this list of conditions and the following disclaimer in the documentation
+.\" * and/or other materials provided with the distribution.
+.\" * - Neither the name of the Red Hat, Inc. nor the names of its
+.\" * contributors may be used to endorse or promote products derived from this
+.\" * software without specific prior written permission.
+.\" *
+.\" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+.\" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+.\" * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+.\" * THE POSSIBILITY OF SUCH DAMAGE.
+.\" */
+.TH "CPG_ITERATION_NEXT" 3 "05/03/2012" "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
+
+.SH NAME
+.P
+cpg_iteration_next \- Return next item in iteration of CPG
+
+.SH SYNOPSIS
+.P
+\fB#include <corosync/cpg.h>\fR
+
+.P
+\fBcs_error_t
+cpg_iteration_next (cpg_iteration_handle_t \fIhandle\fB, struct cpg_iteration_description_t *\fIdescription\fB);\fR
+
+.SH DESCRIPTION
+.P
+The
+.B cpg_iter_next
+function is used to get next value in iteration. The
+.I handle
+argument is iterator handle obtained by
+.B cpg_iteration_initalize(3)
+function.
+.I description
+is pointer to structure with following definition:
+.IP
+.RS
+.ne 18
+.nf
+.PP
+struct cpg_iteration_description_t {
+ struct cpg_name group;
+ uint32_t nodeid;
+ uint32_t pid;
+};
+.ta
+.fi
+.RE
+.IP
+.PP
+
+where \fBgroup\fR is name of group, \fBnodeid\fR is ID of connected node and \fBpid\fR is pid of
+connected process. If iteration was initialized with \fBCPG_ITERATION_NAME_ONLY\fR iteration
+type, both \fBnodeid\fR and \fBpid\fR are 0.
+
+.SH RETURN VALUE
+This call returns the CS_OK value if successful. If there are no more items to iterate, CS_NO_SECTION
+error code is returned.
+
+.SH "SEE ALSO"
+.BR cpg_iteration_initialize (3),
+.BR cpg_overview (3)
diff --git a/man/cpg_join.3.in b/man/cpg_join.3.in
new file mode 100644
index 0000000..4496ec3
--- /dev/null
+++ b/man/cpg_join.3.in
@@ -0,0 +1,112 @@
+.\"/*
+.\" * Copyright (c) 2006 Red Hat, Inc.
+.\" *
+.\" * All rights reserved.
+.\" *
+.\" * Author: Patrick Caulfield <pcaulfie@redhat.com>
+.\" *
+.\" * This software licensed under BSD license, the text of which follows:
+.\" *
+.\" * Redistribution and use in source and binary forms, with or without
+.\" * modification, are permitted provided that the following conditions are met:
+.\" *
+.\" * - Redistributions of source code must retain the above copyright notice,
+.\" * this list of conditions and the following disclaimer.
+.\" * - Redistributions in binary form must reproduce the above copyright notice,
+.\" * this list of conditions and the following disclaimer in the documentation
+.\" * and/or other materials provided with the distribution.
+.\" * - Neither the name of the MontaVista Software, Inc. nor the names of its
+.\" * contributors may be used to endorse or promote products derived from this
+.\" * software without specific prior written permission.
+.\" *
+.\" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+.\" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+.\" * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+.\" * THE POSSIBILITY OF SUCH DAMAGE.
+.\" */
+.TH CPG_JOIN 3 2004-08-31 "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
+.SH NAME
+cpg_join \- Joins one or more groups in the CPG library
+.SH SYNOPSIS
+.B #include <corosync/cpg.h>
+.sp
+.BI "int cpg_join(cpg_handle_t " handle ", struct cpg_name *" group ");
+.SH DESCRIPTION
+The
+.B cpg_join
+function is used to join one group. When a group is joined, the
+.B cpg_mcast_joined(3)
+is called internally to multicast to the groups joined in the argument
+.I handle.
+The process will also get notifications of other processes joining
+and leaving the group.
+Messages that are sent to any of the groups joined to the parameter
+.I handle
+will be delivered by
+.B cpg_dispatch(3).
+.PP
+This function may be only be called once for each handle. When a group has been joined
+the process will start to receive callbacks relating to messages sent from members
+of the group or notifications of processes joining or leaving the group.
+.PP
+Note that more than one process on each node can join a CPG group and
+each will receive its own copy of any messages sent using
+.I cpg_mcast_joined()
+and its own confchg callback.
+.PP
+
+The argument
+.I group
+is used to specify the group to join.
+
+
+The
+.I groups
+argument is of the type struct cpg_name which is defined by the structure:
+
+.IP
+.RS
+.ne 18
+.nf
+.ta 4n 30n 33n
+struct cpg_name {
+ int length;
+ char value[128];
+};
+.ta
+.fi
+.RE
+.IP
+.PP
+.PP
+.SH RETURN VALUE
+This call returns the CS_OK value if successful, CS_ERR_INVALID_PARAM if the
+handle is already joined to a group.
+.PP
+.SH ERRORS
+Not all errors are documented.
+.SH "SEE ALSO"
+.BR cpg_overview (3),
+.BR cpg_initialize (3),
+.BR cpg_finalize (3),
+.BR cpg_fd_get (3),
+.BR cpg_dispatch (3),
+.BR cpg_join (3),
+.BR cpg_leave (3),
+.BR cpg_mcast_joined (3),
+.BR cpg_membership_get (3)
+.BR cpg_zcb_alloc (3)
+.BR cpg_zcb_free (3)
+.BR cpg_zcb_mcast_joined (3)
+.BR cpg_context_get (3)
+.BR cpg_context_set (3)
+.BR cpg_local_get (3)
+
+.PP
diff --git a/man/cpg_leave.3.in b/man/cpg_leave.3.in
new file mode 100644
index 0000000..253e343
--- /dev/null
+++ b/man/cpg_leave.3.in
@@ -0,0 +1,77 @@
+.\"/*
+.\" * Copyright (c) 2006 Red Hat, Inc.
+.\" *
+.\" * All rights reserved.
+.\" *
+.\" * Author: Patrick Caulfield <pcaulfie@redhat.com>
+.\" *
+.\" * This software licensed under BSD license, the text of which follows:
+.\" *
+.\" * Redistribution and use in source and binary forms, with or without
+.\" * modification, are permitted provided that the following conditions are met:
+.\" *
+.\" * - Redistributions of source code must retain the above copyright notice,
+.\" * this list of conditions and the following disclaimer.
+.\" * - Redistributions in binary form must reproduce the above copyright notice,
+.\" * this list of conditions and the following disclaimer in the documentation
+.\" * and/or other materials provided with the distribution.
+.\" * - Neither the name of the MontaVista Software, Inc. nor the names of its
+.\" * contributors may be used to endorse or promote products derived from this
+.\" * software without specific prior written permission.
+.\" *
+.\" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+.\" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+.\" * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+.\" * THE POSSIBILITY OF SUCH DAMAGE.
+.\" */
+.TH CPG_LEAVE 3 2004-08-31 "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
+.SH NAME
+cpg_leave \- Leave a group in the CPG library
+.SH SYNOPSIS
+.B #include <corosync/cpg.h>
+.sp
+.BI "int cpg_leave(cpg_handle_t " handle ", struct cpg_name *" group ");
+.SH DESCRIPTION
+The
+.B cpg_leave
+function is used to leave a group. Once a group has been left the process will
+no longer receive messages or notifications about events in that group.
+Note that a process is only deemed to have left the group once it has been
+notified (by its confchg callback) that is has left.
+So expect to receive at least one confchg callback after calling this function.
+
+The argument
+.I group
+is used to specify the group to leave. It is currently ignored as only one group
+can be joined per handle. It is included here for to allow for future development.
+
+.SH RETURN VALUE
+This call returns the CS_OK value if successful, otherwise an error is returned.
+.PP
+.SH ERRORS
+The errors are undocumented.
+.SH "SEE ALSO"
+.BR cpg_overview (3),
+.BR cpg_initialize (3),
+.BR cpg_finalize (3),
+.BR cpg_fd_get (3),
+.BR cpg_dispatch (3),
+.BR cpg_join (3),
+.BR cpg_leave (3),
+.BR cpg_mcast_joined (3),
+.BR cpg_membership_get (3)
+.BR cpg_zcb_alloc (3)
+.BR cpg_zcb_free (3)
+.BR cpg_zcb_mcast_joined (3)
+.BR cpg_context_get (3)
+.BR cpg_context_set (3)
+.BR cpg_local_get (3)
+
+.PP
diff --git a/man/cpg_local_get.3.in b/man/cpg_local_get.3.in
new file mode 100644
index 0000000..1e01779
--- /dev/null
+++ b/man/cpg_local_get.3.in
@@ -0,0 +1,72 @@
+.\"/*
+.\" * Copyright (c) 2007 Red Hat, Inc.
+.\" *
+.\" * All rights reserved.
+.\" *
+.\" * Author: Steven Dake <sdake@redhat.com>
+.\" *
+.\" * This software licensed under BSD license, the text of which follows:
+.\" *
+.\" * Redistribution and use in source and binary forms, with or without
+.\" * modification, are permitted provided that the following conditions are met:
+.\" *
+.\" * - Redistributions of source code must retain the above copyright notice,
+.\" * this list of conditions and the following disclaimer.
+.\" * - Redistributions in binary form must reproduce the above copyright notice,
+.\" * this list of conditions and the following disclaimer in the documentation
+.\" * and/or other materials provided with the distribution.
+.\" * - Neither the name of the MontaVista Software, Inc. nor the names of its
+.\" * contributors may be used to endorse or promote products derived from this
+.\" * software without specific prior written permission.
+.\" *
+.\" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+.\" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+.\" * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+.\" * THE POSSIBILITY OF SUCH DAMAGE.
+.\" */
+.TH CPG_LOCAL_GET 3 2007-06-12 "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
+.SH NAME
+cpg_local_get \- Returns the local node id
+.SH SYNOPSIS
+.B #include <corosync/cpg.h>
+.sp
+.BI "int cpg_local_get(cpg_handle_t " handle ", unsigned int *" local_nodeid ");
+.SH DESCRIPTION
+The
+.B cpg_local_get
+function is used to determine the local node's identifier.
+.BR
+The argument
+.I handle
+is used to reference the cpg instantiation.
+The argument
+.I local_nodeid
+will return the 32 bit node id.
+.PP
+.SH ERRORS
+The errors are undocumented.
+.SH "SEE ALSO"
+.BR cpg_overview (3),
+.BR cpg_initialize (3),
+.BR cpg_finalize (3),
+.BR cpg_fd_get (3),
+.BR cpg_dispatch (3),
+.BR cpg_join (3),
+.BR cpg_leave (3),
+.BR cpg_mcast_joined (3),
+.BR cpg_membership_get (3)
+.BR cpg_zcb_alloc (3)
+.BR cpg_zcb_free (3)
+.BR cpg_zcb_mcast_joined (3)
+.BR cpg_context_get (3)
+.BR cpg_context_set (3)
+.BR cpg_local_get (3)
+
+.PP
diff --git a/man/cpg_mcast_joined.3.in b/man/cpg_mcast_joined.3.in
new file mode 100644
index 0000000..d4f8867
--- /dev/null
+++ b/man/cpg_mcast_joined.3.in
@@ -0,0 +1,142 @@
+.\"/*
+.\" * Copyright (c) 2006 Red Hat, Inc.
+.\" *
+.\" * All rights reserved.
+.\" *
+.\" * Author: Patrick Caulfield <pcaulfie@redhat.com>
+.\" *
+.\" * This software licensed under BSD license, the text of which follows:
+.\" *
+.\" * Redistribution and use in source and binary forms, with or without
+.\" * modification, are permitted provided that the following conditions are met:
+.\" *
+.\" * - Redistributions of source code must retain the above copyright notice,
+.\" * this list of conditions and the following disclaimer.
+.\" * - Redistributions in binary form must reproduce the above copyright notice,
+.\" * this list of conditions and the following disclaimer in the documentation
+.\" * and/or other materials provided with the distribution.
+.\" * - Neither the name of the MontaVista Software, Inc. nor the names of its
+.\" * contributors may be used to endorse or promote products derived from this
+.\" * software without specific prior written permission.
+.\" *
+.\" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+.\" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+.\" * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+.\" * THE POSSIBILITY OF SUCH DAMAGE.
+.\" */
+.TH CPG_MCAST_JOINED 3 2004-08-31 "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
+.SH NAME
+cpg_mcast_joined \- Multicasts to all groups joined to a handle
+.SH SYNOPSIS
+.nf
+.B #include <sys/uio.h>
+.B #include <corosync/cpg.h>
+.sp
+.BI "int cpg_mcast_joined(cpg_handle_t " handle ", cpg_guarantee_t " guarantee ", struct iovec *" iovec ", int " iov_len ");
+.SH DESCRIPTION
+The
+.B cpg_mcast_joined
+function will multicast a message to all the processes that have been joined with the
+.B cpg_join(3)
+function for the same group name.
+Messages that are sent to any of the groups joined to the parameter
+.I handle
+will be delivered to all subscribed processes in the system.
+.PP
+The argument
+.I guarantee
+requests a delivery guarantee for the message to be sent. The cpg_guarantee_t type is
+defined by:
+.IP
+.RS
+.ne 18
+.nf
+.ta 4n 30n 33n
+typedef enum {
+ CPG_TYPE_UNORDERED, /* not implemented */
+ CPG_TYPE_FIFO, /* same as agreed */
+ CPG_TYPE_AGREED, /* implemented */
+ CPG_TYPE_SAFE /* not implemented */
+} cpg_guarantee_t;
+.ta
+.fi
+.RE
+.IP
+.PP
+.PP
+The meanings of the cpg_guarantee_t typedef are:
+.TP
+.B CPG_TYPE_UNORDERED
+Messages are guaranteed to be delivered, but with no particular order. This
+mode is unimplemented in the CPG library.
+.TP
+.B CPG_TYPE_FIFO
+Messages are guaranteed to be delivered in first sent first delivery order.
+In fact, this guarantee is equivalent to the CPG_TYPE_AGREED guarantee.
+.TP
+.B CPG_TYPE_AGREED
+All processors must agree on the order of delivery. If a message is sent
+from two or more processes at about the same time, the delivery will occur
+in the same order to all processes.
+.TP
+.B CPG_TYPE_SAFE
+All processes must agree on the order of delivery. Further all processes
+must have a copy of the message before any delivery takes place. This mode is
+unimplemented in the CPG library.
+.PP
+The
+.I iovec
+argument describes the scatter/gather list which is used to transmit a message. This
+is a iovec described by:
+.IP
+.RS
+.ne 18
+.nf
+.ta 4n 30n 33n
+struct iovec
+{
+ void *iov_base; /* Pointer to data. */
+ unsigned int iov_len; /* Length of data. */
+};
+.ta
+.fi
+.RE
+.IP
+.PP
+.PP
+The
+.I iov_len
+argument describes the number of entries in the
+.I iovec
+argument.
+
+.SH RETURN VALUE
+This call returns the CS_OK value if successful, otherwise an error is returned.
+.PP
+.SH ERRORS
+The errors are undocumented.
+.SH "SEE ALSO"
+.BR cpg_overview (3),
+.BR cpg_initialize (3),
+.BR cpg_finalize (3),
+.BR cpg_fd_get (3),
+.BR cpg_dispatch (3),
+.BR cpg_join (3),
+.BR cpg_leave (3),
+.BR cpg_mcast_joined (3),
+.BR cpg_membership_get (3)
+.BR cpg_zcb_alloc (3)
+.BR cpg_zcb_free (3)
+.BR cpg_zcb_mcast_joined (3)
+.BR cpg_context_get (3)
+.BR cpg_context_set (3)
+.BR cpg_local_get (3)
+
+.PP
diff --git a/man/cpg_membership_get.3.in b/man/cpg_membership_get.3.in
new file mode 100644
index 0000000..75c1a74
--- /dev/null
+++ b/man/cpg_membership_get.3.in
@@ -0,0 +1,81 @@
+.\"/*
+.\" * Copyright (c) 2006 Red Hat, Inc.
+.\" *
+.\" * All rights reserved.
+.\" *
+.\" * Author: Patrick Caulfield <pcaulfie@redhat.com>
+.\" *
+.\" * This software licensed under BSD license, the text of which follows:
+.\" *
+.\" * Redistribution and use in source and binary forms, with or without
+.\" * modification, are permitted provided that the following conditions are met:
+.\" *
+.\" * - Redistributions of source code must retain the above copyright notice,
+.\" * this list of conditions and the following disclaimer.
+.\" * - Redistributions in binary form must reproduce the above copyright notice,
+.\" * this list of conditions and the following disclaimer in the documentation
+.\" * and/or other materials provided with the distribution.
+.\" * - Neither the name of the MontaVista Software, Inc. nor the names of its
+.\" * contributors may be used to endorse or promote products derived from this
+.\" * software without specific prior written permission.
+.\" *
+.\" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+.\" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+.\" * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+.\" * THE POSSIBILITY OF SUCH DAMAGE.
+.\" */
+.TH CPG_MEMBERSHIP_GET 3 2006-02-06 "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
+.SH NAME
+cpg_membership_get \- Returns a list of members of a CPG group
+.SH SYNOPSIS
+.B #include <corosync/cpg.h>
+.sp
+.BI "int cpg_membership_get(cpg_handle_t " handle ", struct cpg_name *" groupName ", struct cpg_address *" member_list ", int *" member_list_entries ");
+.SH DESCRIPTION
+The
+.B cpg_membership_get
+function is used to determine the current processes in the configuration. You probably will not
+need to call this function much as one of the first confchg callbacks you will get will be from
+the cpg_join() function containing your process.
+.BR
+The argument
+.I handle
+is used to reference the cpg instantiation.
+The argument
+.I groupName
+will return the name of the group
+The argument
+.I member_list
+will return the list of processors in the current membership.
+The argument
+.I member_list_entries
+should be set with the size of member_list and will return the size of the
+member_list after return from the function.
+.PP
+.SH ERRORS
+The errors are undocumented.
+.SH "SEE ALSO"
+.BR cpg_overview (3),
+.BR cpg_initialize (3),
+.BR cpg_finalize (3),
+.BR cpg_fd_get (3),
+.BR cpg_dispatch (3),
+.BR cpg_join (3),
+.BR cpg_leave (3),
+.BR cpg_mcast_joined (3),
+.BR cpg_membership_get (3)
+.BR cpg_zcb_alloc (3)
+.BR cpg_zcb_free (3)
+.BR cpg_zcb_mcast_joined (3)
+.BR cpg_context_get (3)
+.BR cpg_context_set (3)
+.BR cpg_local_get (3)
+
+.PP
diff --git a/man/cpg_model_initialize.3.in b/man/cpg_model_initialize.3.in
new file mode 100644
index 0000000..17ca16a
--- /dev/null
+++ b/man/cpg_model_initialize.3.in
@@ -0,0 +1,233 @@
+.\"/*
+.\" * Copyright (c) 2010-2019 Red Hat, Inc.
+.\" *
+.\" * All rights reserved.
+.\" *
+.\" * Author: Jan Friesse <jfriesse@redhat.com>
+.\" * Author: Christine Caulfield <ccaulfie@redhat.com>
+.\" *
+.\" * This software licensed under BSD license, the text of which follows:
+.\" *
+.\" * Redistribution and use in source and binary forms, with or without
+.\" * modification, are permitted provided that the following conditions are met:
+.\" *
+.\" * - Redistributions of source code must retain the above copyright notice,
+.\" * this list of conditions and the following disclaimer.
+.\" * - Redistributions in binary form must reproduce the above copyright notice,
+.\" * this list of conditions and the following disclaimer in the documentation
+.\" * and/or other materials provided with the distribution.
+.\" * - Neither the name of the MontaVista Software, Inc. nor the names of its
+.\" * contributors may be used to endorse or promote products derived from this
+.\" * software without specific prior written permission.
+.\" *
+.\" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+.\" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+.\" * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+.\" * THE POSSIBILITY OF SUCH DAMAGE.
+.\" */
+.TH CPG_MODEL_INITIALIZE 3 2019-04-16 "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
+.SH NAME
+cpg_model_initialize \- Create a new connection to the CPG service
+.SH SYNOPSIS
+.B #include <corosync/cpg.h>
+.sp
+.BI "cs_error_t cpg_model_initialize(cpg_handle_t *" handle ", cpg_model_t " model ", cpg_model_data_t *" model_data ", void *" context ");
+
+.SH DESCRIPTION
+The
+.B cpg_model_initialize
+function is used to initialize a connection to the closed process groups API.
+.PP
+Each application may have several connections to the CPG API. Each application
+uses the
+.I handle
+argument to uniquely identify the connection. The
+.I handle
+argument is then used in other function calls to identify the connection to be used
+for communication with the CPG service.
+.PP
+Argument
+.I model
+is used to explicitly choose set of callbacks and internal parameters. Currently only model
+.I CPG_MODEL_V1
+is defined.
+.PP
+Callbacks and internal parameters are passed by
+.I model_data
+argument. This is casted pointer (idea is similar as in sockaddr function) to one of structures
+corresponding to chosen model. Currently only
+.I cpg_model_v1_data_t
+is needed.
+.SH MODEL_V1
+The
+.I MODEL_V1
+is backwards compatible with original callbacks initialized by
+.I cpg_initialize
+but new callback
+.I cpg_totem_confchg_fn
+is defined.
+.PP
+Every time an CPG event occurs within the joined group, one of the callbacks specified by the argument
+.I callbacks
+is called. The callback functions are described by the following type definitions:
+.PP
+.PP
+.IP
+.RS
+.ne 18
+.nf
+.ta 4n 20n 32n
+
+typedef void (*cpg_deliver_fn_t) (
+ cpg_handle_t handle,
+ const struct cpg_name *group_name,
+ uint32_t nodeid,
+ uint32_t pid,
+ const void *msg,
+ size_t msg_len);
+
+
+typedef void (*cpg_confchg_fn_t) (
+ cpg_handle_t handle,
+ const struct cpg_name *group_name,
+ const struct cpg_address *member_list, size_t member_list_entries,
+ const struct cpg_address *left_list, size_t left_list_entries,
+ const struct cpg_address *joined_list, size_t joined_list_entries);
+
+
+typedef void (*cpg_totem_confchg_fn_t) (
+ cpg_handle_t handle,
+ struct cpg_ring_id ring_id,
+ uint32_t member_list_entries,
+ const uint32_t *member_list);
+.ta
+.fi
+.RE
+.IP
+.PP
+.PP
+The
+.I cpg_model_v1_data_t
+structure is defined as:
+.IP
+.RS
+.ne 18
+.nf
+.PP
+typedef struct {
+ cpg_model_t model;
+ cpg_deliver_fn_t cpg_deliver_fn;
+ cpg_confchg_fn_t cpg_confchg_fn;
+ cpg_totem_confchg_fn_t cpg_totem_confchg_fn;
+ unsigned int flags;
+} cpg_model_v1_data_t;
+.ta
+.fi
+.RE
+.IP
+.PP
+When a configuration change occurs or a message is to be delivered one of the callbacks
+is called from the
+.B cpg_dispatch()
+function. If a configuration change occurs,
+.I cpg_confchg_fn
+is called. If a delivery of a message occurs,
+.I cpg_deliver_fn
+is called.
+When totem membership change occurs,
+.I cpg_totem_confchg_fn
+is called. You can OR
+.I CPG_MODEL_V1_DELIVER_INITIAL_TOTEM_CONF
+constant to flags to get callback after first confchg event.
+
+The
+.I cpg_address
+structure is defined
+.IP
+.RS
+.ne 18
+.nf
+.PP
+struct cpg_address {
+ unsigned int nodeid;
+ unsigned int pid;
+ unsigned int reason;
+};
+.ta
+.fi
+.RE
+.IP
+.PP
+where nodeid is a 32 bit unique node identifier, pid is the process ID of the process that has joined/left the group
+or sent the message, and reason is an integer code indicating why the node joined/left the group (this value is not
+set for the member_list items).
+.PP
+.IP
+.RS
+.ne 18
+.nf
+.PP
+CPG_REASON_JOIN - the process joined a group using cpg_join().
+CPG_REASON_LEAVE - the process left a group using cpg_leave()
+CPG_REASON_NODEDOWN - the process left a group because the node left the cluster.
+CPG_REASON_NODEUP - the process joined a group because it was already a member of a group on a node that has just joined the cluster
+CPG_REASON_PROCDOWN - the process left a group without calling cpg_leave()
+CPG_REASON_UNDEFINED - a special value used for the member_list items
+.ta
+.fi
+.RE
+.IP
+.PP
+The
+.I cpg_ring_id
+structure is defined
+.IP
+.RS
+.ne 18
+.nf
+.PP
+struct cpg_ring_id {
+ uint32_t nodeid;
+ uint64_t seq;
+};
+.ta
+.fi
+.RE
+.IP
+.PP
+where
+.I nodeid
+is if of node of current Totem leader and seq is increasing number.
+
+.PP
+.SH RETURN VALUE
+This call returns the CS_OK value if successful, otherwise an error is returned.
+.PP
+.SH ERRORS
+The errors are undocumented.
+.SH "SEE ALSO"
+.BR cpg_overview (3),
+.BR cpg_initialize (3),
+.BR cpg_finalize (3),
+.BR cpg_fd_get (3),
+.BR cpg_dispatch (3),
+.BR cpg_join (3),
+.BR cpg_leave (3),
+.BR cpg_mcast_joined (3),
+.BR cpg_membership_get (3)
+.BR cpg_zcb_alloc (3)
+.BR cpg_zcb_free (3)
+.BR cpg_zcb_mcast_joined (3)
+.BR cpg_context_get (3)
+.BR cpg_context_set (3)
+.BR cpg_local_get (3)
+.BR cpg_model_initialize (3)
+
+.PP
diff --git a/man/cpg_overview.3 b/man/cpg_overview.3
new file mode 100644
index 0000000..d36d65f
--- /dev/null
+++ b/man/cpg_overview.3
@@ -0,0 +1,82 @@
+.\"/*
+.\" * Copyright (c) 2006-2009 Red Hat, Inc.
+.\" *
+.\" * All rights reserved.
+.\" *
+.\" * Author: Patrick Caulfield <pcaulfie@redhat.com>
+.\" *
+.\" * This software licensed under BSD license, the text of which follows:
+.\" *
+.\" * Redistribution and use in source and binary forms, with or without
+.\" * modification, are permitted provided that the following conditions are met:
+.\" *
+.\" * - Redistributions of source code must retain the above copyright notice,
+.\" * this list of conditions and the following disclaimer.
+.\" * - Redistributions in binary form must reproduce the above copyright notice,
+.\" * this list of conditions and the following disclaimer in the documentation
+.\" * and/or other materials provided with the distribution.
+.\" * - Neither the name of the MontaVista Software, Inc. nor the names of its
+.\" * contributors may be used to endorse or promote products derived from this
+.\" * software without specific prior written permission.
+.\" *
+.\" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+.\" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+.\" * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+.\" * THE POSSIBILITY OF SUCH DAMAGE.
+.\" */
+.TH CPG_OVERVIEW 3 2009-4-15 "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
+.SH NAME
+cpg_overview \- CPG library overview
+.SH OVERVIEW
+The CPG library is delivered with the corosync project. This library is used
+to create distributed applications that operate properly during cluster
+partitions, merges, and faults.
+.PP
+The library provides a mechanism to:
+.PP
+* handle abstraction for multiple instances of a CPG library in one application
+.PP
+* join one or more groups
+.PP
+* leave one or more groups
+.PP
+* Deliver messages to members of that group
+.PP
+* Deliver configuration changes
+.PP
+* Iterate members of groups
+.PP
+.SH SECURITY
+If encryption is enabled in corosync.conf, the CPG library will encrypt and
+authenticate message contents. Applications must run as the ais user to be
+validated by corosync on IPC connection, otherwise they will be unable to
+access the corosync services.
+
+.SH "SEE ALSO"
+.BR cpg_overview (3),
+.BR cpg_initialize (3),
+.BR cpg_finalize (3),
+.BR cpg_fd_get (3),
+.BR cpg_dispatch (3),
+.BR cpg_join (3),
+.BR cpg_leave (3),
+.BR cpg_mcast_joined (3),
+.BR cpg_model_initialize (3),
+.BR cpg_membership_get (3),
+.BR cpg_zcb_alloc (3),
+.BR cpg_zcb_free (3),
+.BR cpg_zcb_mcast_joined (3),
+.BR cpg_context_get (3),
+.BR cpg_context_set (3),
+.BR cpg_local_get (3),
+.BR cpg_iteration_initialize (3),
+.BR cpg_iteration_next (3),
+.BR cpg_iteration_finalize (3)
+.PP
diff --git a/man/cpg_zcb_alloc.3.in b/man/cpg_zcb_alloc.3.in
new file mode 100644
index 0000000..31b1776
--- /dev/null
+++ b/man/cpg_zcb_alloc.3.in
@@ -0,0 +1,85 @@
+.\"/*
+.\" * Copyright (c) 2009 Red Hat, Inc.
+.\" *
+.\" * All rights reserved.
+.\" *
+.\" * Author: Steven Dake <sdake@redhat.com>
+.\" *
+.\" * This software licensed under BSD license, the text of which follows:
+.\" *
+.\" * Redistribution and use in source and binary forms, with or without
+.\" * modification, are permitted provided that the following conditions are met:
+.\" *
+.\" * - Redistributions of source code must retain the above copyright notice,
+.\" * this list of conditions and the following disclaimer.
+.\" * - Redistributions in binary form must reproduce the above copyright notice,
+.\" * this list of conditions and the following disclaimer in the documentation
+.\" * and/or other materials provided with the distribution.
+.\" * - Neither the name of the MontaVista Software, Inc. nor the names of its
+.\" * contributors may be used to endorse or promote products derived from this
+.\" * software without specific prior written permission.
+.\" *
+.\" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+.\" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+.\" * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+.\" * THE POSSIBILITY OF SUCH DAMAGE.
+.\" */
+.TH "CPG_ZCB_ALLOC" 3 "2009-04-15" "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
+.SH NAME
+cpg_zcb_alloc \- Allocates a zero copy buffer
+.SH SYNOPSIS
+.B #include <corosync/cpg.h>
+.sp
+.BI "int cpg_zcb_alloc(cpg_handle_t " handle ", size_t " size ", void **" buffer ");
+.SH DESCRIPTION
+The
+.B cpg_zcb_alloc
+function will allocate a zero copy buffer for use with the
+.B cpg_zcb_mcast_joined(3)
+function. This buffer should not be used in another thread while a
+cpg_zcb_mcast_joined operation is taking place on the buffer. The buffer is
+allocated via operating system mechanisms to avoid copying in the IPC layer.
+
+.PP
+The argument
+.I handle
+describes the handle on which the buffer will be allocated.
+.PP
+The argument
+.I size
+requests a buffer of size be allocated.
+.PP
+The
+.I buffer
+argument is set to the buffer address that is allocated by this operation.
+
+.SH RETURN VALUE
+This call returns the CS_OK value if successful, otherwise an error is returned.
+.PP
+.SH ERRORS
+The errors are undocumented.
+.SH "SEE ALSO"
+.BR cpg_overview (3),
+.BR cpg_initialize (3),
+.BR cpg_finalize (3),
+.BR cpg_fd_get (3),
+.BR cpg_dispatch (3),
+.BR cpg_join (3),
+.BR cpg_leave (3),
+.BR cpg_mcast_joined (3),
+.BR cpg_membership_get (3)
+.BR cpg_zcb_alloc (3)
+.BR cpg_zcb_free (3)
+.BR cpg_zcb_mcast_joined (3)
+.BR cpg_context_get (3)
+.BR cpg_context_set (3)
+.BR cpg_local_get (3)
+
+.PP
diff --git a/man/cpg_zcb_free.3.in b/man/cpg_zcb_free.3.in
new file mode 100644
index 0000000..ef68c39
--- /dev/null
+++ b/man/cpg_zcb_free.3.in
@@ -0,0 +1,77 @@
+.\"/*
+.\" * Copyright (c) 2009 Red Hat, Inc.
+.\" *
+.\" * All rights reserved.
+.\" *
+.\" * Author: Steven Dake <sdake@redhat.com>
+.\" *
+.\" * This software licensed under BSD license, the text of which follows:
+.\" *
+.\" * Redistribution and use in source and binary forms, with or without
+.\" * modification, are permitted provided that the following conditions are met:
+.\" *
+.\" * - Redistributions of source code must retain the above copyright notice,
+.\" * this list of conditions and the following disclaimer.
+.\" * - Redistributions in binary form must reproduce the above copyright notice,
+.\" * this list of conditions and the following disclaimer in the documentation
+.\" * and/or other materials provided with the distribution.
+.\" * - Neither the name of the MontaVista Software, Inc. nor the names of its
+.\" * contributors may be used to endorse or promote products derived from this
+.\" * software without specific prior written permission.
+.\" *
+.\" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+.\" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+.\" * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+.\" * THE POSSIBILITY OF SUCH DAMAGE.
+.\" */
+.TH "CPG_ZCB_FREE" 3 "2009-04-15" "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
+.SH NAME
+cpg_zcb_free \- Frees a zero copy buffer
+.SH SYNOPSIS
+.B #include <corosync/cpg.h>
+.sp
+.BI "int cpg_zcb_fre(cpg_handle_t " handle ", void *" buffer ");
+.SH DESCRIPTION
+The
+.B cpg_zcb_free
+function will free a zero copy buffer.
+
+.PP
+The argument
+.I handle
+describes the handle on which the buffer will be allocated.
+.PP
+The argument
+.I buffer
+is the zero copy buffer to free.
+
+.SH RETURN VALUE
+This call returns the CS_OK value if successful, otherwise an error is returned.
+.PP
+.SH ERRORS
+The errors are undocumented.
+.SH "SEE ALSO"
+.BR cpg_overview (3),
+.BR cpg_initialize (3),
+.BR cpg_finalize (3),
+.BR cpg_fd_get (3),
+.BR cpg_dispatch (3),
+.BR cpg_join (3),
+.BR cpg_leave (3),
+.BR cpg_mcast_joined (3),
+.BR cpg_membership_get (3)
+.BR cpg_zcb_alloc (3)
+.BR cpg_zcb_free (3)
+.BR cpg_zcb_mcast_joined (3)
+.BR cpg_context_get (3)
+.BR cpg_context_set (3)
+.BR cpg_local_get (3)
+
+.PP
diff --git a/man/cpg_zcb_mcast_joined.3.in b/man/cpg_zcb_mcast_joined.3.in
new file mode 100644
index 0000000..42141b4
--- /dev/null
+++ b/man/cpg_zcb_mcast_joined.3.in
@@ -0,0 +1,127 @@
+.\"/*
+.\" * Copyright (c) 2009 Red Hat, Inc.
+.\" *
+.\" * All rights reserved.
+.\" *
+.\" * Author: Steven Dake <sdake@redhat.com>
+.\" *
+.\" * This software licensed under BSD license, the text of which follows:
+.\" *
+.\" * Redistribution and use in source and binary forms, with or without
+.\" * modification, are permitted provided that the following conditions are met:
+.\" *
+.\" * - Redistributions of source code must retain the above copyright notice,
+.\" * this list of conditions and the following disclaimer.
+.\" * - Redistributions in binary form must reproduce the above copyright notice,
+.\" * this list of conditions and the following disclaimer in the documentation
+.\" * and/or other materials provided with the distribution.
+.\" * - Neither the name of the MontaVista Software, Inc. nor the names of its
+.\" * contributors may be used to endorse or promote products derived from this
+.\" * software without specific prior written permission.
+.\" *
+.\" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+.\" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+.\" * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+.\" * THE POSSIBILITY OF SUCH DAMAGE.
+.\" */
+.TH CPG_ZCB_MCAST_JOINED 3 2004-08-31 "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
+.SH NAME
+cpg_mcast_joined \- Multicasts a zero copy buffer to all groups joined to a handle
+.SH SYNOPSIS
+.B #include <sys/uio.h>
+.B #include <corosync/cpg.h>
+.sp
+.BI "int cpg_zcb_mcast_joined(cpg_handle_t " handle ", cpg_guarantee_t " guarantee ", const void *" buffer "", int " msg_len ");
+.SH DESCRIPTION
+The
+.B cpg_zcb_mcast_joined
+function will multicast a zero copy buffer message to all the processes that
+have been joined with the
+.B cpg_join(3)
+function for the same group name.
+Messages that are sent to any of the groups joined to the parameter
+.I handle
+will be delivered to all subscribed processes in the system.
+.PP
+The argument
+.I guarantee
+requests a delivery guarantee for the message to be sent. The cpg_guarantee_t type is
+defined by:
+.IP
+.RS
+.ne 18
+.nf
+.ta 4n 30n 33n
+typedef enum {
+ CPG_TYPE_UNORDERED, /* not implemented */
+ CPG_TYPE_FIFO, /* same as agreed */
+ CPG_TYPE_AGREED, /* implemented */
+ CPG_TYPE_SAFE /* not implemented */
+} cpg_guarantee_t;
+.ta
+.fi
+.RE
+.IP
+.PP
+.PP
+The meanings of the cpg_guarantee_t typedef are:
+.TP
+.B CPG_TYPE_UNORDERED
+Messages are guaranteed to be delivered, but with no particular order. This
+mode is unimplemented in the CPG library.
+.TP
+.B CPG_TYPE_FIFO
+Messages are guaranteed to be delivered in first sent first delivery order.
+In fact, this guarantee is equivalent to the CPG_TYPE_AGREED guarantee.
+.TP
+.B CPG_TYPE_AGREED
+All processors must agree on the order of delivery. If a message is sent
+from two or more processes at about the same time, the delivery will occur
+in the same order to all processes.
+.TP
+.B CPG_TYPE_SAFE
+All processes must agree on the order of delivery. Further all processes
+must have a copy of the message before any delivery takes place. This mode is
+unimplemented in the CPG library.
+.PP
+The
+.I msg
+argument describes the zero copy buffer which is used to transmit a message.
+this buffer must be allocated by
+.B cpg_zcb_alloc(3).
+
+.PP
+The
+.I msg_len
+argument describes the number of bytes to be transmitted in the zero copy buffer.
+
+.SH RETURN VALUE
+This call returns the CS_OK value if successful, otherwise an error is returned.
+.PP
+.SH ERRORS
+The errors are undocumented.
+.SH "SEE ALSO"
+.BR cpg_overview (3),
+.BR cpg_initialize (3),
+.BR cpg_finalize (3),
+.BR cpg_fd_get (3),
+.BR cpg_dispatch (3),
+.BR cpg_join (3),
+.BR cpg_leave (3),
+.BR cpg_mcast_joined (3),
+.BR cpg_membership_get (3)
+.BR cpg_zcb_alloc (3)
+.BR cpg_zcb_free (3)
+.BR cpg_zcb_mcast_joined (3)
+.BR cpg_context_get (3)
+.BR cpg_context_set (3)
+.BR cpg_local_get (3)
+
+.PP
diff --git a/man/index.html b/man/index.html
new file mode 100644
index 0000000..21326dc
--- /dev/null
+++ b/man/index.html
@@ -0,0 +1,400 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
+<html lang="en" dir="ltr">
+
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-15">
+ <meta name="keywords" content="corosync, documentation, manual">
+ <meta name="author" content="many">
+ <meta name="copyright" content="&copy; 2009 Red Hat, Inc.">
+ <!-- meta http-equiv="Content-Style-Type" content="text/css" -->
+ <meta name="date" content="2009-03-17T13:50:00+01:00">
+
+ <title>Corosync Documentation</title>
+ </head>
+
+ <body>
+
+ <h1>Welcome to the corosync project's manual pages.</h1>
+
+ <p>
+ <h2>Daemon, tools and configuration</h2>
+
+ <a href="corosync_overview.7.html">corosync_overview(7)</a>:
+ Overview of the corosync system.
+ <br>
+
+ <a href="corosync.conf.5.html">corosync.conf(5)</a>:
+ Description of configuration options for corosync.
+ <br>
+
+ <a href="corosync.xml.5.html">corosync.xml(5)</a>:
+ Description of configuration options for corosync xml config format.
+ <br>
+
+ <a href="votequorum.5.html">votequorum(5)</a>:
+ Description of configuration options for votequorum module in corosync.conf
+ <br>
+
+ <a href="corosync.8.html">corosync(8)</a>:
+ Description of corosync daemon.
+ <br>
+
+ <a href="corosync-blackbox.8.html">corosync-blackbox(8)</a>:
+ Description of corosync-blackbox tool.
+ <br>
+
+ <a href="corosync-cfgtool.8.html">corosync-cfgtool(8)</a>:
+ Description of corosync-cfgtool tool.
+ <br>
+
+ <a href="corosync-cpgtool.8.html">corosync-cpgtool(8)</a>:
+ Description of corosync-cpgtool tool.
+ <br>
+
+ <a href="corosync-keygen.8.html">corosync-keygen(8)</a>:
+ Description of corosync-keygen tool.
+ <br>
+
+ <a href="corosync-notifyd.8.html">corosync-notifyd(8)</a>:
+ Description of corosync-notifyd tool.
+ <br>
+
+ <a href="corosync-cmapctl.8.html">corosync-cmapctl(8)</a>:
+ Description of corosync-cmapctl tool.
+ <br>
+
+ <a href="cmap_keys.7.html">cmap_keys(7)</a>:
+ Overview of keys stored in the Configuration Map.
+ <br>
+
+ <a href="corosync-quorumtool.8.html">corosync-quorumtool(8)</a>:
+ Description of corosync-quorumtool tool.
+ <br>
+
+ <a href="corosync-xmlproc.8.html">corosync-xmlproc(8)</a>:
+ Description of corosync-xmlproc tool.
+ <br>
+ </p>
+
+ <p>
+ <h2>Developers API references</h2>
+
+ <h3>CPG service</h3>
+
+ <a href="cpg_overview.3.html">cpg_overview(3)</a>:
+ Overview of the cpg extended virtual synchrony group
+ communication toolkit.
+ <br>
+
+ <a href="cpg_initialize.3.html">cpg_initialize(3)</a>:
+ Description of the cpg_initialize interface.
+ <br>
+
+ <a href="cpg_finalize.3.html">cpg_finalize(3)</a>:
+ Description of the cpg_finalize interface.
+ <br>
+
+ <a href="cpg_dispatch.3.html">cpg_dispatch(3)</a>:
+ Description of the cpg_dispatch interface.
+ <br>
+
+ <a href="cpg_fd_get.3.html">cpg_fd_get(3)</a>:
+ Description of the cpg_fd_get interface.
+ <br>
+
+ <a href="cpg_join.3.html">cpg_join(3)</a>:
+ Description of the cpg_join interface.
+ <br>
+
+ <a href="cpg_leave.3.html">cpg_leave(3)</a>:
+ Description of the cpg_leave interface.
+ <br>
+
+ <a href="cpg_mcast_joined.3.html">cpg_mcast_joined(3)</a>:
+ Description of the cpg_mcast_joined interface.
+ <br>
+
+ <a href="cpg_membership_get.3.html">cpg_membership_get(3)</a>:
+ Description of the cpg_membership_get interface.
+ <br>
+
+ <a href="cpg_local_get.3.html">cpg_local_get(3)</a>:
+ Description of the cpg_local_get interface.
+ <br>
+
+ <a href="cpg_iteration_initialize.3.html">cpg_iteration_initialize(3)</a>:
+ Description of the cpg_iteration_initialize interface.
+ <br>
+
+ <a href="cpg_iteration_next.3.html">cpg_iteration_next(3)</a>:
+ Description of the cpg_iteration_next interface.
+ <br>
+
+ <a href="cpg_iteration_finalize.3.html">cpg_iteration_finalize(3)</a>:
+ Description of the cpg_iteration_finalize interface.
+ <br>
+
+ <a href="cpg_context_get.3.html">cpg_context_get(3)</a>:
+ Gets the context variable for a CPG instance.
+ <br>
+
+ <a href="cpg_context_set.3.html">cpg_context_set(3)</a>:
+ Sets the context variable for a CPG instance.
+ <br>
+
+ <a href="cpg_model_initialize.3.html">cpg_model_initialize(3)</a>:
+ Create a new connection to the CPG service
+ <br>
+
+ <a href="cpg_zcb_alloc.3.html">cpg_zcb_alloc(3)</a>:
+ Allocates a zero copy buffer.
+ <br>
+
+ <a href="cpg_zcb_free.3.html">cpg_zcb_free(3)</a>:
+ Frees a zero copy buffer.
+ <br>
+
+ <a href="cpg_zcb_mcast_joined.3.html">cpg_zcb_mcast_joined(3)</a>:
+ Multicasts a zero copy buffer to all groups joined to a handle.
+ <br>
+
+ <h3>SAM service</h3>
+
+ <a href="sam_overview.3.html">sam_overview(3)</a>:
+ Description of sam_overview interface.
+ <br>
+
+ <a href="sam_data_getsize.3.html">sam_data_getsize(3)</a>:
+ Description of sam_data_getsize interface.
+ <br>
+
+ <a href="sam_data_restore.3.html">sam_data_restore(3)</a>:
+ Description of sam_data_restore interface.
+ <br>
+
+ <a href="sam_data_store.3.html">sam_data_store(3)</a>:
+ Description of sam_data_store interface.
+ <br>
+
+ <a href="sam_finalize.3.html">sam_finalize(3)</a>:
+ Description of sam_finalize interface.
+ <br>
+
+ <a href="sam_hc_callback_register.3.html">sam_hc_callback_register(3)</a>:
+ Description of sam_hc_callback_register interface.
+ <br>
+
+ <a href="sam_hc_send.3.html">sam_hc_send(3)</a>:
+ Description of sam_hc_send interface.
+ <br>
+
+ <a href="sam_initialize.3.html">sam_initialize(3)</a>:
+ Description of sam_initialize interface.
+ <br>
+
+ <a href="sam_mark_failed.3.html">sam_mark_failed(3)</a>:
+ Description of sam_mark_failed interface.
+ <br>
+
+ <a href="sam_register.3.html">sam_register(3)</a>:
+ Description of sam_register interface.
+ <br>
+
+ <a href="sam_start.3.html">sam_start(3)</a>:
+ Description of sam_start interface.
+ <br>
+
+ <a href="sam_stop.3.html">sam_stop(3)</a>:
+ Description of sam_stop interface.
+ <br>
+
+ <a href="sam_warn_signal_set.3.html">sam_warn_signal_set(3)</a>:
+ Description of sam_warn_signal_set interface.
+ <br>
+
+ <h3>QUORUM service</h3>
+
+ <a href="quorum_overview.3.html">quorum_overview(3)</a>:
+ An overview of the quorum service
+ <br>
+
+ <a href="quorum_initialize.3.html">quorum_initialize(3)</a>:
+ Description of quorum_initialize interface.
+ <br>
+
+ <a href="quorum_finalize.3.html">quorum_finalize(3)</a>:
+ Description of quorum_finalize interface.
+ <br>
+
+ <a href="quorum_getquorate.3.html">quorum_getquorate(3)</a>:
+ Description of quorum_getquorate interface.
+ <br>
+
+ <a href="quorum_trackstart.3.html">quorum_trackstart(3)</a>:
+ Description of quorum_trackstart interface.
+ <br>
+
+ <a href="quorum_trackstop.3.html">quorum_trackstop(3)</a>:
+ Description of quorum_trackstop interface.
+ <br>
+
+ <a href="quorum_fd_get.3.html">quorum_fd_get(3)</a>:
+ Description of quorum_fd_get interface.
+ <br>
+
+ <a href="quorum_dispatch.3.html">quorum_dispatch(3)</a>:
+ Description of quorum_dispatch interface.
+ <br>
+
+ <a href="quorum_context_set.3.html">quorum_context_set(3)</a>:
+ Description of quorum_context_set interface.
+ <br>
+
+ <a href="quorum_context_get.3.html">quorum_context_get(3)</a>:
+ Description of quorum_context_get interface.
+ <br>
+
+ <h3>VOTEQUORUM service</h3>
+
+ <a href="votequorum_overview.3.html">votequorum_overview(3)</a>:
+ An overview of the vote-based quorum service
+ <br>
+
+ <a href="votequorum_initialize.3.html">votequorum_initialize(3)</a>:
+ Description of the votequorum_initialize interface.
+ <br>
+
+ <a href="votequorum_finalize.3.html">votequorum_finalize(3)</a>:
+ Description of the votequorum_finalize interface.
+ <br>
+
+ <a href="votequorum_getinfo.3.html">votequorum_getinfo(3)</a>:
+ Description of the votequorum_getinfo interface.
+ <br>
+
+ <a href="votequorum_trackstart.3.html">votequorum_trackstart(3)</a>:
+ Description of the votequorum_trackstart interface.
+ <br>
+
+ <a href="votequorum_trackstop.3.html">votequorum_trackstop(3)</a>:
+ Description of the votequorum_trackstop interface.
+ <br>
+
+ <a href="votequorum_fd_get.3.html">votequorum_fd_get(3)</a>:
+ Description of the votequorum_fd_get interface.
+ <br>
+
+ <a href="votequorum_dispatch.3.html">votequorum_dispatch(3)</a>:
+ Description of the votequorum_dispatch interface.
+ <br>
+
+ <a href="votequorum_context_set.3.html">votequorum_context_set(3)</a>:
+ Description of the votequorum_context_set interface.
+ <br>
+
+ <a href="votequorum_context_get.3.html">votequorum_context_get(3)</a>:
+ Description of the votequorum_context_get interface.
+ <br>
+
+ <a href="votequorum_setexpected.3.html">votequorum_setexpected(3)</a>:
+ Description of the votequorum interface.
+ <br>
+
+ <a href="votequorum_setvotes.3.html">votequorum_setvotes(3)</a>:
+ Description of the votequorum interface.
+ <br>
+
+ <a href="votequorum_qdevice_master_wins.3.html">votequorum_qdevice_master_wins(3)</a>:
+ Sets or clears quorum device master_wins flag.
+ <br>
+
+ <a href="votequorum_qdevice_poll.3.html">votequorum_qdevice_poll(3)</a>:
+ Tells votequorum the result of the quorum device poll.
+ <br>
+
+ <a href="votequorum_qdevice_register.3.html">votequorum_qdevice_register(3)</a>:
+ Registers a new quorum device.
+ <br>
+
+ <a href="votequorum_qdevice_unregister.3.html">votequorum_qdevice_unregister(3)</a>:
+ Unregisters a new quorum device.
+ <br>
+
+ <a href="votequorum_qdevice_update.3.html">votequorum_qdevice_update(3)</a>:
+ Updates quorum device name.
+ <br>
+
+ <h3>CMAP service</h3>
+
+ <a href="cmap_overview.3.html">cmap_overview(3)</a>:
+ An overview of the configuration map service.
+ <br>
+
+ <a href="cmap_context_get.3.html">cmap_context_get(3)</a>:
+ Description of the cmap_context_get interface.
+ <br>
+
+ <a href="cmap_context_set.3.html">cmap_context_set(3)</a>:
+ Description of the cmap_context_set interface.
+ <br>
+
+ <a href="cmap_dec.3.html">cmap_dec(3)</a>:
+ Description of the cmap_dec interface.
+ <br>
+
+ <a href="cmap_delete.3.html">cmap_delete(3)</a>:
+ Description of the cmap_delete interface.
+ <br>
+
+ <a href="cmap_dispatch.3.html">cmap_dispatch(3)</a>:
+ Description of the cmap_dispatch interface.
+ <br>
+
+ <a href="cmap_fd_get.3.html">cmap_fd_get(3)</a>:
+ Description of the cmap_fd_get interface.
+ <br>
+
+ <a href="cmap_finalize.3.html">cmap_finalize(3)</a>:
+ Description of the cmap_finalize interface.
+ <br>
+
+ <a href="cmap_get.3.html">cmap_get(3)</a>:
+ Description of the cmap_get interface.
+ <br>
+
+ <a href="cmap_inc.3.html">cmap_inc(3)</a>:
+ Description of the cmap_inc interface.
+ <br>
+
+ <a href="cmap_initialize.3.html">cmap_initialize(3)</a>:
+ Description of the cmap_initialize interface.
+ <br>
+
+ <a href="cmap_iter_finalize.3.html">cmap_iter_finalize(3)</a>:
+ Description of the cmap_iter_finalize interface.
+ <br>
+
+ <a href="cmap_iter_init.3.html">cmap_iter_init(3)</a>:
+ Description of the cmap_iter_init interface.
+ <br>
+
+ <a href="cmap_iter_next.3.html">cmap_iter_next(3)</a>:
+ Description of the cmap_iter_next interface.
+ <br>
+
+ <a href="cmap_set.3.html">cmap_set(3)</a>:
+ Description of the cmap_set interface.
+ <br>
+
+ <a href="cmap_track_add.3.html">cmap_track_add(3)</a>:
+ Description of the cmap_track_add interface.
+ <br>
+
+ <a href="cmap_track_delete.3.html">cmap_track_delete(3)</a>:
+ Description of the cmap_track_delete interface.
+ <br>
+
+ </p>
+
+ </body>
+</html>
diff --git a/man/ipc_common.sh.errors b/man/ipc_common.sh.errors
new file mode 100644
index 0000000..55d4510
--- /dev/null
+++ b/man/ipc_common.sh.errors
@@ -0,0 +1,25 @@
+.PP
+
+.B CS_ERR_TRY_AGAIN
+Resource temporarily unavailable
+
+.B CS_ERR_INVALID_PARAM
+Invalid argument
+
+.B CS_ERR_ACCESS
+Permission denied
+
+.B CS_ERR_LIBRARY
+The connection failed
+
+.B CS_ERR_INTERRUPT
+System call interrupted by a signal
+
+.B CS_ERR_NOT_SUPPORTED
+The requested protocol/functionality not supported
+
+.B CS_ERR_MESSAGE_ERROR
+Incorrect auth message received
+
+.B CS_ERR_NO_MEMORY
+Not enough memory to complete the requested task
diff --git a/man/quorum_context_get.3.in b/man/quorum_context_get.3.in
new file mode 100644
index 0000000..e4c5cf1
--- /dev/null
+++ b/man/quorum_context_get.3.in
@@ -0,0 +1,62 @@
+.\"/*
+.\" * Copyright (c) 2012-2020 Red Hat, Inc.
+.\" *
+.\" * All rights reserved.
+.\" *
+.\" * Author: Fabio M. Di Nitto <fdinitto@redhat.com>
+.\" *
+.\" * This software licensed under BSD license, the text of which follows:
+.\" *
+.\" * Redistribution and use in source and binary forms, with or without
+.\" * modification, are permitted provided that the following conditions are met:
+.\" *
+.\" * - Redistributions of source code must retain the above copyright notice,
+.\" * this list of conditions and the following disclaimer.
+.\" * - Redistributions in binary form must reproduce the above copyright notice,
+.\" * this list of conditions and the following disclaimer in the documentation
+.\" * and/or other materials provided with the distribution.
+.\" * - Neither the name of the MontaVista Software, Inc. nor the names of its
+.\" * contributors may be used to endorse or promote products derived from this
+.\" * software without specific prior written permission.
+.\" *
+.\" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+.\" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+.\" * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+.\" * THE POSSIBILITY OF SUCH DAMAGE.
+.\" */
+.TH QUORUM_CONTEXT_GET 3 @BUILDDATE@ "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
+.SH NAME
+quorum_context_get \- Gets the context variable for a QUORUM instance
+.SH SYNOPSIS
+.B #include <corosync/quorum.h>
+.sp
+.BI "int quorum_context_get(quorum_handle_t " handle ", void **" context ");"
+.SH DESCRIPTION
+The
+.B quorum_context_get
+function is used to retrieve the context variable previously stored using
+.B quorum_context_set(3)
+.SH RETURN VALUE
+This call returns the CS_OK value if successful, otherwise an error is returned.
+.PP
+.SH ERRORS
+@COMMONIPCERRORS@
+.SH "SEE ALSO"
+.BR quorum_overview (3),
+.BR quorum_initialize (3),
+.BR quorum_model_initialize (3),
+.BR quorum_finalize (3),
+.BR quorum_getquorate (3),
+.BR quorum_trackstart (3),
+.BR quorum_trackstop (3),
+.BR quorum_fd_get (3),
+.BR quorum_dispatch (3),
+.BR quorum_context_set (3),
+.PP
diff --git a/man/quorum_context_set.3.in b/man/quorum_context_set.3.in
new file mode 100644
index 0000000..cdc1b3b
--- /dev/null
+++ b/man/quorum_context_set.3.in
@@ -0,0 +1,64 @@
+.\"/*
+.\" * Copyright (c) 2012-2020 Red Hat, Inc.
+.\" *
+.\" * All rights reserved.
+.\" *
+.\" * Author: Fabio M. Di Nitto <fdinitto@redhat.com>
+.\" *
+.\" * This software licensed under BSD license, the text of which follows:
+.\" *
+.\" * Redistribution and use in source and binary forms, with or without
+.\" * modification, are permitted provided that the following conditions are met:
+.\" *
+.\" * - Redistributions of source code must retain the above copyright notice,
+.\" * this list of conditions and the following disclaimer.
+.\" * - Redistributions in binary form must reproduce the above copyright notice,
+.\" * this list of conditions and the following disclaimer in the documentation
+.\" * and/or other materials provided with the distribution.
+.\" * - Neither the name of the MontaVista Software, Inc. nor the names of its
+.\" * contributors may be used to endorse or promote products derived from this
+.\" * software without specific prior written permission.
+.\" *
+.\" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+.\" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+.\" * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+.\" * THE POSSIBILITY OF SUCH DAMAGE.
+.\" */
+.TH QUORUM_CONTEXT_SET 3 @BUILDDATE@ "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
+.SH NAME
+quorum_context_set \- Sets the context variable for a QUORUM instance
+.SH SYNOPSIS
+.B #include <corosync/quorum.h>
+.sp
+.BI "int quorum_context_set(quorum_handle_t " handle ", void *" context ");"
+.SH DESCRIPTION
+The
+.B quorum_context_set
+function is used to set the context variable for a quorum instance. It has no
+meaning inside libquorum itself and will not be touched by the library. It can
+be retrieved using
+.B quorum_context_get(3)
+.SH RETURN VALUE
+This call returns the CS_OK value if successful, otherwise an error is returned.
+.PP
+.SH ERRORS
+@COMMONIPCERRORS@
+.SH "SEE ALSO"
+.BR quorum_overview (3),
+.BR quorum_initialize (3),
+.BR quorum_model_initialize (3),
+.BR quorum_finalize (3),
+.BR quorum_getquorate (3),
+.BR quorum_trackstart (3),
+.BR quorum_trackstop (3),
+.BR quorum_fd_get (3),
+.BR quorum_dispatch (3),
+.BR quorum_context_get (3)
+.PP
diff --git a/man/quorum_dispatch.3.in b/man/quorum_dispatch.3.in
new file mode 100644
index 0000000..c8b822a
--- /dev/null
+++ b/man/quorum_dispatch.3.in
@@ -0,0 +1,98 @@
+.\"/*
+.\" * Copyright (c) 2012-2020 Red Hat, Inc.
+.\" *
+.\" * All rights reserved.
+.\" *
+.\" * Author: Fabio M. Di Nitto <fdinitto@redhat.com>
+.\" *
+.\" * This software licensed under BSD license, the text of which follows:
+.\" *
+.\" * Redistribution and use in source and binary forms, with or without
+.\" * modification, are permitted provided that the following conditions are met:
+.\" *
+.\" * - Redistributions of source code must retain the above copyright notice,
+.\" * this list of conditions and the following disclaimer.
+.\" * - Redistributions in binary form must reproduce the above copyright notice,
+.\" * this list of conditions and the following disclaimer in the documentation
+.\" * and/or other materials provided with the distribution.
+.\" * - Neither the name of the MontaVista Software, Inc. nor the names of its
+.\" * contributors may be used to endorse or promote products derived from this
+.\" * software without specific prior written permission.
+.\" *
+.\" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+.\" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+.\" * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+.\" * THE POSSIBILITY OF SUCH DAMAGE.
+.\" */
+.TH QUORUM_DISPATCH 3 @BUILDDATE@ "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
+.SH NAME
+quorum_dispatch \- Dispatches callbacks from the quorum service
+.SH SYNOPSIS
+.B #include <corosync/quorum.h>
+.sp
+.BI "int quorum_dispatch(quorum_handle_t " handle ", cs_dispatch_flags_t *" dispatch_types ");"
+.SH DESCRIPTION
+The
+.B quorum_dispatch
+function is used to dispatch configuration changes.
+.PP
+Each application may have several connections to the quorum API. Each application
+uses the
+.I handle
+argument to uniquely identify the connection.
+.PP
+The
+.I dispatch_types
+argument is used to identify the type of dispatch to execute. The possible types are
+defined by the structure:
+
+.nf
+typedef enum {
+ CS_DISPATCH_ONE = 1,
+ CS_DISPATCH_ALL = 2,
+ CS_DISPATCH_BLOCKING = 3,
+ CS_DISPATCH_ONE_NONBLOCKING = 4
+} cs_dispatch_flags_t;
+.fi
+.PP
+The dispatch values have the following meanings:
+.TP
+.B CS_DISPATCH_ONE
+Dispatch at least one callback, blocking until the callback is dispatched.
+.TP
+.B CS_DISPATCH_ALL
+Dispatch all waiting callbacks without blocking to wait for any callbacks.
+.TP
+.B CS_DISPATCH_BLOCKING
+Dispatch all callbacks blocking indefinitely. This is used in a threaded
+program where a thread is created, and then quorum_dispatch() is called immediately
+from the created thread to execute callbacks.
+.TP
+.B CS_DISPATCH_ONE_NONBLOCKING
+Dispatch at most one callback. If there is no pending callback,
+CS_ERR_TRY_AGAIN is returned.
+
+.SH RETURN VALUE
+This call returns the CS_OK value if successful, otherwise an error is returned.
+.PP
+.SH ERRORS
+@COMMONIPCERRORS@
+.SH "SEE ALSO"
+.BR quorum_overview (3),
+.BR quorum_initialize (3),
+.BR quorum_model_initialize (3),
+.BR quorum_finalize (3),
+.BR quorum_getquorate (3),
+.BR quorum_trackstart (3),
+.BR quorum_trackstop (3),
+.BR quorum_fd_get (3),
+.BR quorum_context_set (3),
+.BR quorum_context_get (3)
+.PP
diff --git a/man/quorum_fd_get.3.in b/man/quorum_fd_get.3.in
new file mode 100644
index 0000000..1f99399
--- /dev/null
+++ b/man/quorum_fd_get.3.in
@@ -0,0 +1,69 @@
+.\"/*
+.\" * Copyright (c) 2012-2020 Red Hat, Inc.
+.\" *
+.\" * All rights reserved.
+.\" *
+.\" * Author: Fabio M. Di Nitto <fdinitto@redhat.com>
+.\" *
+.\" * This software licensed under BSD license, the text of which follows:
+.\" *
+.\" * Redistribution and use in source and binary forms, with or without
+.\" * modification, are permitted provided that the following conditions are met:
+.\" *
+.\" * - Redistributions of source code must retain the above copyright notice,
+.\" * this list of conditions and the following disclaimer.
+.\" * - Redistributions in binary form must reproduce the above copyright notice,
+.\" * this list of conditions and the following disclaimer in the documentation
+.\" * and/or other materials provided with the distribution.
+.\" * - Neither the name of the MontaVista Software, Inc. nor the names of its
+.\" * contributors may be used to endorse or promote products derived from this
+.\" * software without specific prior written permission.
+.\" *
+.\" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+.\" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+.\" * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+.\" * THE POSSIBILITY OF SUCH DAMAGE.
+.\" */
+.TH QUORUM_FD_GET 3 @BUILDDATE@ "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
+.SH NAME
+quorum_fd_get \- Dispatches callbacks from the quorum service
+.SH SYNOPSIS
+.B #include <corosync/quorum.h>
+.sp
+.BI "int quorum_fd_get(quorum_handle_t " handle ", int *" fd ");"
+.SH DESCRIPTION
+The
+.B quorum_fd_get
+function is used to retrieve the file descriptor that may be used with the poll
+system call to determine when
+.B quorum_dispatch(3)
+won't block. The
+.I handle
+argument may not be used directly with
+.B poll
+because it is not the file descriptor, but instead an internal identifier used
+by the quorum library.
+.SH RETURN VALUE
+This call returns the CS_OK value if successful, otherwise an error is returned.
+.PP
+.SH ERRORS
+@COMMONIPCERRORS@
+.SH "SEE ALSO"
+.BR quorum_overview (3),
+.BR quorum_initialize (3),
+.BR quorum_model_initialize (3),
+.BR quorum_finalize (3),
+.BR quorum_getquorate (3),
+.BR quorum_trackstart (3),
+.BR quorum_trackstop (3),
+.BR quorum_dispatch (3),
+.BR quorum_context_set (3),
+.BR quorum_context_get (3)
+.PP
diff --git a/man/quorum_finalize.3.in b/man/quorum_finalize.3.in
new file mode 100644
index 0000000..d914b30
--- /dev/null
+++ b/man/quorum_finalize.3.in
@@ -0,0 +1,66 @@
+.\"/*
+.\" * Copyright (c) 2012-2020 Red Hat, Inc.
+.\" *
+.\" * All rights reserved.
+.\" *
+.\" * Author: Fabio M. Di Nitto <fdinitto@redhat.com>
+.\" *
+.\" * This software licensed under BSD license, the text of which follows:
+.\" *
+.\" * Redistribution and use in source and binary forms, with or without
+.\" * modification, are permitted provided that the following conditions are met:
+.\" *
+.\" * - Redistributions of source code must retain the above copyright notice,
+.\" * this list of conditions and the following disclaimer.
+.\" * - Redistributions in binary form must reproduce the above copyright notice,
+.\" * this list of conditions and the following disclaimer in the documentation
+.\" * and/or other materials provided with the distribution.
+.\" * - Neither the name of the MontaVista Software, Inc. nor the names of its
+.\" * contributors may be used to endorse or promote products derived from this
+.\" * software without specific prior written permission.
+.\" *
+.\" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+.\" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+.\" * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+.\" * THE POSSIBILITY OF SUCH DAMAGE.
+.\" */
+.TH QUORUM_FINALIZE 3 @BUILDDATE@ "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
+.SH NAME
+quorum_finalize \- Terminate a connection to the quorum service
+.SH SYNOPSIS
+.B #include <corosync/quorum.h>
+.sp
+.BI "int quorum_finalize(quorum_handle_t " handle ");"
+.SH DESCRIPTION
+The
+.B quorum_finalize
+function is used to close a connection to the quorum API.
+Once the connection is finalized, the handle may not be used again by applications.
+No more callbacks will be dispatched from the
+.B quorum_dispatch
+function.
+.PP
+.SH RETURN VALUE
+This call returns the CS_OK value if successful, otherwise an error is returned.
+.PP
+.SH ERRORS
+@COMMONIPCERRORS@
+.SH "SEE ALSO"
+.BR quorum_overview (3),
+.BR quorum_initialize (3),
+.BR quorum_model_initialize (3),
+.BR quorum_getquorate (3),
+.BR quorum_trackstart (3),
+.BR quorum_trackstop (3),
+.BR quorum_fd_get (3),
+.BR quorum_dispatch (3),
+.BR quorum_context_set (3),
+.BR quorum_context_get (3)
+.PP
diff --git a/man/quorum_getquorate.3.in b/man/quorum_getquorate.3.in
new file mode 100644
index 0000000..281efdc
--- /dev/null
+++ b/man/quorum_getquorate.3.in
@@ -0,0 +1,62 @@
+.\"/*
+.\" * Copyright (c) 2012-2020 Red Hat, Inc.
+.\" *
+.\" * All rights reserved.
+.\" *
+.\" * Author: Fabio M. Di Nitto <fdinitto@redhat.com>
+.\" *
+.\" * This software licensed under BSD license, the text of which follows:
+.\" *
+.\" * Redistribution and use in source and binary forms, with or without
+.\" * modification, are permitted provided that the following conditions are met:
+.\" *
+.\" * - Redistributions of source code must retain the above copyright notice,
+.\" * this list of conditions and the following disclaimer.
+.\" * - Redistributions in binary form must reproduce the above copyright notice,
+.\" * this list of conditions and the following disclaimer in the documentation
+.\" * and/or other materials provided with the distribution.
+.\" * - Neither the name of the MontaVista Software, Inc. nor the names of its
+.\" * contributors may be used to endorse or promote products derived from this
+.\" * software without specific prior written permission.
+.\" *
+.\" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+.\" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+.\" * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+.\" * THE POSSIBILITY OF SUCH DAMAGE.
+.\" */
+.TH QUORUM_GETQUORATE 3 @BUILDDATE@ "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
+.SH NAME
+quorum_getquorate \- Gets the quorate status of the node.
+.SH SYNOPSIS
+.B #include <corosync/quorum.h>
+.sp
+.BI "int quorum_getquorate(quorum_handle_t " handle ", int *" quorate ");"
+.SH DESCRIPTION
+The
+.B quorum_getquorate
+function is used to retrieve the quorate status of the node. Quorate is 0 if the node
+is not part of a quorate partition or 1 otherwise.
+.SH RETURN VALUE
+This call returns the CS_OK value if successful, otherwise an error is returned.
+.PP
+.SH ERRORS
+@COMMONIPCERRORS@
+.SH "SEE ALSO"
+.BR quorum_overview (3),
+.BR quorum_initialize (3),
+.BR quorum_model_initialize (3),
+.BR quorum_finalize (3),
+.BR quorum_trackstart (3),
+.BR quorum_trackstop (3),
+.BR quorum_fd_get (3),
+.BR quorum_dispatch (3),
+.BR quorum_context_set (3),
+.BR quorum_context_get (3)
+.PP
diff --git a/man/quorum_initialize.3.in b/man/quorum_initialize.3.in
new file mode 100644
index 0000000..91eb815
--- /dev/null
+++ b/man/quorum_initialize.3.in
@@ -0,0 +1,114 @@
+.\"/*
+.\" * Copyright (c) 2012-2020 Red Hat, Inc.
+.\" *
+.\" * All rights reserved.
+.\" *
+.\" * Author: Fabio M. Di Nitto <fdinitto@redhat.com>
+.\" *
+.\" * This software licensed under BSD license, the text of which follows:
+.\" *
+.\" * Redistribution and use in source and binary forms, with or without
+.\" * modification, are permitted provided that the following conditions are met:
+.\" *
+.\" * - Redistributions of source code must retain the above copyright notice,
+.\" * this list of conditions and the following disclaimer.
+.\" * - Redistributions in binary form must reproduce the above copyright notice,
+.\" * this list of conditions and the following disclaimer in the documentation
+.\" * and/or other materials provided with the distribution.
+.\" * - Neither the name of the MontaVista Software, Inc. nor the names of its
+.\" * contributors may be used to endorse or promote products derived from this
+.\" * software without specific prior written permission.
+.\" *
+.\" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+.\" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+.\" * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+.\" * THE POSSIBILITY OF SUCH DAMAGE.
+.\" */
+.TH QUORUM_INITIALIZE 3 @BUILDDATE@ "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
+.SH NAME
+quorum_initialize \- Create a new connection to the Quorum service
+.SH SYNOPSIS
+.B #include <corosync/quorum.h>
+.sp
+.BI "int quorum_initialize(quorum_handle_t *" handle ", quorum_callbacks_t *" callbacks ", uint32_t *" quorum_type ");"
+.SH DESCRIPTION
+The
+.B quorum_initialize
+function is used to initialize a connection to the quorum API.
+.PP
+Each application may have several connections to the quorum API. Each application
+uses the
+.I handle
+argument to uniquely identify the connection. The
+.I handle
+argument is then used in other function calls to identify the connection to be used
+for communication with the quorum service.
+.PP
+Every time the voting configuration changes (eg a node joins or leave the cluster) or the quorum status change,
+the callback is called.
+The callback function is described by the following type definitions:
+
+.nf
+typedef void (*quorum_notification_fn_t) (
+ quorum_handle_t handle,
+ uint32_t quorate,
+ uint64_t ring_seq,
+ uint32_t view_list_entries,
+ uint32_t *view_list
+ );
+.fi
+.PP
+The
+.I callbacks
+argument is of the type:
+
+.nf
+typedef struct {
+ quorum_notification_fn_t quorum_notify_fn;
+} quorum_callbacks_t;
+.fi
+.PP
+The
+.I quorum_type
+argument is set to:
+
+.nf
+#define QUORUM_FREE 0
+#define QUORUM_SET 1
+.fi
+.PP
+.I QUORUM_FREE
+value means that no quorum algorithm is loaded and that no callbacks will take place.
+.PP
+.I QUORUM_SET
+value means that one quorum algorithm is configured and that callbacks will take place.
+.PP
+When a configuration change occurs, the callback
+is called from the
+.B quorum_dispatch()
+function.
+.PP
+.SH RETURN VALUE
+This call returns the CS_OK value if successful, otherwise an error is returned.
+.PP
+.SH ERRORS
+@COMMONIPCERRORS@
+.SH "SEE ALSO"
+.BR quorum_overview (3),
+.BR quorum_model_initialize (3),
+.BR quorum_finalize (3),
+.BR quorum_getquorate (3),
+.BR quorum_trackstart (3),
+.BR quorum_trackstop (3),
+.BR quorum_fd_get (3),
+.BR quorum_dispatch (3),
+.BR quorum_context_set (3),
+.BR quorum_context_get (3)
+.PP
diff --git a/man/quorum_model_initialize.3.in b/man/quorum_model_initialize.3.in
new file mode 100644
index 0000000..0ac6c26
--- /dev/null
+++ b/man/quorum_model_initialize.3.in
@@ -0,0 +1,165 @@
+.\"/*
+.\" * Copyright (c) 2012-2020 Red Hat, Inc.
+.\" *
+.\" * All rights reserved.
+.\" *
+.\" * Authors: Jan Friesse <jfriesse@redhat.com>
+.\" * Fabio M. Di Nitto <fdinitto@redhat.com>
+.\" *
+.\" * This software licensed under BSD license, the text of which follows:
+.\" *
+.\" * Redistribution and use in source and binary forms, with or without
+.\" * modification, are permitted provided that the following conditions are met:
+.\" *
+.\" * - Redistributions of source code must retain the above copyright notice,
+.\" * this list of conditions and the following disclaimer.
+.\" * - Redistributions in binary form must reproduce the above copyright notice,
+.\" * this list of conditions and the following disclaimer in the documentation
+.\" * and/or other materials provided with the distribution.
+.\" * - Neither the name of the MontaVista Software, Inc. nor the names of its
+.\" * contributors may be used to endorse or promote products derived from this
+.\" * software without specific prior written permission.
+.\" *
+.\" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+.\" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+.\" * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+.\" * THE POSSIBILITY OF SUCH DAMAGE.
+.\" */
+.TH QUORUM_MODEL_INITIALIZE 3 @BUILDDATE@ "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
+.SH NAME
+quorum_model_initialize \- Create a new connection to the Quorum service
+.SH SYNOPSIS
+.B #include <corosync/quorum.h>
+.sp
+.BI "cs_error_t quorum_model_initialize(quorum_handle_t *" handle ", quorum_model_t " model ", quorum_model_data_t *" model_data ", uint32_t *" quorum_type ",void *" context ");"
+.SH DESCRIPTION
+The
+.B quorum_model_initialize
+function is an enhanced way to initialize a connection to the quorum API.
+.PP
+Each application may have several connections to the quorum API. Each application
+uses the
+.I handle
+argument to uniquely identify the connection. The
+.I handle
+argument is then used in other function calls to identify the connection to be used
+for communication with the quorum service.
+.PP
+The
+.I model
+is used to explicitly choose set of callbacks and internal parameters. Currently two models
+.I QUORUM_MODEL_V0
+and
+.I QUORUM_MODEL_V1
+are defined.
+.I QUORUM_MODEL_V0
+exists only for compatibility reasons with
+.B quorum_initialize(3)
+function and it is not recommended to be used as an argument for
+.B quorum_model_initialize(3).
+
+The Following description is focused only on
+.I QUORUM_MODEL_V1
+model.
+
+.PP
+Every time the voting configuration changes (eg a node joins or leave the cluster) or the quorum status changes
+the quorum callback is called.
+The quorum callback function is described by the following type definitions:
+
+.nf
+typedef void (*quorum_v1_quorum_notification_fn_t) (
+ quorum_handle_t handle,
+ uint32_t quorate,
+ struct quorum_ring_id ring_id,
+ uint32_t member_list_entries,
+ const uint32_t *member_list
+);
+.fi
+.PP
+Also every time when membership configuration changes (eg a node joins or leave the cluster) the node list change
+callback is called before the quorum callback.
+The node list change callback function is described by the following type definitions:
+
+.nf
+typedef void (*quorum_v1_nodelist_notification_fn_t) (
+ quorum_handle_t handle,
+ struct quorum_ring_id ring_id,
+ uint32_t member_list_entries,
+ const uint32_t *member_list,
+ uint32_t joined_list_entries,
+ const uint32_t *joined_list,
+ uint32_t left_list_entries,
+ const uint32_t *left_list
+);
+.fi
+.PP
+The
+.I model_data
+argument for
+.I QUORUM_MODEL_V1
+is of the type:
+
+.nf
+typedef struct {
+ quorum_model_t model;
+ quorum_v1_quorum_notification_fn_t quorum_notify_fn;
+ quorum_v1_nodelist_notification_fn_t nodelist_notify_fn;
+} quorum_model_v1_data_t;
+.fi
+
+It's not required (nor recommended) to set
+.I model
+field in the structure. It is also fine if only some of notification callbacks are
+used (only these events will be delivered then).
+
+.PP
+The
+.I quorum_type
+argument is set to:
+
+.nf
+#define QUORUM_FREE 0
+#define QUORUM_SET 1
+.fi
+.PP
+.I QUORUM_FREE
+value means that no quorum algorithm is loaded and that no callbacks will take place.
+.PP
+.I QUORUM_SET
+value means that one quorum algorithm is configured and that callbacks will take place.
+.PP
+The
+.I context
+argument sets context same way as
+.B quorum_context_set(3).
+.PP
+When a configuration change occurs, the callback
+is called from the
+.B quorum_dispatch(3)
+function.
+.PP
+.SH RETURN VALUE
+This call returns the CS_OK value if successful, otherwise an error is returned.
+.PP
+.SH ERRORS
+@COMMONIPCERRORS@
+.SH "SEE ALSO"
+.BR quorum_overview (3),
+.BR quorum_initialize (3),
+.BR quorum_finalize (3),
+.BR quorum_getquorate (3),
+.BR quorum_trackstart (3),
+.BR quorum_trackstop (3),
+.BR quorum_fd_get (3),
+.BR quorum_dispatch (3),
+.BR quorum_context_set (3),
+.BR quorum_context_get (3)
+.PP
diff --git a/man/quorum_overview.3 b/man/quorum_overview.3
new file mode 100644
index 0000000..8c42b1a
--- /dev/null
+++ b/man/quorum_overview.3
@@ -0,0 +1,67 @@
+.\"/*
+.\" * Copyright (c) 2008-2020 Red Hat, Inc.
+.\" *
+.\" * All rights reserved.
+.\" *
+.\" * Authors: Christine Caulfield <ccaulfie@redhat.com>
+.\" * Fabio M. Di Nitto <fdinitto@redhat.com>
+.\" *
+.\" * This software licensed under BSD license, the text of which follows:
+.\" *
+.\" * Redistribution and use in source and binary forms, with or without
+.\" * modification, are permitted provided that the following conditions are met:
+.\" *
+.\" * - Redistributions of source code must retain the above copyright notice,
+.\" * this list of conditions and the following disclaimer.
+.\" * - Redistributions in binary form must reproduce the above copyright notice,
+.\" * this list of conditions and the following disclaimer in the documentation
+.\" * and/or other materials provided with the distribution.
+.\" * - Neither the name of the MontaVista Software, Inc. nor the names of its
+.\" * contributors may be used to endorse or promote products derived from this
+.\" * software without specific prior written permission.
+.\" *
+.\" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+.\" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+.\" * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+.\" * THE POSSIBILITY OF SUCH DAMAGE.
+.\" */
+.TH QUORUM_OVERVIEW 3 2020-02-14 "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
+.SH NAME
+quorum_overview \- Quorum Library Overview
+.SH OVERVIEW
+The quorum library is delivered with the corosync project. It is the external interface to
+the quorum service. This service is loaded into all nodes in a corosync cluster and track
+the quorum status of a node. In order for quorum service to be useful, a quorum provider
+must be configured.
+.PP
+The library provides a mechanism to:
+.PP
+* Query the quorum status
+.PP
+* Receive notifications of quorum state changes
+.PP
+* Receive notifications of membership changes
+.SH BUGS
+No known bugs at the time of writing. The authors are from outerspace. Deal with it.
+.SH "SEE ALSO"
+.BR corosync-quorumtool (8),
+.BR corosync.conf (5),
+.BR votequorum (5),
+.BR quorum_initialize (3),
+.BR quorum_model_initialize (3),
+.BR quorum_finalize (3),
+.BR quorum_getquorate (3),
+.BR quorum_trackstart (3),
+.BR quorum_trackstop (3),
+.BR quorum_fd_get (3),
+.BR quorum_dispatch (3),
+.BR quorum_context_set (3),
+.BR quorum_context_get (3)
+.PP
diff --git a/man/quorum_trackstart.3.in b/man/quorum_trackstart.3.in
new file mode 100644
index 0000000..2474b10
--- /dev/null
+++ b/man/quorum_trackstart.3.in
@@ -0,0 +1,78 @@
+.\"/*
+.\" * Copyright (c) 2012-2020 Red Hat, Inc.
+.\" *
+.\" * All rights reserved.
+.\" *
+.\" * Author: Fabio M. Di Nitto <fdinitto@redhat.com>
+.\" *
+.\" * This software licensed under BSD license, the text of which follows:
+.\" *
+.\" * Redistribution and use in source and binary forms, with or without
+.\" * modification, are permitted provided that the following conditions are met:
+.\" *
+.\" * - Redistributions of source code must retain the above copyright notice,
+.\" * this list of conditions and the following disclaimer.
+.\" * - Redistributions in binary form must reproduce the above copyright notice,
+.\" * this list of conditions and the following disclaimer in the documentation
+.\" * and/or other materials provided with the distribution.
+.\" * - Neither the name of the MontaVista Software, Inc. nor the names of its
+.\" * contributors may be used to endorse or promote products derived from this
+.\" * software without specific prior written permission.
+.\" *
+.\" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+.\" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+.\" * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+.\" * THE POSSIBILITY OF SUCH DAMAGE.
+.\" */
+.TH QUORUM_TRACKSTART 3 @BUILDDATE@ "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
+.SH NAME
+quorum_trackstart \- Enable callbacks notification.
+.SH SYNOPSIS
+.B #include <corosync/quorum.h>
+.sp
+.BI "int quorum_trackstart(quorum_handle_t *" handle ", unsigned int " flags ");"
+.SH DESCRIPTION
+The
+.B quorum_trackstart
+function is used to enable callbacks notification from the quorum API.
+.PP
+Every time the voting configuration changes (eg a node joins or leave the cluster)
+or the quorum status change, the notification is queued.
+.PP
+The notification is dispatched via
+.B quorum_dispatch()
+function that will execute the callback.
+.PP
+The
+.I flags
+argument is defined by one or more of the following values and values can be bitwise-or'd
+
+.nf
+#define CS_TRACK_CURRENT 0x01
+#define CS_TRACK_CHANGES 0x02
+#define CS_TRACK_CHANGES_ONLY 0x04
+.fi
+.SH RETURN VALUE
+This call returns the CS_OK value if successful, otherwise an error is returned.
+.PP
+.SH ERRORS
+@COMMONIPCERRORS@
+.SH "SEE ALSO"
+.BR quorum_overview (3),
+.BR quorum_initialize (3),
+.BR quorum_model_initialize (3),
+.BR quorum_finalize (3),
+.BR quorum_getquorate (3),
+.BR quorum_trackstop (3),
+.BR quorum_fd_get (3),
+.BR quorum_dispatch (3),
+.BR quorum_context_set (3),
+.BR quorum_context_get (3)
+.PP
diff --git a/man/quorum_trackstop.3.in b/man/quorum_trackstop.3.in
new file mode 100644
index 0000000..fc1f1ba
--- /dev/null
+++ b/man/quorum_trackstop.3.in
@@ -0,0 +1,62 @@
+.\"/*
+.\" * Copyright (c) 2012-2020 Red Hat, Inc.
+.\" *
+.\" * All rights reserved.
+.\" *
+.\" * Author: Fabio M. Di Nitto <fdinitto@redhat.com>
+.\" *
+.\" * This software licensed under BSD license, the text of which follows:
+.\" *
+.\" * Redistribution and use in source and binary forms, with or without
+.\" * modification, are permitted provided that the following conditions are met:
+.\" *
+.\" * - Redistributions of source code must retain the above copyright notice,
+.\" * this list of conditions and the following disclaimer.
+.\" * - Redistributions in binary form must reproduce the above copyright notice,
+.\" * this list of conditions and the following disclaimer in the documentation
+.\" * and/or other materials provided with the distribution.
+.\" * - Neither the name of the MontaVista Software, Inc. nor the names of its
+.\" * contributors may be used to endorse or promote products derived from this
+.\" * software without specific prior written permission.
+.\" *
+.\" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+.\" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+.\" * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+.\" * THE POSSIBILITY OF SUCH DAMAGE.
+.\" */
+.TH QUORUM_TRACKSTOP 3 @BUILDDATE@ "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
+.SH NAME
+quorum_trackstop \- Disable callbacks notification.
+.SH SYNOPSIS
+.B #include <corosync/quorum.h>
+.sp
+.BI "int quorum_trackstart(quorum_handle_t *" handle ");"
+.SH DESCRIPTION
+The
+.B quorum_trackstop
+function is used to disable callbacks notification from the quorum API.
+.PP
+.SH RETURN VALUE
+This call returns the CS_OK value if successful, otherwise an error is returned.
+.PP
+.SH ERRORS
+@COMMONIPCERRORS@
+.SH "SEE ALSO"
+.BR quorum_overview (3),
+.BR quorum_initialize (3),
+.BR quorum_model_initialize (3),
+.BR quorum_finalize (3),
+.BR quorum_getquorate (3),
+.BR quorum_trackstart (3),
+.BR quorum_fd_get (3),
+.BR quorum_dispatch (3),
+.BR quorum_context_set (3),
+.BR quorum_context_get (3)
+.PP
diff --git a/man/sam_data_getsize.3.in b/man/sam_data_getsize.3.in
new file mode 100644
index 0000000..33d527e
--- /dev/null
+++ b/man/sam_data_getsize.3.in
@@ -0,0 +1,68 @@
+.\"/*
+.\" * Copyright (c) 2010 Red Hat, Inc.
+.\" *
+.\" * All rights reserved.
+.\" *
+.\" * Author: Jan Friesse (jfriesse@redhat.com)
+.\" *
+.\" * This software licensed under BSD license, the text of which follows:
+.\" *
+.\" * Redistribution and use in source and binary forms, with or without
+.\" * modification, are permitted provided that the following conditions are met:
+.\" *
+.\" * - Redistributions of source code must retain the above copyright notice,
+.\" * this list of conditions and the following disclaimer.
+.\" * - Redistributions in binary form must reproduce the above copyright notice,
+.\" * this list of conditions and the following disclaimer in the documentation
+.\" * and/or other materials provided with the distribution.
+.\" * - Neither the name of the Red Hat, Inc. nor the names of its
+.\" * contributors may be used to endorse or promote products derived from this
+.\" * software without specific prior written permission.
+.\" *
+.\" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+.\" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+.\" * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+.\" * THE POSSIBILITY OF SUCH DAMAGE.
+.\" */
+.TH "SAM_DATA_GETSIZE" 3 "04/15/2010" "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
+
+.SH NAME
+.P
+sam_data_getsize \- Return size of stored data in bytes
+
+.SH SYNOPSIS
+.P
+\fB#include <corosync/sam.h>\fR
+
+.P
+\fBcs_error_t sam_data_getsize (size_t *\fIsize\fB);\fR
+
+.SH DESCRIPTION
+.P
+The \fBsam_data_getsize\fR function is used to return size of stored
+data. Size is returned in bytes. If user data is NULL, zero is returned.
+Function is intended to be used before \fBsam_data_restore(3)\fR call to
+properly allocate buffer for restored data.
+
+.SH RETURN VALUE
+.P
+This call return CS_OK value if successful, otherwise and error is returned.
+
+.SH ERRORS
+.TP
+CS_ERR_BAD_HANDLE
+component was not initialized by calling \fBsam_initialize(3)\fR or it was finalized.
+.TP
+CS_ERR_INVALID_PARAM
+size parameter is NULL
+
+.SH "SEE ALSO"
+.BR sam_data_store (3),
+.BR sam_data_restore (3)
diff --git a/man/sam_data_restore.3.in b/man/sam_data_restore.3.in
new file mode 100644
index 0000000..32b816a
--- /dev/null
+++ b/man/sam_data_restore.3.in
@@ -0,0 +1,77 @@
+.\"/*
+.\" * Copyright (c) 2010 Red Hat, Inc.
+.\" *
+.\" * All rights reserved.
+.\" *
+.\" * Author: Jan Friesse (jfriesse@redhat.com)
+.\" *
+.\" * This software licensed under BSD license, the text of which follows:
+.\" *
+.\" * Redistribution and use in source and binary forms, with or without
+.\" * modification, are permitted provided that the following conditions are met:
+.\" *
+.\" * - Redistributions of source code must retain the above copyright notice,
+.\" * this list of conditions and the following disclaimer.
+.\" * - Redistributions in binary form must reproduce the above copyright notice,
+.\" * this list of conditions and the following disclaimer in the documentation
+.\" * and/or other materials provided with the distribution.
+.\" * - Neither the name of the Red Hat, Inc. nor the names of its
+.\" * contributors may be used to endorse or promote products derived from this
+.\" * software without specific prior written permission.
+.\" *
+.\" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+.\" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+.\" * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+.\" * THE POSSIBILITY OF SUCH DAMAGE.
+.\" */
+.TH "SAM_DATA_RESTORE" 3 "04/15/2010" "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
+
+.SH NAME
+.P
+sam_data_restore \- Restore previously saved user data
+
+.SH SYNOPSIS
+.P
+\fB#include <corosync/sam.h>\fR
+
+.P
+\fBcs_error_t sam_data_restore (void *\fIdata\fB, size_t \fIsize\fB);\fR
+
+.SH DESCRIPTION
+.P
+The \fBsam_data_restore\fR function is used to restore data, previously
+saved by calling \fBsam_data_store(3)\fR. Such data survives between instances.
+
+.P
+The \fIdata\fR parameter is pointer to memory initialized by caller. Stored data
+are copied there. This also means, that caller is responsible for freeing memory.
+
+.P
+The \fIsize\fR parameter is length of \fIdata\fR. This one must be at least same
+length as previously stored data otherwise error is returned. Parameter can
+be larger but only stored data size bytes are changed.
+
+Use \fBsam_data_getsize(3)\fR to find out length of stored data.
+
+.SH RETURN VALUE
+.P
+This call return CS_OK value if successful, otherwise and error is returned.
+
+.SH ERRORS
+.TP
+CS_ERR_BAD_HANDLE
+component was not initialized by calling \fBsam_initialize(3)\fR or it was finalized.
+.TP
+CS_ERR_INVALID_PARAM
+data parameter is NULL or size is less then currently stored data length
+
+.SH "SEE ALSO"
+.BR sam_data_getsize (3),
+.BR sam_data_store (3)
diff --git a/man/sam_data_store.3.in b/man/sam_data_store.3.in
new file mode 100644
index 0000000..88ab7aa
--- /dev/null
+++ b/man/sam_data_store.3.in
@@ -0,0 +1,83 @@
+.\"/*
+.\" * Copyright (c) 2010 Red Hat, Inc.
+.\" *
+.\" * All rights reserved.
+.\" *
+.\" * Author: Jan Friesse (jfriesse@redhat.com)
+.\" *
+.\" * This software licensed under BSD license, the text of which follows:
+.\" *
+.\" * Redistribution and use in source and binary forms, with or without
+.\" * modification, are permitted provided that the following conditions are met:
+.\" *
+.\" * - Redistributions of source code must retain the above copyright notice,
+.\" * this list of conditions and the following disclaimer.
+.\" * - Redistributions in binary form must reproduce the above copyright notice,
+.\" * this list of conditions and the following disclaimer in the documentation
+.\" * and/or other materials provided with the distribution.
+.\" * - Neither the name of the Red Hat, Inc. nor the names of its
+.\" * contributors may be used to endorse or promote products derived from this
+.\" * software without specific prior written permission.
+.\" *
+.\" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+.\" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+.\" * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+.\" * THE POSSIBILITY OF SUCH DAMAGE.
+.\" */
+.TH "SAM_DATA_STORE" 3 "04/15/2010" "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
+
+.SH NAME
+.P
+sam_data_store \- Store user data
+
+.SH SYNOPSIS
+.P
+\fB#include <corosync/sam.h>\fR
+
+.P
+\fBcs_error_t sam_data_store (const void *\fIdata\fB, size_t \fIsize\fB);\fR
+
+.SH DESCRIPTION
+.P
+The \fBsam_data_store\fR function is used to store data, which survives between
+instances.
+
+.P
+The \fIdata\fR parameter is pointer to memory with data to store. Data
+are stored in newly allocated memory inside library, so caller can safely remove
+them after call of function.
+
+You can use NULL as parameter to remove and free previously saved data. In this
+case \fIsize\fR argument is ignored.
+
+.P
+The \fIsize\fR parameter is length of \fIdata\fR.
+
+Use \fBsam_data_getsize(3)\fR to find out length of stored data and \fBsam_data_restore(3)\fR
+to restore stored data.
+
+.SH RETURN VALUE
+.P
+This call return CS_OK value if successful, otherwise and error is returned.
+
+.SH ERRORS
+.TP
+CS_ERR_BAD_HANDLE
+component was not initialized by calling \fBsam_initialize(3)\fR or it was finalized.
+.TP
+CS_ERR_NO_MEMORY
+internal malloc/realloc failed because data are too large
+.TP
+CS_ERR_LIBRARY
+some internal error appeared (mostly because communication with parent process failed)
+
+.SH "SEE ALSO"
+.BR sam_data_getsize (3),
+.BR sam_data_restore (3)
diff --git a/man/sam_finalize.3.in b/man/sam_finalize.3.in
new file mode 100644
index 0000000..c633a70
--- /dev/null
+++ b/man/sam_finalize.3.in
@@ -0,0 +1,63 @@
+.\"/*
+.\" * Copyright (c) 2009 Red Hat, Inc.
+.\" *
+.\" * All rights reserved.
+.\" *
+.\" * Author: Jan Friesse (jfriesse@redhat.com)
+.\" *
+.\" * This software licensed under BSD license, the text of which follows:
+.\" *
+.\" * Redistribution and use in source and binary forms, with or without
+.\" * modification, are permitted provided that the following conditions are met:
+.\" *
+.\" * - Redistributions of source code must retain the above copyright notice,
+.\" * this list of conditions and the following disclaimer.
+.\" * - Redistributions in binary form must reproduce the above copyright notice,
+.\" * this list of conditions and the following disclaimer in the documentation
+.\" * and/or other materials provided with the distribution.
+.\" * - Neither the name of the Red Hat, Inc. nor the names of its
+.\" * contributors may be used to endorse or promote products derived from this
+.\" * software without specific prior written permission.
+.\" *
+.\" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+.\" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+.\" * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+.\" * THE POSSIBILITY OF SUCH DAMAGE.
+.\" */
+.TH "SAM_FINALIZE" 3 "12/01/2009" "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
+
+.SH NAME
+.P
+sam_finalize \- Terminate SAM service
+
+.SH SYNOPSIS
+.P
+\fB#include <corosync/sam.h>\fR
+
+.P
+\fBcs_error_t sam_finalize (void);\fR
+
+.SH DESCRIPTION
+.P
+The \fBsam_finalize\fR function is used to terminate SAM API. Once the connection is finalized,
+the SAM may not be used again by application. Whole functionality (health checking) will be
+stopped and after application fail, recovery action will not be taken.
+
+.SH RETURN VALUE
+.P
+This call return CS_OK value if successful, otherwise and error is returned.
+
+.SH ERRORS
+.TP
+CS_ERR_BAD_HANDLE
+library was not initialized by \fBsam_init(3)\fR function or was finished already.
+
+.SH "SEE ALSO"
+.BR sam_initialize (3)
diff --git a/man/sam_hc_callback_register.3.in b/man/sam_hc_callback_register.3.in
new file mode 100644
index 0000000..c9f5619
--- /dev/null
+++ b/man/sam_hc_callback_register.3.in
@@ -0,0 +1,89 @@
+.\"/*
+.\" * Copyright (c) 2009 Red Hat, Inc.
+.\" *
+.\" * All rights reserved.
+.\" *
+.\" * Author: Jan Friesse (jfriesse@redhat.com)
+.\" *
+.\" * This software licensed under BSD license, the text of which follows:
+.\" *
+.\" * Redistribution and use in source and binary forms, with or without
+.\" * modification, are permitted provided that the following conditions are met:
+.\" *
+.\" * - Redistributions of source code must retain the above copyright notice,
+.\" * this list of conditions and the following disclaimer.
+.\" * - Redistributions in binary form must reproduce the above copyright notice,
+.\" * this list of conditions and the following disclaimer in the documentation
+.\" * and/or other materials provided with the distribution.
+.\" * - Neither the name of the Red Hat, Inc. nor the names of its
+.\" * contributors may be used to endorse or promote products derived from this
+.\" * software without specific prior written permission.
+.\" *
+.\" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+.\" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+.\" * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+.\" * THE POSSIBILITY OF SUCH DAMAGE.
+.\" */
+.TH "SAM_HC_CALLBACK_REGISTER" 3 "12/01/2009" "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
+
+.SH NAME
+.P
+sam_hc_callback_register \- Register health check callback
+
+.SH SYNOPSIS
+.P
+\fB#include <corosync/sam.h>\fR
+
+.P
+\fBcs_error_t sam_hc_callback_register (sam_hc_callback_t cb);\fR
+
+.SH DESCRIPTION
+.P
+The \fBsam_hc_callback_register\fR function is used to register a user provided
+healthcheck callback. After calling of this function, the SAM is switched
+from application driven healthchecking to event driven healthchecking. In this
+mode, \fBsam_hc_send(3)\fR does not need to be executed.
+
+.P
+The parameter \fIcb\fR is callback function of type \fIsam_hc_callback_t\fR
+defined as:
+
+.nf
+ typedef int (*sam_hc_callback_t)(void);
+.fi
+
+.P
+This function will be regularly called and must return 0 if the process is
+functioning normally, or -1 if the process is executing abnormally. When -1 is
+returned, the SAM server execute the registered recovery policy.
+
+.P
+A value of NULL can be passed into this function to switch into application
+driven healthchecking.
+\fIcb\fR to NULL.
+
+.SH RETURN VALUE
+.P
+This call return CS_OK value if successful, otherwise and error is returned.
+
+.SH ERRORS
+.TP
+CS_ERR_BAD_HANDLE
+SAM was not initialized and registered or health checking is in running state
+.TP
+CS_ERR_LIBRARY
+internal library call failed. This can occur during fork() or pipe() system
+calls and the errno variable can be read to retrieve more information.
+
+.SH "SEE ALSO"
+.BR sam_start (3),
+.BR sam_stop (3),
+.BR sam_hc_send (3),
+.BR sam_register (3),
diff --git a/man/sam_hc_send.3.in b/man/sam_hc_send.3.in
new file mode 100644
index 0000000..dfcf93c
--- /dev/null
+++ b/man/sam_hc_send.3.in
@@ -0,0 +1,68 @@
+.\"/*
+.\" * Copyright (c) 2009 Red Hat, Inc.
+.\" *
+.\" * All rights reserved.
+.\" *
+.\" * Author: Jan Friesse (jfriesse@redhat.com)
+.\" *
+.\" * This software licensed under BSD license, the text of which follows:
+.\" *
+.\" * Redistribution and use in source and binary forms, with or without
+.\" * modification, are permitted provided that the following conditions are met:
+.\" *
+.\" * - Redistributions of source code must retain the above copyright notice,
+.\" * this list of conditions and the following disclaimer.
+.\" * - Redistributions in binary form must reproduce the above copyright notice,
+.\" * this list of conditions and the following disclaimer in the documentation
+.\" * and/or other materials provided with the distribution.
+.\" * - Neither the name of the Red Hat, Inc. nor the names of its
+.\" * contributors may be used to endorse or promote products derived from this
+.\" * software without specific prior written permission.
+.\" *
+.\" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+.\" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+.\" * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+.\" * THE POSSIBILITY OF SUCH DAMAGE.
+.\" */
+.TH "SAM_HC_SEND" 3 "12/01/2009" "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
+
+.SH NAME
+.P
+sam_hc_send \- Send health check confirmation
+
+.SH SYNOPSIS
+.P
+\fB#include <corosync/sam.h>\fR
+
+.P
+\fBcs_error_t sam_hc_send (void);\fR
+
+.SH DESCRIPTION
+.P
+The \fBsam_hc_send\fR function is used to send healthcheck confirmation from
+the application. This function should be called regularly when configured for
+application driven healthchecking, otherwise recovery action will be taken.
+
+When using event driven healthchecking, this function should not be used.
+
+.SH RETURN VALUE
+.P
+This call return CS_OK value if successful, otherwise and error is returned.
+
+.SH ERRORS
+.TP
+CS_ERR_BAD_HANDLE
+health checking is not in running state (\fBsam_start(3)\fR has not been
+executed) or function is called after stop/finalization of SAM.
+
+.SH "SEE ALSO"
+.BR sam_start (3),
+.BR sam_stop (3),
+.BR sam_hc_callback_register (3)
diff --git a/man/sam_initialize.3.in b/man/sam_initialize.3.in
new file mode 100644
index 0000000..2e57904
--- /dev/null
+++ b/man/sam_initialize.3.in
@@ -0,0 +1,126 @@
+.\"/*
+.\" * Copyright (c) 2009-2010 Red Hat, Inc.
+.\" *
+.\" * All rights reserved.
+.\" *
+.\" * Author: Jan Friesse (jfriesse@redhat.com)
+.\" *
+.\" * This software licensed under BSD license, the text of which follows:
+.\" *
+.\" * Redistribution and use in source and binary forms, with or without
+.\" * modification, are permitted provided that the following conditions are met:
+.\" *
+.\" * - Redistributions of source code must retain the above copyright notice,
+.\" * this list of conditions and the following disclaimer.
+.\" * - Redistributions in binary form must reproduce the above copyright notice,
+.\" * this list of conditions and the following disclaimer in the documentation
+.\" * and/or other materials provided with the distribution.
+.\" * - Neither the name of the Red Hat, Inc. nor the names of its
+.\" * contributors may be used to endorse or promote products derived from this
+.\" * software without specific prior written permission.
+.\" *
+.\" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+.\" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+.\" * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+.\" * THE POSSIBILITY OF SUCH DAMAGE.
+.\" */
+.TH "SAM_INITIALIZE" 3 "21/05/2010" "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
+
+.SH NAME
+.P
+sam_initialize \- Initialize health checking
+
+.SH SYNOPSIS
+.P
+\fB#include <corosync/sam.h>\fR
+
+.P
+\fBcs_error_t sam_initialize (int\fR \fItime_interval\fR\fB, sam_recovery_policy_t \fIrecovery_policy\fR);\fR
+
+.SH DESCRIPTION
+.P
+The \fBsam_initialize\fR function is used to initialize health checking of a process.
+
+.P
+Application can have only one instance of SAM. This function must be called
+before any other of SAM functions. It is recommended to initialize before the
+process begins any process initialization.
+
+.P
+The \fItime_interval\fR parameter is a timeout in milliseconds before taking
+recovery action after having not received a healthcheck.
+
+If \fItime_interval\fR parameter is zero, there is no time limit and no
+healthcheck must be sent by the process. In this operational mode, a process
+failure will continue to execute the recovery policy.
+
+.P
+The \fIrecovery_policy\fR is defined as type:
+
+.nf
+ typedef enum {
+ SAM_RECOVERY_POLICY_QUIT = 1,
+ SAM_RECOVERY_POLICY_RESTART = 2,
+ SAM_RECOVERY_POLICY_QUORUM = 0x08,
+ SAM_RECOVERY_POLICY_QUORUM_QUIT = SAM_RECOVERY_POLICY_QUORUM | SAM_RECOVERY_POLICY_QUIT,
+ SAM_RECOVERY_POLICY_QUORUM_RESTART = SAM_RECOVERY_POLICY_QUORUM | SAM_RECOVERY_POLICY_RESTART,
+ SAM_RECOVERY_POLICY_CMAP = 0x10,
+ SAM_RECOVERY_POLICY_CONFDB = 0x10,
+ } sam_recovery_policy_t;
+.fi
+
+.P
+where
+
+.TP
+SAM_RECOVERY_POLICY_QUIT
+on failure, the process will terminate.
+.TP
+SAM_RECOVERY_POLICY_RESTART
+on failure, the process will restart.
+.TP
+SAM_RECOVERY_POLICY_QUORUM
+is not policy. Used only as flag meaning quorum integration
+.TP
+SAM_RECOVERY_POLICY_QUORUM_QUIT
+same as \fISAM_RECOVERY_POLICY_QUIT\fR but \fBsam_start (3)\fR will block until corosync becomes
+quorate and process will be terminated if quorum is lost.
+.TP
+SAM_RECOVERY_POLICY_QUORUM_RESTART
+same as \fISAM_RECOVERY_POLICY_RESTART\fR but \fBsam_start (3)\fR will block until corosync becomes
+quorate and process will be restarted if quorum is lost.
+.TP
+SAM_RECOVERY_POLICY_CMAP
+is not policy. Used only as flag meaning cmap integration. It can be used with all previous policies.
+For backward compatibility, SAM_RECOVERY_POLICY_CONFDB with same meaning as
+\fISAM_RECOVERY_POLICY_CMAP\fR is also provided.
+
+.P
+To perform event driven healthchecking, \fBsam_register(3)\fR and
+\fBsam_start(3)\fR functions must called. Event driven healthchecking causes
+the duplicate standby process running the SAM serve rto periodically request
+healthchecks from the active process.
+
+.SH RETURN VALUE
+.P
+This call return CS_OK value if successful, otherwise and error is returned.
+
+.SH ERRORS
+.TP
+CS_ERR_BAD_HANDLE
+can happened in case of double initialization.
+.TP
+CS_ERR_INVALID_PARAM
+\fIrecovery_policy\fR has invalid value.
+
+.SH "SEE ALSO"
+.BR sam_register (3),
+.BR sam_start (3),
+.BR sam_hc_callback_register (3)
diff --git a/man/sam_mark_failed.3.in b/man/sam_mark_failed.3.in
new file mode 100644
index 0000000..acfb3ee
--- /dev/null
+++ b/man/sam_mark_failed.3.in
@@ -0,0 +1,73 @@
+.\"/*
+.\" * Copyright (c) 2010 Red Hat, Inc.
+.\" *
+.\" * All rights reserved.
+.\" *
+.\" * Author: Jan Friesse (jfriesse@redhat.com)
+.\" *
+.\" * This software licensed under BSD license, the text of which follows:
+.\" *
+.\" * Redistribution and use in source and binary forms, with or without
+.\" * modification, are permitted provided that the following conditions are met:
+.\" *
+.\" * - Redistributions of source code must retain the above copyright notice,
+.\" * this list of conditions and the following disclaimer.
+.\" * - Redistributions in binary form must reproduce the above copyright notice,
+.\" * this list of conditions and the following disclaimer in the documentation
+.\" * and/or other materials provided with the distribution.
+.\" * - Neither the name of the Red Hat, Inc. nor the names of its
+.\" * contributors may be used to endorse or promote products derived from this
+.\" * software without specific prior written permission.
+.\" *
+.\" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+.\" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+.\" * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+.\" * THE POSSIBILITY OF SUCH DAMAGE.
+.\" */
+.TH "SAM_STOP" 3 "21/05/2010" "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
+
+.SH NAME
+.P
+sam_mark_failed \- Mark process failed
+
+.SH SYNOPSIS
+.P
+\fB#include <corosync/sam.h>\fR
+
+.P
+\fBcs_error_t sam_mark_failed (void);\fR
+
+.SH DESCRIPTION
+.P
+The \fBsam_mark_failed\fR function is used with SAM_RECOVERY_POLICY_CMAP mostly
+together with SAM_RECOVERY_POLICY_RESTART to mark process failed. Process marked
+failed is killed without sending warn signal and control process will exit
+as with SAM_RECOVERY_POLICY_QUIT policy. Condb key state will be set to failed so
+corosync watchdog can take required action.
+
+.SH RETURN VALUE
+.P
+This call return CS_OK value if successful, otherwise and error is returned.
+
+.SH ERRORS
+.TP
+CS_ERR_BAD_HANDLE
+library was not initialized by calling \fBsam_initialize(3)\fR or was already finalized
+
+.TP
+CS_ERR_INVALID_PARAM
+recovery policy doesn't has SAM_RECOVERY_POLICY_CMAP flag set
+
+.TP
+CS_ERR_LIBRARY
+some internal error appeared (communication with parent process)
+
+.SH "SEE ALSO"
+.BR sam_initialize (3)
diff --git a/man/sam_overview.3 b/man/sam_overview.3
new file mode 100644
index 0000000..13b45ad
--- /dev/null
+++ b/man/sam_overview.3
@@ -0,0 +1,181 @@
+.\"/*
+.\" * Copyright (c) 2009-2010 Red Hat, Inc.
+.\" *
+.\" * All rights reserved.
+.\" *
+.\" * Author: Jan Friesse (jfriesse@redhat.com)
+.\" * Author: Steven Dake (sdake@redhat.com)
+.\" *
+.\" * This software licensed under BSD license, the text of which follows:
+.\" *
+.\" * Redistribution and use in source and binary forms, with or without
+.\" * modification, are permitted provided that the following conditions are met:
+.\" *
+.\" * - Redistributions of source code must retain the above copyright notice,
+.\" * this list of conditions and the following disclaimer.
+.\" * - Redistributions in binary form must reproduce the above copyright notice,
+.\" * this list of conditions and the following disclaimer in the documentation
+.\" * and/or other materials provided with the distribution.
+.\" * - Neither the name of the Red Hat, Inc. nor the names of its
+.\" * contributors may be used to endorse or promote products derived from this
+.\" * software without specific prior written permission.
+.\" *
+.\" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+.\" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+.\" * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+.\" * THE POSSIBILITY OF SUCH DAMAGE.
+.\" */
+.TH "SAM_OVERVIEW" 3 "21/05/2010" "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
+
+.SH NAME
+.P
+sam_overview \- Overview of the Simple Availability Manager
+
+.SH OVERVIEW
+.P
+The SAM library provide a tool to check the health of an application.
+The main purpose of SAM is to restart a local process when it fails to respond
+to a healthcheck request in a configured time interval.
+
+.P
+During \fBsam_initialize(3)\fR, a duplicate copy of the process is created using
+the \fBfork(3)\fR system call. This duplicate process copy contains the logic
+for executing the SAM server. The SAM server is responsible for requesting
+healthchecks from the active process, and controlling the lifecycle of the
+active process when it fails. If the active process fails to respond to the
+healthcheck request sent by the SAM server, it will be sent a user configurable
+signal (default SIGTERM) to request shutdown of the application. After a configured time interval, the
+process will be forcibly killed by being sent a SIGKILL signal. Once the
+active process terminates, the SAM server will create a new active process.
+
+.P
+The Simple Availability Manager is meant to be used in conjunction with the
+cpg service. Used together, it is possible to restart a cpg process that fails
+healthchecking during operation.
+
+.P
+The main features of SAM include:
+
+.RS
+.IP \(bu 3
+A configurable recovery policy.
+.IP \(bu 3
+A configurable time interval for health check operations.
+.IP \(bu 3
+A notification via signal before recovery action is taken.
+.IP \(bu 3
+A mechanism to indicate to the application the number of times an active
+process has been created by the SAM server.
+.IP \(bu 3
+Both application driven health checking and event driven health checking.
+.RE
+
+.SH Initializing SAM
+.P
+The SAM library is initialized by \fBsam_initialize(3)\fR.
+\fBsam_initalize(3)\fR may only be called once per process. Calling it more
+then once has undefined results and is not recommended or tested.
+
+.SH Setting warning callback
+.P
+User configurable signal (default \fISIGTERM\fR) is sent to the application when a recovery action is
+planned. The application can use the \fBsignal(3)\fR system call to monitor
+for this signal.
+
+.P
+There are no special constraints on what SAM apis may be called in a warning
+callback. After \fItime_interval\fR expires, a SIGKILL signal is sent to the
+active process to force its termination.
+
+.SH Registering the active process
+.P
+The active process is registered with SAM by calling \fBsam_register(3)\fR.
+This function should only be called one time in a process. After a recovery
+action is taken, the new active process will begin execution at the next line
+of code in a user process after \fBsam_register(3)\fR.
+
+.SH Enabling event driven healthchecking
+.P
+Two types of healthchecking are available to the user. The first model is one
+where the user application healthchecks during its normal operation. It is
+never requested to healtcheck, and if the active process doesn't respond within
+the time interval, the process will be restarted.
+
+.P
+A more useful mechanism for healthchecking is event driven healthchecking.
+Because this model is directed by the SAM server, It isn't necessary to guess
+or add timers to the active process to signal a healthcheck operation is
+successful. To use event driven healthchecking,
+the \fBsam_hc_callback_register(3)\fR function should be executed.
+
+.SH Quorum integration
+.P
+SAM has special policies (\fISAM_RECOVERY_POLICY_QUIT\fR and \fISAM_RECOVERY_POLICY_RESTART\fR)
+for integration with quorum service. This policies changes SAM behaviour in two aspects.
+.RS
+.IP \(bu 3
+Call of \fBsam_start(3)\fR blocks until corosync becomes quorate
+.IP \(bu 3
+User selected recovery action is taken immediately after lost of quorum.
+.RE
+
+.SH Storing user data
+.P
+Sometimes there is need to store some data, which survives between instances.
+One can in such case use files, databases, ... or much simpler in memory solution
+presented by \fBsam_data_store(3)\fR, \fBsam_data_restore(3)\fR and \fBsam_data_getsize(3)\fR
+functions.
+
+.SH Confdb integration
+.P
+SAM has policy flag used for confdb system integration (\fISAM_RECOVERY_POLICY_CONFDB\fR).
+If process is registered with this flag, new confdb object PROCESS_NAME:PID is created with following
+keys:
+.RS
+.IP \(bu 3
+\fIrecovery\fR - will be quit or restart depending on policy
+.IP \(bu 3
+\fIpoll_period\fR - period of health checking in milliseconds
+.IP \(bu 3
+\fIlast_updated\fR - Timestamp (in nanoseconds) of the last health check.
+.IP \(bu 3
+\fIstate\fR - state of process (can be one of registered, started, failed, waiting for quorum)
+.RE
+
+.P
+Object is automatically deleted if process exits with stopped health checking.
+
+.P
+Confdb integration with corosync watchdog can be used in implicit and explicit way.
+
+.P
+Implicit way is achieved by setting recovery policy to QUIT and let process exit with started health checking.
+If this happened, object is not deleted and corosync watchdog will take required action.
+
+.P
+Explicit way is useful for situations, when developer can deal with some non-fatal fall of application.
+This mode is achieved by setting policy to RESTART and using SAM same as without Confdb integration.
+If real fail is needed (like too many restarts at all, per/sec, ...), it's possible to use \fBsam_mark_failed(3)\fR
+and let corosync watchdog take required action.
+
+.SH BUGS
+.SH "SEE ALSO"
+.BR sam_initialize (3),
+.BR sam_data_getsize (3),
+.BR sam_data_restore (3),
+.BR sam_data_store (3),
+.BR sam_finalize (3),
+.BR sam_mark_failed (3),
+.BR sam_start (3),
+.BR sam_stop (3),
+.BR sam_register (3),
+.BR sam_warn_signal_set (3),
+.BR sam_hc_send (3),
+.BR sam_hc_callback_register (3)
diff --git a/man/sam_register.3.in b/man/sam_register.3.in
new file mode 100644
index 0000000..2af86d2
--- /dev/null
+++ b/man/sam_register.3.in
@@ -0,0 +1,88 @@
+.\"/*
+.\" * Copyright (c) 2009 Red Hat, Inc.
+.\" *
+.\" * All rights reserved.
+.\" *
+.\" * Author: Jan Friesse (jfriesse@redhat.com)
+.\" *
+.\" * This software licensed under BSD license, the text of which follows:
+.\" *
+.\" * Redistribution and use in source and binary forms, with or without
+.\" * modification, are permitted provided that the following conditions are met:
+.\" *
+.\" * - Redistributions of source code must retain the above copyright notice,
+.\" * this list of conditions and the following disclaimer.
+.\" * - Redistributions in binary form must reproduce the above copyright notice,
+.\" * this list of conditions and the following disclaimer in the documentation
+.\" * and/or other materials provided with the distribution.
+.\" * - Neither the name of the Red Hat, Inc. nor the names of its
+.\" * contributors may be used to endorse or promote products derived from this
+.\" * software without specific prior written permission.
+.\" *
+.\" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+.\" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+.\" * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+.\" * THE POSSIBILITY OF SUCH DAMAGE.
+.\" */
+.TH "SAM_REGISTER" 3 "12/01/2009" "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
+
+.SH NAME
+.P
+sam_rehister \- Register component for health checking
+
+.SH SYNOPSIS
+.P
+\fB#include <corosync/sam.h>\fR
+
+.P
+\fBcs_error_t sam_register (unsigned int *\fIinstance_id\fR);\fR
+
+.SH DESCRIPTION
+.P
+The \fBsam_register\fR function is used to register a process for healthchecking.
+If recovery policy is set to \fISAM_RECOVERY_POLICY_RESTART\fR and recovery
+action will be taken, the new process instance will begin execution at the next
+code line after this function is called.
+
+.P
+This function can be called only once and SAM must be initialized by
+\fBsam_initialize(3)\fR function.
+
+.P
+The \fIinstance_id\fR argument is a pointer to a value storing the current
+iteration instance. If this parameter is NULL, no \fIinstance_id\fR is returned.
+and then, no \fIinstance_id\fR will be returned. This value starts at 0 for the
+first iteration instance, and increases by 1 each time a recovery restart is
+executed. After reaching MAX_INT, the instance_id will reset to 0.
+
+.P
+The placement of this function is important because after it is called, the
+process id will change.
+
+.P
+After registration, event driven health checking is not running.
+
+.SH RETURN VALUE
+.P
+This call return CS_OK value if successful, otherwise and error is returned.
+
+.SH ERRORS
+.TP
+CS_ERR_BAD_HANDLE
+health checking was not started by calling \fBsam_start(3)\fR function.
+.TP
+CS_ERR_LIBRARY
+internal library call failed. This can be one of pipe creation or fork.
+It's possible to get more information from errno.
+
+.SH "SEE ALSO"
+.BR sam_start (3),
+.BR sam_initialize (3),
+.BR sam_hc_callback_register (3)
diff --git a/man/sam_start.3.in b/man/sam_start.3.in
new file mode 100644
index 0000000..c49f230
--- /dev/null
+++ b/man/sam_start.3.in
@@ -0,0 +1,83 @@
+.\"/*
+.\" * Copyright (c) 2009-2010 Red Hat, Inc.
+.\" *
+.\" * All rights reserved.
+.\" *
+.\" * Author: Jan Friesse (jfriesse@redhat.com)
+.\" *
+.\" * This software licensed under BSD license, the text of which follows:
+.\" *
+.\" * Redistribution and use in source and binary forms, with or without
+.\" * modification, are permitted provided that the following conditions are met:
+.\" *
+.\" * - Redistributions of source code must retain the above copyright notice,
+.\" * this list of conditions and the following disclaimer.
+.\" * - Redistributions in binary form must reproduce the above copyright notice,
+.\" * this list of conditions and the following disclaimer in the documentation
+.\" * and/or other materials provided with the distribution.
+.\" * - Neither the name of the Red Hat, Inc. nor the names of its
+.\" * contributors may be used to endorse or promote products derived from this
+.\" * software without specific prior written permission.
+.\" *
+.\" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+.\" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+.\" * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+.\" * THE POSSIBILITY OF SUCH DAMAGE.
+.\" */
+.TH "SAM_START" 3 "30/04/2010" "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
+
+.SH NAME
+.P
+sam_start \- Start health checking
+
+.SH SYNOPSIS
+.P
+\fB#include <corosync/sam.h>\fR
+
+.P
+\fBcs_error_t sam_start (void);\fR
+
+.SH DESCRIPTION
+.P
+The \fBsam_start\fR function is used to start health checking of application.
+After calling this function, the active process needs to send healthchecks
+within the registered time interval by calling \fBsam_hc_send(3)\fR. If
+event driven healthchecking is configured by calling \fBsam_register(3)\fR,
+an internal thread will be created and send health check confirmations four
+times per \fItime_interval\fR.
+
+.P
+Application must be registered by calling \fBsam_register(3)\fR before this
+function can be called.
+
+.P
+An application can always stop health checking by calling the \fBsam_stop(3)\fR
+function.
+
+.P
+If SAM is initialized with quorum policy \fISAM_RECOVERY_POLICY_QUIT\fR or
+\fISAM_RECOVERY_POLICY_RESTART\fR \fBsam_start\fR will block until corosync
+becomes quorate.
+
+.SH RETURN VALUE
+.P
+This call return CS_OK value if successful, otherwise and error is returned. If
+SAM is initialized with quorum policy, returned error can also be quorum error.
+
+.SH ERRORS
+.TP
+CS_ERR_BAD_HANDLE
+component was not registered by calling \fBsam_register(3)\fR function.
+
+.SH "SEE ALSO"
+.BR sam_hc_send (3),
+.BR sam_stop (3),
+.BR sam_register (3),
+.BR sam_hc_callback_register (3)
diff --git a/man/sam_stop.3.in b/man/sam_stop.3.in
new file mode 100644
index 0000000..708d079
--- /dev/null
+++ b/man/sam_stop.3.in
@@ -0,0 +1,67 @@
+.\"/*
+.\" * Copyright (c) 2009 Red Hat, Inc.
+.\" *
+.\" * All rights reserved.
+.\" *
+.\" * Author: Jan Friesse (jfriesse@redhat.com)
+.\" *
+.\" * This software licensed under BSD license, the text of which follows:
+.\" *
+.\" * Redistribution and use in source and binary forms, with or without
+.\" * modification, are permitted provided that the following conditions are met:
+.\" *
+.\" * - Redistributions of source code must retain the above copyright notice,
+.\" * this list of conditions and the following disclaimer.
+.\" * - Redistributions in binary form must reproduce the above copyright notice,
+.\" * this list of conditions and the following disclaimer in the documentation
+.\" * and/or other materials provided with the distribution.
+.\" * - Neither the name of the Red Hat, Inc. nor the names of its
+.\" * contributors may be used to endorse or promote products derived from this
+.\" * software without specific prior written permission.
+.\" *
+.\" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+.\" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+.\" * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+.\" * THE POSSIBILITY OF SUCH DAMAGE.
+.\" */
+.TH "SAM_STOP" 3 "12/01/2009" "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
+
+.SH NAME
+.P
+sam_stop \- Stop health checking
+
+.SH SYNOPSIS
+.P
+\fB#include <corosync/sam.h>\fR
+
+.P
+\fBcs_error_t sam_stop (void);\fR
+
+.SH DESCRIPTION
+.P
+The \fBsam_stop\fR function is used to stop health checking of an active
+process. After calling this function, the application no longer should send
+helathchecks. In the case of event driven healthchecking, the healthchecking
+thread will be stopped.
+
+.P
+A process can always start health checking again by calling \fBsam_start(3)\fR function.
+
+.SH RETURN VALUE
+.P
+This call return CS_OK value if successful, otherwise and error is returned.
+
+.SH ERRORS
+.TP
+CS_ERR_BAD_HANDLE
+health checking was not started by calling \fBsam_start(3)\fR function.
+
+.SH "SEE ALSO"
+.BR sam_start (3)
diff --git a/man/sam_warn_signal_set.3.in b/man/sam_warn_signal_set.3.in
new file mode 100644
index 0000000..ffc31eb
--- /dev/null
+++ b/man/sam_warn_signal_set.3.in
@@ -0,0 +1,63 @@
+.\"/*
+.\" * Copyright (c) 2010 Red Hat, Inc.
+.\" *
+.\" * All rights reserved.
+.\" *
+.\" * Author: Jan Friesse (jfriesse@redhat.com)
+.\" *
+.\" * This software licensed under BSD license, the text of which follows:
+.\" *
+.\" * Redistribution and use in source and binary forms, with or without
+.\" * modification, are permitted provided that the following conditions are met:
+.\" *
+.\" * - Redistributions of source code must retain the above copyright notice,
+.\" * this list of conditions and the following disclaimer.
+.\" * - Redistributions in binary form must reproduce the above copyright notice,
+.\" * this list of conditions and the following disclaimer in the documentation
+.\" * and/or other materials provided with the distribution.
+.\" * - Neither the name of the Red Hat, Inc. nor the names of its
+.\" * contributors may be used to endorse or promote products derived from this
+.\" * software without specific prior written permission.
+.\" *
+.\" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+.\" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+.\" * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+.\" * THE POSSIBILITY OF SUCH DAMAGE.
+.\" */
+.TH "SAM_WARN_SIGNAL_SET" 3 "03/11/2010" "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
+
+.SH NAME
+.P
+sam_warn_signal_set \- Set warn signal
+
+.SH SYNOPSIS
+.P
+\fB#include <corosync/sam.h>\fR
+
+.P
+\fBcs_error_t sam_warn_signal_set (int warn_signal);\fR
+
+.SH DESCRIPTION
+.P
+The \fBsam_warn_signal_set\fR function is used to configure warning signal
+sent before real killing of unresponsive application. Default value is
+SIGTERM. SIGKILL can be used to emulate "not warning signal send" behaviour.
+
+.SH RETURN VALUE
+.P
+This call return CS_OK value if successful, otherwise and error is returned.
+
+.SH ERRORS
+.TP
+CS_ERR_BAD_HANDLE
+component was not initialized by calling \fBsam_initialize(3)\fR or it was finalized.
+
+.SH "SEE ALSO"
+.BR sam_initialize (3)
diff --git a/man/votequorum.5 b/man/votequorum.5
new file mode 100644
index 0000000..0cb03c2
--- /dev/null
+++ b/man/votequorum.5
@@ -0,0 +1,410 @@
+.\"/*
+.\" * Copyright (c) 2012-2014 Red Hat, Inc.
+.\" *
+.\" * All rights reserved.
+.\" *
+.\" * Authors: Christine Caulfield <ccaulfie@redhat.com>
+.\" * Fabio M. Di Nitto <fdinitto@redhat.com>
+.\" *
+.\" * This software licensed under BSD license, the text of which follows:
+.\" *
+.\" * Redistribution and use in source and binary forms, with or without
+.\" * modification, are permitted provided that the following conditions are met:
+.\" *
+.\" * - Redistributions of source code must retain the above copyright notice,
+.\" * this list of conditions and the following disclaimer.
+.\" * - Redistributions in binary form must reproduce the above copyright notice,
+.\" * this list of conditions and the following disclaimer in the documentation
+.\" * and/or other materials provided with the distribution.
+.\" * - Neither the name of the MontaVista Software, Inc. nor the names of its
+.\" * contributors may be used to endorse or promote products derived from this
+.\" * software without specific prior written permission.
+.\" *
+.\" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+.\" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+.\" * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+.\" * THE POSSIBILITY OF SUCH DAMAGE.
+.\" */
+.TH VOTEQUORUM 5 2018-12-14 "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
+.SH NAME
+votequorum \- Votequorum Configuration Overview
+.SH OVERVIEW
+The votequorum service is part of the corosync project. This service can be optionally loaded
+into the nodes of a corosync cluster to avoid split-brain situations.
+It does this by having a number of votes assigned to each system in the cluster and ensuring
+that only when a majority of the votes are present, cluster operations are allowed to proceed.
+The service must be loaded into all nodes or none. If it is loaded into a subset of cluster nodes
+the results will be unpredictable.
+.PP
+The following corosync.conf extract will enable votequorum service within corosync:
+.PP
+.nf
+quorum {
+ provider: corosync_votequorum
+}
+.fi
+.PP
+votequorum reads its configuration from corosync.conf. Some values can be changed at runtime, others
+are only read at corosync startup. It is very important that those values are consistent
+across all the nodes participating in the cluster or votequorum behavior will be unpredictable.
+.PP
+votequorum requires an expected_votes value to function, this can be provided in two ways.
+The number of expected votes will be automatically calculated when the nodelist { } section is
+present in corosync.conf or expected_votes can be specified in the quorum { } section. Lack of
+both will disable votequorum. If both are present at the same time,
+the quorum.expected_votes value will override the one calculated from the nodelist.
+.PP
+Example (no nodelist) of an 8 node cluster (each node has 1 vote):
+.nf
+
+quorum {
+ provider: corosync_votequorum
+ expected_votes: 8
+}
+.fi
+.PP
+Example (with nodelist) of a 3 node cluster (each node has 1 vote):
+.nf
+
+quorum {
+ provider: corosync_votequorum
+}
+
+nodelist {
+ node {
+ ring0_addr: 192.168.1.1
+ }
+ node {
+ ring0_addr: 192.168.1.2
+ }
+ node {
+ ring0_addr: 192.168.1.3
+ }
+}
+.fi
+.SH SPECIAL FEATURES
+.PP
+.B two_node: 1
+.PP
+Enables two node cluster operations (default: 0).
+.PP
+The "two node cluster" is a use case that requires special consideration.
+With a standard two node cluster, each node with a single vote, there
+are 2 votes in the cluster. Using the simple majority calculation
+(50% of the votes + 1) to calculate quorum, the quorum would be 2.
+This means that the both nodes would always have
+to be alive for the cluster to be quorate and operate.
+.PP
+Enabling two_node: 1, quorum is set artificially to 1.
+.PP
+Example configuration 1:
+
+.nf
+quorum {
+ provider: corosync_votequorum
+ expected_votes: 2
+ two_node: 1
+}
+.fi
+
+.PP
+Example configuration 2:
+
+.nf
+quorum {
+ provider: corosync_votequorum
+ two_node: 1
+}
+
+nodelist {
+ node {
+ ring0_addr: 192.168.1.1
+ }
+ node {
+ ring0_addr: 192.168.1.2
+ }
+}
+.fi
+.PP
+NOTES: enabling two_node: 1 automatically enables wait_for_all. It is
+still possible to override wait_for_all by explicitly setting it to 0.
+If more than 2 nodes join the cluster, the two_node option is
+automatically disabled.
+.PP
+.B wait_for_all: 1
+.PP
+Enables Wait For All (WFA) feature (default: 0).
+.PP
+The general behaviour of votequorum is to switch a cluster from inquorate to quorate
+as soon as possible. For example, in an 8 node cluster, where every node has 1 vote,
+expected_votes is set to 8 and quorum is (50% + 1) 5. As soon as 5 (or more) nodes
+are visible to each other, the partition of 5 (or more) becomes quorate and can
+start operating.
+.PP
+When WFA is enabled, the cluster will be quorate for the first time
+only after all nodes have been visible at least once at the same time.
+.PP
+This feature has the advantage of avoiding some startup race conditions, with the cost
+that all nodes need to be up at the same time at least once before the cluster
+can operate.
+.PP
+A common startup race condition based on the above example is that as soon as 5
+nodes become quorate, with the other 3 still offline, the remaining 3 nodes will
+be fenced.
+.PP
+It is very useful when combined with last_man_standing (see below).
+.PP
+Example configuration:
+.nf
+
+quorum {
+ provider: corosync_votequorum
+ expected_votes: 8
+ wait_for_all: 1
+}
+.fi
+.PP
+.B last_man_standing: 1
+/
+.B last_man_standing_window: 10000
+.PP
+Enables Last Man Standing (LMS) feature (default: 0).
+Tunable last_man_standing_window (default: 10 seconds, expressed in ms).
+.PP
+The general behaviour of votequorum is to set expected_votes and quorum
+at startup (unless modified by the user at runtime, see below) and use
+those values during the whole lifetime of the cluster.
+.PP
+Using for example an 8 node cluster where each node has 1 vote, expected_votes
+is set to 8 and quorum to 5. This condition allows a total failure of 3
+nodes. If a 4th node fails, the cluster becomes inquorate and it will
+stop providing services.
+.PP
+Enabling LMS allows the cluster to dynamically recalculate expected_votes
+and quorum under specific circumstances. It is essential to enable
+WFA when using LMS in High Availability clusters.
+.PP
+Using the above 8 node cluster example, with LMS enabled the cluster can retain
+quorum and continue operating by losing, in a cascade fashion, up to 6 nodes with
+only 2 remaining active.
+.PP
+Example chain of events:
+.nf
+1) cluster is fully operational with 8 nodes.
+ (expected_votes: 8 quorum: 5)
+
+2) 3 nodes die, cluster is quorate with 5 nodes.
+
+3) after last_man_standing_window timer expires,
+ expected_votes and quorum are recalculated.
+ (expected_votes: 5 quorum: 3)
+
+4) at this point, 2 more nodes can die and
+ cluster will still be quorate with 3.
+
+5) once again, after last_man_standing_window
+ timer expires expected_votes and quorum are
+ recalculated.
+ (expected_votes: 3 quorum: 2)
+
+6) at this point, 1 more node can die and
+ cluster will still be quorate with 2.
+
+7) one more last_man_standing_window timer
+ (expected_votes: 2 quorum: 2)
+.fi
+.PP
+NOTES: In order for the cluster to downgrade automatically from 2 nodes
+to a 1 node cluster, the auto_tie_breaker feature must also be enabled (see below).
+If auto_tie_breaker is not enabled, and one more failure occurs, the
+remaining node will not be quorate. LMS does not work with asymmetric voting
+schemes, each node must vote 1. LMS is also incompatible with quorum devices,
+if last_man_standing is specified in corosync.conf then the quorum device
+will be disabled.
+
+.PP
+Example configuration 1:
+.nf
+
+quorum {
+ provider: corosync_votequorum
+ expected_votes: 8
+ last_man_standing: 1
+}
+.fi
+.PP
+Example configuration 2 (increase timeout to 20 seconds):
+.nf
+
+quorum {
+ provider: corosync_votequorum
+ expected_votes: 8
+ last_man_standing: 1
+ last_man_standing_window: 20000
+}
+.fi
+.PP
+.B auto_tie_breaker: 1
+.PP
+Enables Auto Tie Breaker (ATB) feature (default: 0).
+.PP
+The general behaviour of votequorum allows a simultaneous node failure up
+to 50% - 1 node, assuming each node has 1 vote.
+.PP
+When ATB is enabled, the cluster can suffer up to 50% of the nodes failing
+at the same time, in a deterministic fashion. By default the cluster
+partition, or the set of nodes that are still in contact with the
+node that has the lowest nodeid will remain quorate. The other nodes will
+be inquorate. This behaviour can be changed by also specifying
+.PP
+.B auto_tie_breaker_node: lowest|highest|<list of node IDs>
+.PP
+\(oqlowest\(cq is the default, \(oqhighest\(cq is similar in that if the current set of
+nodes contains the highest nodeid then it will remain quorate. Alternatively
+it is possible to specify a particular node ID or list of node IDs that will
+be required to maintain quorum. If a (space-separated) list is given, the
+nodes are evaluated in order, so if the first node is present then it will
+be used to determine the quorate partition, if that node is not in either
+half (ie was not in the cluster before the split) then the second node ID
+will be checked for and so on. ATB is incompatible with quorum devices -
+if auto_tie_breaker is specified in corosync.conf then the quorum device
+will be disabled.
+.PP
+Example configuration 1:
+.nf
+
+quorum {
+ provider: corosync_votequorum
+ expected_votes: 8
+ auto_tie_breaker: 1
+ auto_tie_breaker_node: lowest
+}
+.fi
+.PP
+Example configuration 2:
+.nf
+quorum {
+ provider: corosync_votequorum
+ expected_votes: 8
+ auto_tie_breaker: 1
+ auto_tie_breaker_node: 1 3 5
+}
+.PP
+.fi
+.PP
+.B allow_downscale: 1
+.PP
+Enables allow downscale (AD) feature (default: 0).
+.PP
+THIS FEATURE IS INCOMPLETE AND CURRENTLY UNSUPPORTED.
+.PP
+The general behaviour of votequorum is to never decrease expected votes or quorum.
+.PP
+When AD is enabled, both expected votes and quorum are recalculated when
+a node leaves the cluster in a clean state (normal corosync shutdown process) down
+to configured expected_votes.
+.PP
+Example use case:
+.PP
+.nf
+1) N node cluster (where N is any value higher than 3)
+
+2) expected_votes set to 3 in corosync.conf
+
+3) only 3 nodes are running
+
+4) admin requires to increase processing power and adds 10 nodes
+
+5) internal expected_votes is automatically set to 13
+
+6) minimum expected_votes is 3 (from configuration)
+
+- up to this point this is standard votequorum behavior -
+
+7) once the work is done, admin wants to remove nodes from the cluster
+
+8) using an ordered shutdown the admin can reduce the cluster size
+ automatically back to 3, but not below 3, where normal quorum
+ operation will work as usual.
+
+.fi
+.PP
+Example configuration:
+.nf
+
+quorum {
+ provider: corosync_votequorum
+ expected_votes: 3
+ allow_downscale: 1
+}
+.fi
+allow_downscale implicitly enabled EVT (see below).
+.PP
+.B expected_votes_tracking: 1
+.PP
+Enables Expected Votes Tracking (EVT) feature (default: 0).
+.PP
+Expected Votes Tracking stores the highest-seen value of expected votes on disk and uses
+that as the minimum value for expected votes in the absence of any higher authority (eg
+a current quorate cluster). This is useful for when a group of nodes becomes detached from
+the main cluster and after a restart could have enough votes to provide quorum, which can
+happen after using allow_downscale.
+.PP
+Note that even if the in-memory version of expected_votes is reduced, eg by removing nodes
+or using corosync-quorumtool, the stored value will still be the highest value seen - it
+never gets reduced.
+.PP
+The value is held in the file ev_tracking (stored in the directory configured in system.state_dir
+or /var/lib/corosync/ when unset) which can be deleted if you
+really do need to reduce the expected votes for any reason, like the node has been moved
+to a different cluster.
+.PP
+.fi
+.PP
+.SH VARIOUS NOTES
+.PP
+* WFA / LMS / ATB / AD can be used combined together.
+.PP
+* In order to change the default votes for a node there are two options:
+.nf
+
+1) nodelist:
+
+nodelist {
+ node {
+ ring0_addr: 192.168.1.1
+ quorum_votes: 3
+ }
+ ....
+}
+
+2) quorum section (deprecated):
+
+quorum {
+ provider: corosync_votequorum
+ expected_votes: 2
+ votes: 2
+}
+
+.fi
+In the event that both nodelist and quorum { votes: } are defined, the value
+from the nodelist will be used.
+.PP
+* Only votes, quorum_votes, expected_votes and two_node can be changed at runtime. Everything else
+requires a cluster restart.
+.SH BUGS
+No known bugs at the time of writing. The authors are from outerspace. Deal with it.
+.SH "SEE ALSO"
+.BR corosync (8),
+.BR corosync.conf (5),
+.BR corosync-quorumtool (8),
+.BR corosync-qdevice (8),
+.BR votequorum_overview (3)
+.PP
diff --git a/man/votequorum_context_get.3.in b/man/votequorum_context_get.3.in
new file mode 100644
index 0000000..6ac6bcc
--- /dev/null
+++ b/man/votequorum_context_get.3.in
@@ -0,0 +1,64 @@
+.\"/*
+.\" * Copyright (c) 2007,2012 Red Hat, Inc.
+.\" *
+.\" * All rights reserved.
+.\" *
+.\" * Author: Patrick Caulfield <pcaulfie@redhat.com>
+.\" *
+.\" * This software licensed under BSD license, the text of which follows:
+.\" *
+.\" * Redistribution and use in source and binary forms, with or without
+.\" * modification, are permitted provided that the following conditions are met:
+.\" *
+.\" * - Redistributions of source code must retain the above copyright notice,
+.\" * this list of conditions and the following disclaimer.
+.\" * - Redistributions in binary form must reproduce the above copyright notice,
+.\" * this list of conditions and the following disclaimer in the documentation
+.\" * and/or other materials provided with the distribution.
+.\" * - Neither the name of the MontaVista Software, Inc. nor the names of its
+.\" * contributors may be used to endorse or promote products derived from this
+.\" * software without specific prior written permission.
+.\" *
+.\" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+.\" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+.\" * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+.\" * THE POSSIBILITY OF SUCH DAMAGE.
+.\" */
+.TH VOTEQUORUM_CONTEXT_GET 3 @BUILDDATE@ "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
+.SH NAME
+votequorum_context_get \- Gets the context variable for a VOTEQUORUM instance
+.SH SYNOPSIS
+.B #include <corosync/votequorum.h>
+.sp
+.BI "int votequorum_context_get(votequorum_handle_t " handle ", void **" context ");"
+.SH DESCRIPTION
+The
+.B votequorum_context_get
+function is used to retrieve the context variable previously stored using
+.B votequorum_context_set(3)
+.SH RETURN VALUE
+This call returns the CS_OK value if successful, otherwise an error is returned.
+.PP
+.SH ERRORS
+@COMMONIPCERRORS@
+.SH "SEE ALSO"
+.BR votequorum_overview (3),
+.BR votequorum_initialize (3),
+.BR votequorum_finalize (3),
+.BR votequorum_getinfo (3),
+.BR votequorum_trackstart (3),
+.BR votequorum_trackstop (3),
+.BR votequorum_fd_get (3),
+.BR votequorum_dispatch (3),
+.BR votequorum_context_set (3),
+.BR votequorum_context_get (3),
+.BR votequorum_setexpected (3),
+.BR votequorum_setvotes (3)
+.PP
diff --git a/man/votequorum_context_set.3.in b/man/votequorum_context_set.3.in
new file mode 100644
index 0000000..5053e88
--- /dev/null
+++ b/man/votequorum_context_set.3.in
@@ -0,0 +1,66 @@
+.\"/*
+.\" * Copyright (c) 2007,2012 Red Hat, Inc.
+.\" *
+.\" * All rights reserved.
+.\" *
+.\" * Author: Patrick Caulfield <pcaulfie@redhat.com>
+.\" *
+.\" * This software licensed under BSD license, the text of which follows:
+.\" *
+.\" * Redistribution and use in source and binary forms, with or without
+.\" * modification, are permitted provided that the following conditions are met:
+.\" *
+.\" * - Redistributions of source code must retain the above copyright notice,
+.\" * this list of conditions and the following disclaimer.
+.\" * - Redistributions in binary form must reproduce the above copyright notice,
+.\" * this list of conditions and the following disclaimer in the documentation
+.\" * and/or other materials provided with the distribution.
+.\" * - Neither the name of the MontaVista Software, Inc. nor the names of its
+.\" * contributors may be used to endorse or promote products derived from this
+.\" * software without specific prior written permission.
+.\" *
+.\" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+.\" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+.\" * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+.\" * THE POSSIBILITY OF SUCH DAMAGE.
+.\" */
+.TH VOTEQUORUM_CONTEXT_SET 3 @BUILDDATE@ "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
+.SH NAME
+votequorum_context_set \- Sets the context variable for a VOTEQUORUM instance
+.SH SYNOPSIS
+.B #include <corosync/votequorum.h>
+.sp
+.BI "int votequorum_context_set(votequorum_handle_t " handle ", void *" context ");"
+.SH DESCRIPTION
+The
+.B votequorum_context_set
+function is used to set the context variable for a votequorum instance. It has no
+meaning inside libvotequorum itself and will not be touched by the library. It can
+be retrieved using
+.B votequorum_context_get(3)
+.SH RETURN VALUE
+This call returns the CS_OK value if successful, otherwise an error is returned.
+.PP
+.SH ERRORS
+@COMMONIPCERRORS@
+.SH "SEE ALSO"
+.BR votequorum_overview (3),
+.BR votequorum_initialize (3),
+.BR votequorum_finalize (3),
+.BR votequorum_getinfo (3),
+.BR votequorum_trackstart (3),
+.BR votequorum_trackstop (3),
+.BR votequorum_fd_get (3),
+.BR votequorum_dispatch (3),
+.BR votequorum_context_set (3),
+.BR votequorum_context_get (3),
+.BR votequorum_setexpected (3),
+.BR votequorum_setvotes (3)
+.PP
diff --git a/man/votequorum_dispatch.3.in b/man/votequorum_dispatch.3.in
new file mode 100644
index 0000000..10f4030
--- /dev/null
+++ b/man/votequorum_dispatch.3.in
@@ -0,0 +1,99 @@
+.\"/*
+.\" * Copyright (c) 2009,2012 Red Hat, Inc.
+.\" *
+.\" * All rights reserved.
+.\" *
+.\" * Author: Christine Caulfield <ccaulfie@redhat.com>
+.\" *
+.\" * This software licensed under BSD license, the text of which follows:
+.\" *
+.\" * Redistribution and use in source and binary forms, with or without
+.\" * modification, are permitted provided that the following conditions are met:
+.\" *
+.\" * - Redistributions of source code must retain the above copyright notice,
+.\" * this list of conditions and the following disclaimer.
+.\" * - Redistributions in binary form must reproduce the above copyright notice,
+.\" * this list of conditions and the following disclaimer in the documentation
+.\" * and/or other materials provided with the distribution.
+.\" * - Neither the name of the MontaVista Software, Inc. nor the names of its
+.\" * contributors may be used to endorse or promote products derived from this
+.\" * software without specific prior written permission.
+.\" *
+.\" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+.\" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+.\" * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+.\" * THE POSSIBILITY OF SUCH DAMAGE.
+.\" */
+.TH VOTEQUORUM_DISPATCH 3 @BUILDDATE@ "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
+.SH NAME
+votequorum_dispatch \- Dispatches callbacks from the votequorum service
+.SH SYNOPSIS
+.B #include <corosync/votequorum.h>
+.sp
+.BI "int votequorum_dispatch(votequorum_handle_t " handle ", cs_dispatch_flags_t *" dispatch_types ");"
+.SH DESCRIPTION
+The
+.B votequorum_dispatch
+function is used to dispatch configuration changes.
+.PP
+Each application may have several connections to the votequorum API. Each application
+uses the
+.I handle
+argument to uniquely identify the connection.
+.PP
+The
+.I dispatch_types
+argument is used to identify the type of dispatch to execute. The possible types are
+defined by the structure:
+
+.nf
+typedef enum {
+ CS_DISPATCH_ONE = 1,
+ CS_DISPATCH_ALL = 2,
+ CS_DISPATCH_BLOCKING = 3,
+ CS_DISPATCH_ONE_NONBLOCKING = 4
+} cs_dispatch_flags_t;
+.fi
+.PP
+The dispatch values have the following meanings:
+.TP
+.B CS_DISPATCH_ONE
+Dispatch at least one callback, blocking until the callback is dispatched.
+.TP
+.B CS_DISPATCH_ALL
+Dispatch all waiting callbacks without blocking to wait for any callbacks.
+.TP
+.B CS_DISPATCH_BLOCKING
+Dispatch all callbacks blocking indefinitely. This is used in a threaded
+program where a thread is created, and then quorum_dispatch() is called immediately
+from the created thread to execute callbacks.
+.TP
+.B CS_DISPATCH_ONE_NONBLOCKING
+Dispatch at most one callback. If there is no pending callback,
+CS_ERR_TRY_AGAIN is returned.
+
+.SH RETURN VALUE
+This call returns the CS_OK value if successful, otherwise an error is returned.
+.PP
+.SH ERRORS
+@COMMONIPCERRORS@
+.SH "SEE ALSO"
+.BR votequorum_overview (3),
+.BR votequorum_initialize (3),
+.BR votequorum_finalize (3),
+.BR votequorum_getinfo (3),
+.BR votequorum_trackstart (3),
+.BR votequorum_trackstop (3),
+.BR votequorum_fd_get (3),
+.BR votequorum_context_set (3),
+.BR votequorum_context_get (3),
+.BR votequorum_setexpected (3),
+.BR votequorum_setvotes (3)
+.PP
diff --git a/man/votequorum_fd_get.3.in b/man/votequorum_fd_get.3.in
new file mode 100644
index 0000000..352b25a
--- /dev/null
+++ b/man/votequorum_fd_get.3.in
@@ -0,0 +1,70 @@
+.\"/*
+.\" * Copyright (c) 2009,2012 Red Hat, Inc.
+.\" *
+.\" * All rights reserved.
+.\" *
+.\" * Author: Christine Caulfield <ccaulfie@redhat.com>
+.\" *
+.\" * This software licensed under BSD license, the text of which follows:
+.\" *
+.\" * Redistribution and use in source and binary forms, with or without
+.\" * modification, are permitted provided that the following conditions are met:
+.\" *
+.\" * - Redistributions of source code must retain the above copyright notice,
+.\" * this list of conditions and the following disclaimer.
+.\" * - Redistributions in binary form must reproduce the above copyright notice,
+.\" * this list of conditions and the following disclaimer in the documentation
+.\" * and/or other materials provided with the distribution.
+.\" * - Neither the name of the MontaVista Software, Inc. nor the names of its
+.\" * contributors may be used to endorse or promote products derived from this
+.\" * software without specific prior written permission.
+.\" *
+.\" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+.\" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+.\" * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+.\" * THE POSSIBILITY OF SUCH DAMAGE.
+.\" */
+.TH VOTEQUORUM_FD_GET 3 @BUILDDATE@ "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
+.SH NAME
+votequorum_fd_get \- Dispatches callbacks from the votequorum service
+.SH SYNOPSIS
+.B #include <corosync/votequorum.h>
+.sp
+.BI "int votequorum_fd_get(votequorum_handle_t " handle ", int *" fd ");"
+.SH DESCRIPTION
+The
+.B votequorum_fd_get
+function is used to retrieve the file descriptor that may be used with the poll
+system call to determine when
+.B votequorum_dispatch(3)
+won't block. The
+.I handle
+argument may not be used directly with
+.B poll
+because it is not the file descriptor, but instead an internal identifier used
+by the votequorum library.
+.SH RETURN VALUE
+This call returns the CS_OK value if successful, otherwise an error is returned.
+.PP
+.SH ERRORS
+@COMMONIPCERRORS@
+.SH "SEE ALSO"
+.BR votequorum_overview (3),
+.BR votequorum_initialize (3),
+.BR votequorum_finalize (3),
+.BR votequorum_getinfo (3),
+.BR votequorum_trackstart (3),
+.BR votequorum_trackstop (3),
+.BR votequorum_dispatch (3),
+.BR votequorum_context_set (3),
+.BR votequorum_context_get (3),
+.BR votequorum_setexpected (3),
+.BR votequorum_setvotes (3)
+.PP
diff --git a/man/votequorum_finalize.3.in b/man/votequorum_finalize.3.in
new file mode 100644
index 0000000..fccd729
--- /dev/null
+++ b/man/votequorum_finalize.3.in
@@ -0,0 +1,67 @@
+.\"/*
+.\" * Copyright (c) 2009,2012 Red Hat, Inc.
+.\" *
+.\" * All rights reserved.
+.\" *
+.\" * Author: Christine Caulfield <ccaulfie@redhat.com>
+.\" *
+.\" * This software licensed under BSD license, the text of which follows:
+.\" *
+.\" * Redistribution and use in source and binary forms, with or without
+.\" * modification, are permitted provided that the following conditions are met:
+.\" *
+.\" * - Redistributions of source code must retain the above copyright notice,
+.\" * this list of conditions and the following disclaimer.
+.\" * - Redistributions in binary form must reproduce the above copyright notice,
+.\" * this list of conditions and the following disclaimer in the documentation
+.\" * and/or other materials provided with the distribution.
+.\" * - Neither the name of the MontaVista Software, Inc. nor the names of its
+.\" * contributors may be used to endorse or promote products derived from this
+.\" * software without specific prior written permission.
+.\" *
+.\" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+.\" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+.\" * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+.\" * THE POSSIBILITY OF SUCH DAMAGE.
+.\" */
+.TH VOTEQUORUM_FINALIZE 3 @BUILDDATE@ "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
+.SH NAME
+votequorum_finalize \- Terminate a connection to the votequorum service
+.SH SYNOPSIS
+.B #include <corosync/votequorum.h>
+.sp
+.BI "int votequorum_finalize(votequorum_handle_t " handle ");"
+.SH DESCRIPTION
+The
+.B votequorum_finalize
+function is used to close a connection to the configuration database API.
+Once the connection is finalized, the handle may not be used again by applications.
+No more callbacks will be dispatched from the
+.B votequorum_dispatch
+function.
+.PP
+.SH RETURN VALUE
+This call returns the CS_OK value if successful, otherwise an error is returned.
+.PP
+.SH ERRORS
+@COMMONIPCERRORS@
+.SH "SEE ALSO"
+.BR votequorum_overview (3),
+.BR votequorum_initialize (3),
+.BR votequorum_getinfo (3),
+.BR votequorum_trackstart (3),
+.BR votequorum_trackstop (3),
+.BR votequorum_fd_get (3),
+.BR votequorum_dispatch (3),
+.BR votequorum_context_set (3),
+.BR votequorum_context_get (3),
+.BR votequorum_setexpected (3),
+.BR votequorum_setvotes (3)
+.PP
diff --git a/man/votequorum_getinfo.3.in b/man/votequorum_getinfo.3.in
new file mode 100644
index 0000000..8e15690
--- /dev/null
+++ b/man/votequorum_getinfo.3.in
@@ -0,0 +1,111 @@
+.\"/*
+.\" * Copyright (c) 2009,2012 Red Hat, Inc.
+.\" *
+.\" * All rights reserved.
+.\" *
+.\" * Author: Christine Caulfield <ccaulfie@redhat.com>
+.\" *
+.\" * This software licensed under BSD license, the text of which follows:
+.\" *
+.\" * Redistribution and use in source and binary forms, with or without
+.\" * modification, are permitted provided that the following conditions are met:
+.\" *
+.\" * - Redistributions of source code must retain the above copyright notice,
+.\" * this list of conditions and the following disclaimer.
+.\" * - Redistributions in binary form must reproduce the above copyright notice,
+.\" * this list of conditions and the following disclaimer in the documentation
+.\" * and/or other materials provided with the distribution.
+.\" * - Neither the name of the MontaVista Software, Inc. nor the names of its
+.\" * contributors may be used to endorse or promote products derived from this
+.\" * software without specific prior written permission.
+.\" *
+.\" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+.\" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+.\" * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+.\" * THE POSSIBILITY OF SUCH DAMAGE.
+.\" */
+.TH VOTEQUORUM_GETINFO 3 @BUILDDATE@ "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
+.SH NAME
+votequorum_getinfo \- Get information about the VoteQuorum service
+.SH SYNOPSIS
+.B #include <corosync/votequorum.h>
+.sp
+.BI "int votequorum_getinfo(votequorum_handle_t *" handle ", unsigned int " nodeid ", struct votequorum_info *" info ");"
+.SH DESCRIPTION
+The
+.B votequorum_getinfo
+function is used to get information about the voting system and its nodes.
+
+The
+.I nodeid
+argument indicates which node information should be stored in the votequorum_info structure.
+
+The votequorum_info structure is defined as follows:
+
+.nf
+
+struct votequorum_info {
+ unsigned int node_id;
+ unsigned int node_state;
+ unsigned int node_votes;
+ unsigned int node_expected_votes;
+ unsigned int highest_expected;
+ unsigned int total_votes;
+ unsigned int quorum;
+ unsigned int flags;
+ unsigned int qdevice_votes;
+ char qdevice_name[VOTEQUORUM_QDEVICE_MAX_NAME_LEN];
+};
+
+.fi
+The node_state is defined as:
+.nf
+
+#define VOTEQUORUM_NODESTATE_MEMBER 1
+#define VOTEQUORUM_NODESTATE_DEAD 2
+#define VOTEQUORUM_NODESTATE_LEAVING 3
+
+.fi
+The flags are defined as:
+.nf
+
+#define VOTEQUORUM_INFO_TWONODE 1
+#define VOTEQUORUM_INFO_QUORATE 2
+#define VOTEQUORUM_INFO_WAIT_FOR_ALL 4
+#define VOTEQUORUM_INFO_LAST_MAN_STANDING 8
+#define VOTEQUORUM_INFO_AUTO_TIE_BREAKER 16
+#define VOTEQUORUM_INFO_ALLOW_DOWNSCALE 32
+#define VOTEQUORUM_INFO_QDEVICE_REGISTERED 64
+#define VOTEQUORUM_INFO_QDEVICE_ALIVE 128
+#define VOTEQUORUM_INFO_QDEVICE_CAST_VOTE 256
+#define VOTEQUORUM_INFO_QDEVICE_MASTER_WINS 512
+
+.fi
+.PP
+The members starting node_ hold information specific to the requested nodeid, the other are
+general to the voting system.
+.SH RETURN VALUE
+This call returns the CS_OK value if successful, otherwise a generic error is returned.
+.PP
+.SH ERRORS
+@COMMONIPCERRORS@
+.SH "SEE ALSO"
+.BR votequorum_overview (3),
+.BR votequorum_initialize (3),
+.BR votequorum_finalize (3),
+.BR votequorum_trackstart (3),
+.BR votequorum_trackstop (3),
+.BR votequorum_fd_get (3),
+.BR votequorum_dispatch (3),
+.BR votequorum_context_set (3),
+.BR votequorum_context_get (3),
+.BR votequorum_setexpected (3),
+.BR votequorum_setvotes (3)
+.PP
diff --git a/man/votequorum_initialize.3.in b/man/votequorum_initialize.3.in
new file mode 100644
index 0000000..be7f3f1
--- /dev/null
+++ b/man/votequorum_initialize.3.in
@@ -0,0 +1,139 @@
+.\"/*
+.\" * Copyright (c) 2009,2012 Red Hat, Inc.
+.\" *
+.\" * All rights reserved.
+.\" *
+.\" * Author: Christine Caulfield <ccaulfie@redhat.com>
+.\" *
+.\" * This software licensed under BSD license, the text of which follows:
+.\" *
+.\" * Redistribution and use in source and binary forms, with or without
+.\" * modification, are permitted provided that the following conditions are met:
+.\" *
+.\" * - Redistributions of source code must retain the above copyright notice,
+.\" * this list of conditions and the following disclaimer.
+.\" * - Redistributions in binary form must reproduce the above copyright notice,
+.\" * this list of conditions and the following disclaimer in the documentation
+.\" * and/or other materials provided with the distribution.
+.\" * - Neither the name of the MontaVista Software, Inc. nor the names of its
+.\" * contributors may be used to endorse or promote products derived from this
+.\" * software without specific prior written permission.
+.\" *
+.\" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+.\" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+.\" * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+.\" * THE POSSIBILITY OF SUCH DAMAGE.
+.\" */
+.TH VOTEQUORUM_INITIALIZE 3 @BUILDDATE@ "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
+.SH NAME
+votequorum_initialize \- Create a new connection to the VoteQuorum service
+.SH SYNOPSIS
+.B #include <corosync/votequorum.h>
+.sp
+.BI "int votequorum_initialize(votequorum_handle_t *" handle ", votequorum_callbacks_t *" callbacks ");"
+.SH DESCRIPTION
+The
+.B votequorum_initialize
+function is used to initialize a connection to the vote-based quorum database API.
+.PP
+Each application may have several connections to the votequorum API. Each application
+uses the
+.I handle
+argument to uniquely identify the connection. The
+.I handle
+argument is then used in other function calls to identify the connection to be used
+for communication with the votequorum service.
+.PP
+Every time the voting configuration is about to change (eg a node joins or leave the cluster), the callback is called.
+The callback function is described by the following type definitions:
+
+.nf
+typedef void (*votequorum_nodelist_notification_fn_t) (
+ votequorum_handle_t handle,
+ uint64_t context,
+ uint32_t node_list_entries,
+ uint32_t node_list[]
+ );
+
+.fi
+
+Current ring_id (one get in votequorum_quorum_notification_fn) must be passed to
+.B votequorum_qdevice_poll
+to make qdevice voting valid.
+
+.PP
+Every time the quorum state changes (eg a node joins or leave the cluster), the callback is called.
+The callback function is described by the following type definitions:
+
+.nf
+typedef void (*votequorum_quorum_notification_fn_t) (
+ votequorum_handle_t handle,
+ uint64_t context,
+ uint32_t quorate,
+ uint32_t node_list_entries,
+ votequorum_node_t node_list[]
+ );
+
+.fi
+
+The difference between votequorum_nodelist_notification_t and votequorum_quorum_notification_t is subtle but important.
+The 'nodelist' callback is sent at the start of a cluster state transition and contains the new ring_id and only the list of
+nodes that are included in the sync state - ie only active nodes. No quorum information is included this callback
+because it is not available at that time.
+The 'quorum' callback is sent after the cluster state transition has completed and does contain quorum information.
+In addition, the nodelist contains a list of all nodes known to votequorum (whether up or down) and their state as well
+as information about the quorum device attached (if any). Quorum callbacks will not be sent for qdevice up and down
+events unless they affect quorum.
+
+.PP
+Every time the expected votes are changed, the callback is called.
+The expected votes callback function is described by the following type definitions:
+
+.nf
+typedef void (*votequorum_expectedvotes_notification_fn_t) (
+ votequorum_handle_t handle,
+ uint64_t context,
+ uint32_t expected_votes);
+.fi
+.PP
+The
+.I callbacks
+argument is of the type:
+
+.nf
+typedef struct {
+ votequorum_quorum_notification_fn_t votequorum_quorum_notify_fn;
+ votequorum_expectedvotes_notification_fn_t votequorum_expectedvotes_notify_fn;
+ votequorum_nodelist_notification_fn_t votequorum_nodelist_notify_fn;
+} votequorum_callbacks_t;
+.fi
+.PP
+When a configuration change occurs, the callback
+is called from the
+.B votequorum_dispatch()
+function.
+.PP
+.SH RETURN VALUE
+This call returns the CS_OK value if successful, otherwise an error is returned.
+.SH ERRORS
+@COMMONIPCERRORS@
+.SH "SEE ALSO"
+.BR votequorum_overview (3),
+.BR votequorum_finalize (3),
+.BR votequorum_getinfo (3),
+.BR votequorum_trackstart (3),
+.BR votequorum_trackstop (3),
+.BR votequorum_fd_get (3),
+.BR votequorum_dispatch (3),
+.BR votequorum_context_set (3),
+.BR votequorum_context_get (3),
+.BR votequorum_setexpected (3),
+.BR votequorum_setvotes (3)
+.PP
diff --git a/man/votequorum_overview.3 b/man/votequorum_overview.3
new file mode 100644
index 0000000..4ec1b75
--- /dev/null
+++ b/man/votequorum_overview.3
@@ -0,0 +1,84 @@
+.\"/*
+.\" * Copyright (c) 2008, 2012 Red Hat, Inc.
+.\" *
+.\" * All rights reserved.
+.\" *
+.\" * Authors: Christine Caulfield <ccaulfie@redhat.com>
+.\" * Fabio M. Di Nitto <fdinitto@redhat.com>
+.\" *
+.\" * This software licensed under BSD license, the text of which follows:
+.\" *
+.\" * Redistribution and use in source and binary forms, with or without
+.\" * modification, are permitted provided that the following conditions are met:
+.\" *
+.\" * - Redistributions of source code must retain the above copyright notice,
+.\" * this list of conditions and the following disclaimer.
+.\" * - Redistributions in binary form must reproduce the above copyright notice,
+.\" * this list of conditions and the following disclaimer in the documentation
+.\" * and/or other materials provided with the distribution.
+.\" * - Neither the name of the MontaVista Software, Inc. nor the names of its
+.\" * contributors may be used to endorse or promote products derived from this
+.\" * software without specific prior written permission.
+.\" *
+.\" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+.\" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+.\" * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+.\" * THE POSSIBILITY OF SUCH DAMAGE.
+.\" */
+.TH VOTEQUORUM_OVERVIEW 3 2012-01-12 "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
+.SH NAME
+votequorum_overview \- Votequorum Library Overview
+.SH OVERVIEW
+The votequorum library is delivered with the corosync project. It is the external interface to
+the vote-based quorum service. This service is optionally loaded into all nodes in a corosync cluster
+to avoid split-brain situations. It does this by having a number of votes assigned to each system
+in the cluster and ensuring that only when a majority of the votes are present, cluster operations are
+allowed to proceed.
+.PP
+The library provides a mechanism to:
+.PP
+* Query the quorum status
+.PP
+* Get a list of nodes known to the quorum service
+.PP
+* Receive notifications of quorum state changes
+.PP
+* Change the number of votes assigned to a node
+.PP
+* Change the number of expected votes for a cluster to be quorate
+.PP
+* Connect an additional quorum device to allow small clusters to remain quorate during node outages.
+.PP
+.SH VIRTUAL SYNCHRONY
+Votequorum is the only one service where communication with library is allowed during synchronization
+phase. This makes it possible for quorum device to react to membership change and decide to vote or
+not without timing hazard, because corosync stands in synchronization phase until qdevice on all
+nodes votes or timeout expires.
+
+As a side effect, extended virtual synchrony is broken for the votequorum service. This means, that
+messages sent during synchronization phase can be delivered sooner then messages sent right
+before sync phase began. This applies also for local messages.
+.SH BUGS
+No known bugs at the time of writing. The authors are from outerspace. Deal with it.
+.SH "SEE ALSO"
+.BR corosync-quorumtool (8),
+.BR votequorum (5),
+.BR votequorum_initialize (3),
+.BR votequorum_finalize (3),
+.BR votequorum_getinfo (3),
+.BR votequorum_trackstart (3),
+.BR votequorum_trackstop (3),
+.BR votequorum_fd_get (3),
+.BR votequorum_dispatch (3),
+.BR votequorum_context_set (3),
+.BR votequorum_context_get (3),
+.BR votequorum_setexpected (3),
+.BR votequorum_setvotes (3)
+.PP
diff --git a/man/votequorum_qdevice_master_wins.3.in b/man/votequorum_qdevice_master_wins.3.in
new file mode 100644
index 0000000..4be1aa0
--- /dev/null
+++ b/man/votequorum_qdevice_master_wins.3.in
@@ -0,0 +1,77 @@
+.\"/*
+.\" * Copyright (c) 2014 Red Hat, Inc.
+.\" *
+.\" * All rights reserved.
+.\" *
+.\" * Author: Christine Caulfield <ccaulfie@redhat.com>
+.\" *
+.\" * This software licensed under BSD license, the text of which follows:
+.\" *
+.\" * Redistribution and use in source and binary forms, with or without
+.\" * modification, are permitted provided that the following conditions are met:
+.\" *
+.\" * - Redistributions of source code must retain the above copyright notice,
+.\" * this list of conditions and the following disclaimer.
+.\" * - Redistributions in binary form must reproduce the above copyright notice,
+.\" * this list of conditions and the following disclaimer in the documentation
+.\" * and/or other materials provided with the distribution.
+.\" * - Neither the name of the MontaVista Software, Inc. nor the names of its
+.\" * contributors may be used to endorse or promote products derived from this
+.\" * software without specific prior written permission.
+.\" *
+.\" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+.\" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+.\" * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+.\" * THE POSSIBILITY OF SUCH DAMAGE.
+.\" */
+.TH VOTEQUORUM_QDEVICE_MASTER_WINS 3 @BUILDDATE@ "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
+.SH NAME
+votequorum_qdevice_master_wins \- Sets or clears quorum device master_wins flag
+.SH SYNOPSIS
+.B #include <corosync/votequorum.h>
+.sp
+.BI "int votequorum_qdevice_master_wins(votequorum_handle_t " handle " const char " name ", unsigned int " allow ");"
+.SH DESCRIPTION
+The
+.B votequorum_qdevice_master_wins
+informs votequorum whether or not the currently registered qdevice subsystem supports 'master_wins' mode (default 0).
+This mode allows the qdevice to effectively take over the quorum calculations of votequorum. Any node with an active
+qdevice that also has master_wins set becomes quorate regardless of the node votes of the cluster. It is left up to the
+qdevice subsystem itself (not part of votequorum) to communicate across the nodes or otherwise provide some system of
+deciding which nodes will be part of the quorate cluster, if any. eg They may be the set of nodes that has access to
+a quorum disk.
+.br
+.B name
+The name of the currently registered quorum device on this node. This must match the existing name known to votequorum.
+.br
+.B allow
+0 (the default) means that master_wins is not active on this node. 1 means that master_wins is active on this node.
+.SH RETURN VALUE
+This call returns the CS_OK value if successful, otherwise an error is returned.
+.PP
+.SH ERRORS
+@COMMONIPCERRORS@
+.SH "SEE ALSO"
+.BR votequorum_overview (3),
+.BR votequorum_initialize (3),
+.BR votequorum_finalize (3),
+.BR votequorum_getinfo (3),
+.BR votequorum_trackstart (3),
+.BR votequorum_trackstop (3),
+.BR votequorum_fd_get (3),
+.BR votequorum_dispatch (3),
+.BR votequorum_context_set (3),
+.BR votequorum_context_get (3),
+.BR votequorum_setexpected (3),
+.BR votequorum_setvotes (3),
+.BR votequorum_qdevice_register (3),
+.BR votequorum_qdevice_poll (3),
+.BR votequorum_qdevice_update (3),
+.PP
diff --git a/man/votequorum_qdevice_poll.3.in b/man/votequorum_qdevice_poll.3.in
new file mode 100644
index 0000000..c39969e
--- /dev/null
+++ b/man/votequorum_qdevice_poll.3.in
@@ -0,0 +1,83 @@
+.\"/*
+.\" * Copyright (c) 2009,2012,2014 Red Hat, Inc.
+.\" *
+.\" * All rights reserved.
+.\" *
+.\" * Author: Christine Caulfield <ccaulfie@redhat.com>
+.\" *
+.\" * This software licensed under BSD license, the text of which follows:
+.\" *
+.\" * Redistribution and use in source and binary forms, with or without
+.\" * modification, are permitted provided that the following conditions are met:
+.\" *
+.\" * - Redistributions of source code must retain the above copyright notice,
+.\" * this list of conditions and the following disclaimer.
+.\" * - Redistributions in binary form must reproduce the above copyright notice,
+.\" * this list of conditions and the following disclaimer in the documentation
+.\" * and/or other materials provided with the distribution.
+.\" * - Neither the name of the MontaVista Software, Inc. nor the names of its
+.\" * contributors may be used to endorse or promote products derived from this
+.\" * software without specific prior written permission.
+.\" *
+.\" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+.\" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+.\" * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+.\" * THE POSSIBILITY OF SUCH DAMAGE.
+.\" */
+.TH VOTEQUORUM_QDEVICE_POLL 3 @BUILDDATE@ "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
+.SH NAME
+votequorum_qdevice_poll \- Tells votequorum the result of the quorum device poll
+.SH SYNOPSIS
+.B #include <corosync/votequorum.h>
+.sp
+.BI "int votequorum_qdevice_poll(votequorum_handle_t " handle ", const char * " name ", unsigned int " cast_vote ", votequorum_ring_id_t " ring_id ");"
+.SH DESCRIPTION
+The
+.B votequorum_qdevice_poll
+is called by the quorum device subsystem (not provided as part of votequorum) to tell
+the voting system if the quorum device is present/active or not. If
+.B cast_vote
+is 1 then the votes for the device are included in the quorum calculation, otherwise not.
+Current
+.B ring_id
+must be set (one get in votequorum_notification_fn callback) otherwise poll is ignored.
+This routine should be called at regular intervals to ensure that the device status
+is always known to votequorum. If
+.B votequorum_qdevice_poll
+is not called for (default) 10 seconds (or 30 seconds for sync phase) then the device will be deemed to be dead and
+its votes removed from the cluster. This does not unregister the device.
+The default poll time can be changed by setting the cmap variable
+.B quorum.device.timeout
+for normal operation or
+.B quorum.device.sync_timeout
+for synchronization phase.
+.SH RETURN VALUE
+This call returns the CS_OK value if successful, otherwise an error is returned.
+.PP
+.SH ERRORS
+@COMMONIPCERRORS@
+.SH "SEE ALSO"
+.BR votequorum_overview (3),
+.BR votequorum_initialize (3),
+.BR votequorum_finalize (3),
+.BR votequorum_getinfo (3),
+.BR votequorum_trackstart (3),
+.BR votequorum_trackstop (3),
+.BR votequorum_fd_get (3),
+.BR votequorum_dispatch (3),
+.BR votequorum_context_set (3),
+.BR votequorum_context_get (3),
+.BR votequorum_setexpected (3),
+.BR votequorum_setvotes (3),
+.BR votequorum_qdevice_register (3),
+.BR votequorum_qdevice_unregister (3),
+.BR votequorum_qdevice_update (3),
+.BR votequorum_qdevice_master_wins (3),
+.PP
diff --git a/man/votequorum_qdevice_register.3.in b/man/votequorum_qdevice_register.3.in
new file mode 100644
index 0000000..48393d9
--- /dev/null
+++ b/man/votequorum_qdevice_register.3.in
@@ -0,0 +1,83 @@
+.\"/*
+.\" * Copyright (c) 2009,2012,2014 Red Hat, Inc.
+.\" *
+.\" * All rights reserved.
+.\" *
+.\" * Author: Christine Caulfield <ccaulfie@redhat.com>
+.\" *
+.\" * This software licensed under BSD license, the text of which follows:
+.\" *
+.\" * Redistribution and use in source and binary forms, with or without
+.\" * modification, are permitted provided that the following conditions are met:
+.\" *
+.\" * - Redistributions of source code must retain the above copyright notice,
+.\" * this list of conditions and the following disclaimer.
+.\" * - Redistributions in binary form must reproduce the above copyright notice,
+.\" * this list of conditions and the following disclaimer in the documentation
+.\" * and/or other materials provided with the distribution.
+.\" * - Neither the name of the MontaVista Software, Inc. nor the names of its
+.\" * contributors may be used to endorse or promote products derived from this
+.\" * software without specific prior written permission.
+.\" *
+.\" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+.\" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+.\" * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+.\" * THE POSSIBILITY OF SUCH DAMAGE.
+.\" */
+.TH VOTEQUORUM_QDEVICE_REGISTER 3 @BUILDDATE@ "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
+.SH NAME
+votequorum_qdevice_register \- Registers a new quorum device
+.SH SYNOPSIS
+.B #include <corosync/votequorum.h>
+.sp
+.BI "int votequorum_qdevice_register(votequorum_handle_t " handle ", const char * " name ");"
+.SH DESCRIPTION
+The
+.B votequorum_qdevice_register
+is used to register a new quorum device. A quorum device is an external way of adding votes to a small
+cluster. The quorum device is, in effect, a pseudo node in the cluster that provide votes based on some
+external device, usually a shared disk partition or perhaps a network router.
+.br
+This call creates the device but does not mark it active.
+.B votequorum_qdevice_poll
+must be called for the votes to be included in the quorum calculation.
+.br
+.B name
+is string containing an informative name for the quorum device. It is simply stored
+by votequorum and used in the display of corosync-quorumtool, it can be a maximum of 254 characters.
+.br
+The number of votes contributed by the quorum device is already known to votequorum, it is set in cmap
+quorum.device.votes and not by the device.
+.br
+Note that it is the responsibility of the quorum device subsystem (not provided as part of votequorum)
+to keep all nodes informed of the quorum device status.
+.SH RETURN VALUE
+This call returns the CS_OK value if successful, otherwise an error is returned.
+.PP
+.SH ERRORS
+@COMMONIPCERRORS@
+.SH "SEE ALSO"
+.BR votequorum_overview (3),
+.BR votequorum_initialize (3),
+.BR votequorum_finalize (3),
+.BR votequorum_getinfo (3),
+.BR votequorum_trackstart (3),
+.BR votequorum_trackstop (3),
+.BR votequorum_fd_get (3),
+.BR votequorum_dispatch (3),
+.BR votequorum_context_set (3),
+.BR votequorum_context_get (3),
+.BR votequorum_setexpected (3),
+.BR votequorum_setvotes (3),
+.BR votequorum_qdevice_unregister (3),
+.BR votequorum_qdevice_poll (3),
+.BR votequorum_qdevice_update (3),
+.BR votequorum_qdevice_master_wins (3)
+.PP
diff --git a/man/votequorum_qdevice_unregister.3.in b/man/votequorum_qdevice_unregister.3.in
new file mode 100644
index 0000000..311466e
--- /dev/null
+++ b/man/votequorum_qdevice_unregister.3.in
@@ -0,0 +1,68 @@
+.\"/*
+.\" * Copyright (c) 2009,2012,2014 Red Hat, Inc.
+.\" *
+.\" * All rights reserved.
+.\" *
+.\" * Author: Christine Caulfield <ccaulfie@redhat.com>
+.\" *
+.\" * This software licensed under BSD license, the text of which follows:
+.\" *
+.\" * Redistribution and use in source and binary forms, with or without
+.\" * modification, are permitted provided that the following conditions are met:
+.\" *
+.\" * - Redistributions of source code must retain the above copyright notice,
+.\" * this list of conditions and the following disclaimer.
+.\" * - Redistributions in binary form must reproduce the above copyright notice,
+.\" * this list of conditions and the following disclaimer in the documentation
+.\" * and/or other materials provided with the distribution.
+.\" * - Neither the name of the MontaVista Software, Inc. nor the names of its
+.\" * contributors may be used to endorse or promote products derived from this
+.\" * software without specific prior written permission.
+.\" *
+.\" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+.\" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+.\" * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+.\" * THE POSSIBILITY OF SUCH DAMAGE.
+.\" */
+.TH VOTEQUORUM_QDEVICE_UNREGISTER 3 @BUILDDATE@ "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
+.SH NAME
+votequorum_qdevice_unregister \- Unregisters a new quorum device
+.SH SYNOPSIS
+.B #include <corosync/votequorum.h>
+.sp
+.BI "int votequorum_qdevice_unregister(votequorum_handle_t " handle ", const char * " name ");"
+.SH DESCRIPTION
+The
+.B votequorum_qdevice_unregister
+unregisters a quorum device. Any votes it had will be removed from the cluster. NOTE that this could
+make the cluster inquorate.
+.SH RETURN VALUE
+This call returns the CS_OK value if successful, otherwise an error is returned.
+.PP
+.SH ERRORS
+@COMMONIPCERRORS@
+.SH "SEE ALSO"
+.BR votequorum_overview (3),
+.BR votequorum_initialize (3),
+.BR votequorum_finalize (3),
+.BR votequorum_getinfo (3),
+.BR votequorum_trackstart (3),
+.BR votequorum_trackstop (3),
+.BR votequorum_fd_get (3),
+.BR votequorum_dispatch (3),
+.BR votequorum_context_set (3),
+.BR votequorum_context_get (3),
+.BR votequorum_setexpected (3),
+.BR votequorum_setvotes (3),
+.BR votequorum_qdevice_register (3),
+.BR votequorum_qdevice_poll (3),
+.BR votequorum_qdevice_update (3),
+.BR votequorum_qdevice_master_wins (3)
+.PP
diff --git a/man/votequorum_qdevice_update.3.in b/man/votequorum_qdevice_update.3.in
new file mode 100644
index 0000000..a75357e
--- /dev/null
+++ b/man/votequorum_qdevice_update.3.in
@@ -0,0 +1,69 @@
+.\"/*
+.\" * Copyright (c) 2014 Red Hat, Inc.
+.\" *
+.\" * All rights reserved.
+.\" *
+.\" * Author: Christine Caulfield <ccaulfie@redhat.com>
+.\" *
+.\" * This software licensed under BSD license, the text of which follows:
+.\" *
+.\" * Redistribution and use in source and binary forms, with or without
+.\" * modification, are permitted provided that the following conditions are met:
+.\" *
+.\" * - Redistributions of source code must retain the above copyright notice,
+.\" * this list of conditions and the following disclaimer.
+.\" * - Redistributions in binary form must reproduce the above copyright notice,
+.\" * this list of conditions and the following disclaimer in the documentation
+.\" * and/or other materials provided with the distribution.
+.\" * - Neither the name of the MontaVista Software, Inc. nor the names of its
+.\" * contributors may be used to endorse or promote products derived from this
+.\" * software without specific prior written permission.
+.\" *
+.\" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+.\" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+.\" * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+.\" * THE POSSIBILITY OF SUCH DAMAGE.
+.\" */
+.TH VOTEQUORUM_QDEVICE_UPDATE 3 @BUILDDATE@ "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
+.SH NAME
+votequorum_qdevice_update \- Updates quorum device name
+.SH SYNOPSIS
+.B #include <corosync/votequorum.h>
+.sp
+.BI "int votequorum_qdevice_update(votequorum_handle_t " handle "const char " oldname ", const char " newname ");"
+.SH DESCRIPTION
+The
+.B votequorum_qdevice_update
+is used to change the name of the quorum device to corosync. The name of q quorum device is purely informational
+and has no significance to votequorum itself, but it's useful for the name (displayed by corosync-quorumtool)
+to reflect the actual device contributing votes to quorum to avoid user confusion.
+.SH RETURN VALUE
+This call returns the CS_OK value if successful, otherwise an error is returned.
+.PP
+.SH ERRORS
+@COMMONIPCERRORS@
+.SH "SEE ALSO"
+.BR votequorum_overview (3),
+.BR votequorum_initialize (3),
+.BR votequorum_finalize (3),
+.BR votequorum_getinfo (3),
+.BR votequorum_trackstart (3),
+.BR votequorum_trackstop (3),
+.BR votequorum_fd_get (3),
+.BR votequorum_dispatch (3),
+.BR votequorum_context_set (3),
+.BR votequorum_context_get (3),
+.BR votequorum_setexpected (3),
+.BR votequorum_setvotes (3),
+.BR votequorum_qdevice_register (3),
+.BR votequorum_qdevice_poll (3),
+.BR votequorum_qdevice_master_wins (3),
+.BR corosync-quorumtool (8)
+.PP
diff --git a/man/votequorum_setexpected.3.in b/man/votequorum_setexpected.3.in
new file mode 100644
index 0000000..0cc4069
--- /dev/null
+++ b/man/votequorum_setexpected.3.in
@@ -0,0 +1,66 @@
+.\"/*
+.\" * Copyright (c) 2009,2012 Red Hat, Inc.
+.\" *
+.\" * All rights reserved.
+.\" *
+.\" * Author: Christine Caulfield <ccaulfie@redhat.com>
+.\" *
+.\" * This software licensed under BSD license, the text of which follows:
+.\" *
+.\" * Redistribution and use in source and binary forms, with or without
+.\" * modification, are permitted provided that the following conditions are met:
+.\" *
+.\" * - Redistributions of source code must retain the above copyright notice,
+.\" * this list of conditions and the following disclaimer.
+.\" * - Redistributions in binary form must reproduce the above copyright notice,
+.\" * this list of conditions and the following disclaimer in the documentation
+.\" * and/or other materials provided with the distribution.
+.\" * - Neither the name of the MontaVista Software, Inc. nor the names of its
+.\" * contributors may be used to endorse or promote products derived from this
+.\" * software without specific prior written permission.
+.\" *
+.\" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+.\" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+.\" * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+.\" * THE POSSIBILITY OF SUCH DAMAGE.
+.\" */
+.TH VOTEQUORUM_SETEXPECTED 3 @BUILDDATE@ "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
+.SH NAME
+votequorum_setexpected \- Sets the expected votes for the cluster
+.SH SYNOPSIS
+.B #include <corosync/votequorum.h>
+.sp
+.BI "int votequorum_setexpected(votequorum_handle_t " handle ", int " expected_votes ");"
+.SH DESCRIPTION
+The
+.B votequorum_setexpected
+function is used to change the expected votes in the cluster. Expected votes is used to calculate
+quorum and should normally be the total number of votes that will exist when all the expected nodes
+are joined. Quorum will usually be half of this (rounded up).
+.BR
+It is not possible to set expected votes up so that it makes the cluster inquorate using this command.
+.SH RETURN VALUE
+This call returns the CS_OK value if successful, otherwise an error is returned.
+.PP
+.SH ERRORS
+@COMMONIPCERRORS@
+.SH "SEE ALSO"
+.BR votequorum_overview (3),
+.BR votequorum_initialize (3),
+.BR votequorum_finalize (3),
+.BR votequorum_getinfo (3),
+.BR votequorum_trackstart (3),
+.BR votequorum_trackstop (3),
+.BR votequorum_fd_get (3),
+.BR votequorum_dispatch (3),
+.BR votequorum_context_set (3),
+.BR votequorum_context_get (3),
+.BR votequorum_setvotes (3)
+.PP
diff --git a/man/votequorum_setvotes.3.in b/man/votequorum_setvotes.3.in
new file mode 100644
index 0000000..cc7b434
--- /dev/null
+++ b/man/votequorum_setvotes.3.in
@@ -0,0 +1,63 @@
+.\"/*
+.\" * Copyright (c) 2009,2012 Red Hat, Inc.
+.\" *
+.\" * All rights reserved.
+.\" *
+.\" * Author: Christine Caulfield <ccaulfie@redhat.com>
+.\" *
+.\" * This software licensed under BSD license, the text of which follows:
+.\" *
+.\" * Redistribution and use in source and binary forms, with or without
+.\" * modification, are permitted provided that the following conditions are met:
+.\" *
+.\" * - Redistributions of source code must retain the above copyright notice,
+.\" * this list of conditions and the following disclaimer.
+.\" * - Redistributions in binary form must reproduce the above copyright notice,
+.\" * this list of conditions and the following disclaimer in the documentation
+.\" * and/or other materials provided with the distribution.
+.\" * - Neither the name of the MontaVista Software, Inc. nor the names of its
+.\" * contributors may be used to endorse or promote products derived from this
+.\" * software without specific prior written permission.
+.\" *
+.\" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+.\" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+.\" * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+.\" * THE POSSIBILITY OF SUCH DAMAGE.
+.\" */
+.TH VOTEQUORUM_VOTES 3 @BUILDDATE@ "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
+.SH NAME
+votequorum_setvotes \- Sets the number of votes for a node
+.SH SYNOPSIS
+.B #include <corosync/votequorum.h>
+.sp
+.BI "int votequorum_setexpected(votequorum_handle_t " handle ", unsigned int " nodeid ", int " votes ");"
+.SH DESCRIPTION
+The
+.B votequorum_setvotes
+is used to change the number of votes that a node has. Note that it is not possible, using this function,
+to change the number of node votes such that the cluster goes inquorate.
+.SH RETURN VALUE
+This call returns the CS_OK value if successful, otherwise an error is returned.
+.PP
+.SH ERRORS
+@COMMONIPCERRORS@
+.SH "SEE ALSO"
+.BR votequorum_overview (3),
+.BR votequorum_initialize (3),
+.BR votequorum_finalize (3),
+.BR votequorum_getinfo (3),
+.BR votequorum_trackstart (3),
+.BR votequorum_trackstop (3),
+.BR votequorum_fd_get (3),
+.BR votequorum_dispatch (3),
+.BR votequorum_context_set (3),
+.BR votequorum_context_get (3),
+.BR votequorum_setexpected (3)
+.PP
diff --git a/man/votequorum_trackstart.3.in b/man/votequorum_trackstart.3.in
new file mode 100644
index 0000000..7a14b06
--- /dev/null
+++ b/man/votequorum_trackstart.3.in
@@ -0,0 +1,83 @@
+.\"/*
+.\" * Copyright (c) 2012 Red Hat, Inc.
+.\" *
+.\" * All rights reserved.
+.\" *
+.\" * Author: Fabio M. Di Nitto <fdinitto@redhat.com>
+.\" *
+.\" * This software licensed under BSD license, the text of which follows:
+.\" *
+.\" * Redistribution and use in source and binary forms, with or without
+.\" * modification, are permitted provided that the following conditions are met:
+.\" *
+.\" * - Redistributions of source code must retain the above copyright notice,
+.\" * this list of conditions and the following disclaimer.
+.\" * - Redistributions in binary form must reproduce the above copyright notice,
+.\" * this list of conditions and the following disclaimer in the documentation
+.\" * and/or other materials provided with the distribution.
+.\" * - Neither the name of the MontaVista Software, Inc. nor the names of its
+.\" * contributors may be used to endorse or promote products derived from this
+.\" * software without specific prior written permission.
+.\" *
+.\" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+.\" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+.\" * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+.\" * THE POSSIBILITY OF SUCH DAMAGE.
+.\" */
+.TH VOTEQUORUM_TRACKSTART 3 @BUILDDATE@ "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
+.SH NAME
+votequorum_trackstart \- Enable callbacks notification.
+.SH SYNOPSIS
+.B #include <corosync/votequorum.h>
+.sp
+.BI "int votequorum_trackstart(votequorum_handle_t *" handle ", uint64_t " context ", unsigned int " flags ");"
+.SH DESCRIPTION
+The
+.B votequorum_trackstart
+function is used to enable callbacks notification from the votequorum API.
+.PP
+Every time the voting configuration changes (eg a node joins or leave the cluster)
+or the quorum status change or the expected votes changes, the notification is queued.
+.PP
+The notification is dispatched via
+.B votequorum_dispatch()
+function that will execute the callback.
+.PP
+The
+.I context
+option allows one to set a tracking context.
+.PP
+The
+.I flags
+argument is defined by one or more of the following values and values can be bitwise-or'd
+
+.nf
+#define CS_TRACK_CURRENT 0x01
+#define CS_TRACK_CHANGES 0x02
+#define CS_TRACK_CHANGES_ONLY 0x04
+.fi
+.SH RETURN VALUE
+This call returns the CS_OK value if successful, otherwise an error is returned.
+.PP
+.SH ERRORS
+@COMMONIPCERRORS@
+.SH "SEE ALSO"
+.BR votequorum_overview (3),
+.BR votequorum_initialize (3),
+.BR votequorum_finalize (3),
+.BR votequorum_getinfo (3),
+.BR votequorum_trackstop (3),
+.BR votequorum_fd_get (3),
+.BR votequorum_dispatch (3),
+.BR votequorum_context_set (3),
+.BR votequorum_context_get (3),
+.BR votequorum_setexpected (3),
+.BR votequorum_setvotes (3)
+.PP
diff --git a/man/votequorum_trackstop.3.in b/man/votequorum_trackstop.3.in
new file mode 100644
index 0000000..ee4387e
--- /dev/null
+++ b/man/votequorum_trackstop.3.in
@@ -0,0 +1,63 @@
+.\"/*
+.\" * Copyright (c) 2012 Red Hat, Inc.
+.\" *
+.\" * All rights reserved.
+.\" *
+.\" * Author: Fabio M. Di Nitto <fdinitto@redhat.com>
+.\" *
+.\" * This software licensed under BSD license, the text of which follows:
+.\" *
+.\" * Redistribution and use in source and binary forms, with or without
+.\" * modification, are permitted provided that the following conditions are met:
+.\" *
+.\" * - Redistributions of source code must retain the above copyright notice,
+.\" * this list of conditions and the following disclaimer.
+.\" * - Redistributions in binary form must reproduce the above copyright notice,
+.\" * this list of conditions and the following disclaimer in the documentation
+.\" * and/or other materials provided with the distribution.
+.\" * - Neither the name of the MontaVista Software, Inc. nor the names of its
+.\" * contributors may be used to endorse or promote products derived from this
+.\" * software without specific prior written permission.
+.\" *
+.\" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+.\" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+.\" * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+.\" * THE POSSIBILITY OF SUCH DAMAGE.
+.\" */
+.TH VOTEQUORUM_TRACKSTOP 3 @BUILDDATE@ "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
+.SH NAME
+votequorum_trackstop \- Disable callbacks notification.
+.SH SYNOPSIS
+.B #include <corosync/votequorum.h>
+.sp
+.BI "int votequorum_trackstart(votequorum_handle_t *" handle ");"
+.SH DESCRIPTION
+The
+.B votequorum_trackstop
+function is used to disable callbacks notification from the votequorum API.
+.PP
+.SH RETURN VALUE
+This call returns the CS_OK value if successful, otherwise an error is returned.
+.PP
+.SH ERRORS
+@COMMONIPCERRORS@
+.SH "SEE ALSO"
+.BR votequorum_overview (3),
+.BR votequorum_initialize (3),
+.BR votequorum_finalize (3),
+.BR votequorum_getinfo (3),
+.BR votequorum_trackstart (3),
+.BR votequorum_fd_get (3),
+.BR votequorum_dispatch (3),
+.BR votequorum_context_set (3),
+.BR votequorum_context_get (3),
+.BR votequorum_setexpected (3),
+.BR votequorum_setvotes (3)
+.PP
diff --git a/missing b/missing
new file mode 100755
index 0000000..cdea514
--- /dev/null
+++ b/missing
@@ -0,0 +1,215 @@
+#! /bin/sh
+# Common wrapper for a few potentially missing GNU programs.
+
+scriptversion=2012-06-26.16; # UTC
+
+# Copyright (C) 1996-2013 Free Software Foundation, Inc.
+# Originally written by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+if test $# -eq 0; then
+ echo 1>&2 "Try '$0 --help' for more information"
+ exit 1
+fi
+
+case $1 in
+
+ --is-lightweight)
+ # Used by our autoconf macros to check whether the available missing
+ # script is modern enough.
+ exit 0
+ ;;
+
+ --run)
+ # Back-compat with the calling convention used by older automake.
+ shift
+ ;;
+
+ -h|--h|--he|--hel|--help)
+ echo "\
+$0 [OPTION]... PROGRAM [ARGUMENT]...
+
+Run 'PROGRAM [ARGUMENT]...', returning a proper advice when this fails due
+to PROGRAM being missing or too old.
+
+Options:
+ -h, --help display this help and exit
+ -v, --version output version information and exit
+
+Supported PROGRAM values:
+ aclocal autoconf autoheader autom4te automake makeinfo
+ bison yacc flex lex help2man
+
+Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and
+'g' are ignored when checking the name.
+
+Send bug reports to <bug-automake@gnu.org>."
+ exit $?
+ ;;
+
+ -v|--v|--ve|--ver|--vers|--versi|--versio|--version)
+ echo "missing $scriptversion (GNU Automake)"
+ exit $?
+ ;;
+
+ -*)
+ echo 1>&2 "$0: unknown '$1' option"
+ echo 1>&2 "Try '$0 --help' for more information"
+ exit 1
+ ;;
+
+esac
+
+# Run the given program, remember its exit status.
+"$@"; st=$?
+
+# If it succeeded, we are done.
+test $st -eq 0 && exit 0
+
+# Also exit now if we it failed (or wasn't found), and '--version' was
+# passed; such an option is passed most likely to detect whether the
+# program is present and works.
+case $2 in --version|--help) exit $st;; esac
+
+# Exit code 63 means version mismatch. This often happens when the user
+# tries to use an ancient version of a tool on a file that requires a
+# minimum version.
+if test $st -eq 63; then
+ msg="probably too old"
+elif test $st -eq 127; then
+ # Program was missing.
+ msg="missing on your system"
+else
+ # Program was found and executed, but failed. Give up.
+ exit $st
+fi
+
+perl_URL=http://www.perl.org/
+flex_URL=http://flex.sourceforge.net/
+gnu_software_URL=http://www.gnu.org/software
+
+program_details ()
+{
+ case $1 in
+ aclocal|automake)
+ echo "The '$1' program is part of the GNU Automake package:"
+ echo "<$gnu_software_URL/automake>"
+ echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:"
+ echo "<$gnu_software_URL/autoconf>"
+ echo "<$gnu_software_URL/m4/>"
+ echo "<$perl_URL>"
+ ;;
+ autoconf|autom4te|autoheader)
+ echo "The '$1' program is part of the GNU Autoconf package:"
+ echo "<$gnu_software_URL/autoconf/>"
+ echo "It also requires GNU m4 and Perl in order to run:"
+ echo "<$gnu_software_URL/m4/>"
+ echo "<$perl_URL>"
+ ;;
+ esac
+}
+
+give_advice ()
+{
+ # Normalize program name to check for.
+ normalized_program=`echo "$1" | sed '
+ s/^gnu-//; t
+ s/^gnu//; t
+ s/^g//; t'`
+
+ printf '%s\n' "'$1' is $msg."
+
+ configure_deps="'configure.ac' or m4 files included by 'configure.ac'"
+ case $normalized_program in
+ autoconf*)
+ echo "You should only need it if you modified 'configure.ac',"
+ echo "or m4 files included by it."
+ program_details 'autoconf'
+ ;;
+ autoheader*)
+ echo "You should only need it if you modified 'acconfig.h' or"
+ echo "$configure_deps."
+ program_details 'autoheader'
+ ;;
+ automake*)
+ echo "You should only need it if you modified 'Makefile.am' or"
+ echo "$configure_deps."
+ program_details 'automake'
+ ;;
+ aclocal*)
+ echo "You should only need it if you modified 'acinclude.m4' or"
+ echo "$configure_deps."
+ program_details 'aclocal'
+ ;;
+ autom4te*)
+ echo "You might have modified some maintainer files that require"
+ echo "the 'automa4te' program to be rebuilt."
+ program_details 'autom4te'
+ ;;
+ bison*|yacc*)
+ echo "You should only need it if you modified a '.y' file."
+ echo "You may want to install the GNU Bison package:"
+ echo "<$gnu_software_URL/bison/>"
+ ;;
+ lex*|flex*)
+ echo "You should only need it if you modified a '.l' file."
+ echo "You may want to install the Fast Lexical Analyzer package:"
+ echo "<$flex_URL>"
+ ;;
+ help2man*)
+ echo "You should only need it if you modified a dependency" \
+ "of a man page."
+ echo "You may want to install the GNU Help2man package:"
+ echo "<$gnu_software_URL/help2man/>"
+ ;;
+ makeinfo*)
+ echo "You should only need it if you modified a '.texi' file, or"
+ echo "any other file indirectly affecting the aspect of the manual."
+ echo "You might want to install the Texinfo package:"
+ echo "<$gnu_software_URL/texinfo/>"
+ echo "The spurious makeinfo call might also be the consequence of"
+ echo "using a buggy 'make' (AIX, DU, IRIX), in which case you might"
+ echo "want to install GNU make:"
+ echo "<$gnu_software_URL/make/>"
+ ;;
+ *)
+ echo "You might have modified some files without having the proper"
+ echo "tools for further handling them. Check the 'README' file, it"
+ echo "often tells you about the needed prerequisites for installing"
+ echo "this package. You may also peek at any GNU archive site, in"
+ echo "case some other package contains this missing '$1' program."
+ ;;
+ esac
+}
+
+give_advice "$1" | sed -e '1s/^/WARNING: /' \
+ -e '2,$s/^/ /' >&2
+
+# Propagate the correct exit status (expected to be 127 for a program
+# not found, 63 for a program that failed due to version mismatch).
+exit $st
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
diff --git a/pkgconfig/Makefile.am b/pkgconfig/Makefile.am
new file mode 100644
index 0000000..b7288f5
--- /dev/null
+++ b/pkgconfig/Makefile.am
@@ -0,0 +1,70 @@
+# Copyright (c) 2009-2022 Red Hat, Inc.
+#
+# All rights reserved.
+#
+# This software licensed under BSD license, the text of which follows:
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# - Redistributions of source code must retain the above copyright notice,
+# this list of conditions and the following disclaimer.
+# - Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+# - Neither the name of the MontaVista Software, Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from this
+# software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR ENGINES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+# THE POSSIBILITY OF SUCH DAMAGE.
+
+MAINTAINERCLEANFILES = Makefile.in
+
+EXTRA_DIST = libtemplate.pc.in corosync.pc.in
+
+LIBS = cfg cpg quorum \
+ votequorum sam cmap corosync_common
+
+pkgconfigdir = $(libdir)/pkgconfig
+
+target_LIBS = $(LIBS:%=lib%.pc)
+
+target_PACKAGE = corosync.pc
+
+pkgconfig_DATA = $(target_LIBS) $(target_PACKAGE)
+
+CLEANFILES = $(pkgconfig_DATA)
+
+lib%.pc: libtemplate.pc.in Makefile
+ rm -f $@-t $@
+ $(SED) \
+ -e 's#@''PREFIX@#$(exec_prefix)#g' \
+ -e 's#@''LIBDIR@#$(libdir)#g' \
+ -e 's#@''LIBVERSION@#$(VERSION)#g' \
+ -e 's#@''LIB@#'$(*:lib%=%)'#g' \
+ $< > $@-t
+ chmod a-w $@-t
+ mv $@-t $@
+
+%: %.in Makefile
+ rm -f $@-t $@
+ $(SED) \
+ -e 's#@''PREFIX@#$(exec_prefix)#g' \
+ -e 's#@''LIBDIR@#$(libdir)#g' \
+ -e 's#@''LIBVERSION@#$(VERSION)#g' \
+ -e 's#@''LOGDIR@#$(LOGDIR)#g' \
+ -e 's#@''COROSYSCONFDIR@#$(COROSYSCONFDIR)#g' \
+ $< > $@-t
+ chmod a-w $@-t
+ mv $@-t $@
+
diff --git a/pkgconfig/Makefile.in b/pkgconfig/Makefile.in
new file mode 100644
index 0000000..6af65c9
--- /dev/null
+++ b/pkgconfig/Makefile.in
@@ -0,0 +1,597 @@
+# Makefile.in generated by automake 1.13.4 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+# Copyright (c) 2009-2022 Red Hat, Inc.
+#
+# All rights reserved.
+#
+# This software licensed under BSD license, the text of which follows:
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# - Redistributions of source code must retain the above copyright notice,
+# this list of conditions and the following disclaimer.
+# - Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+# - Neither the name of the MontaVista Software, Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from this
+# software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR ENGINES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+# THE POSSIBILITY OF SUCH DAMAGE.
+
+VPATH = @srcdir@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = pkgconfig
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/lib/libcfg.verso $(top_srcdir)/lib/libcpg.verso \
+ $(top_srcdir)/lib/libquorum.verso \
+ $(top_srcdir)/lib/libsam.verso \
+ $(top_srcdir)/lib/libvotequorum.verso \
+ $(top_srcdir)/lib/libcmap.verso $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/include/corosync/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+SOURCES =
+DIST_SOURCES =
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+am__installdirs = "$(DESTDIR)$(pkgconfigdir)"
+DATA = $(pkgconfig_DATA)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALLOCA = @ALLOCA@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUGTOOL = @AUGTOOL@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BASHPATH = @BASHPATH@
+BINDGEN = @BINDGEN@
+CARGO = @CARGO@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFG_SONAME = @CFG_SONAME@
+CFLAGS = @CFLAGS@
+CLIPPY = @CLIPPY@
+CMAP_SONAME = @CMAP_SONAME@
+COROSYSCONFDIR = @COROSYSCONFDIR@
+CPG_SONAME = @CPG_SONAME@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DBUS_CFLAGS = @DBUS_CFLAGS@
+DBUS_LIBS = @DBUS_LIBS@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DOT = @DOT@
+DOXYGEN = @DOXYGEN@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GREP = @GREP@
+GROFF = @GROFF@
+INITCONFIGDIR = @INITCONFIGDIR@
+INITDDIR = @INITDDIR@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBQB_CFLAGS = @LIBQB_CFLAGS@
+LIBQB_LIBS = @LIBQB_LIBS@
+LIBS = cfg cpg quorum \
+ votequorum sam cmap corosync_common
+
+LIBTOOL = @LIBTOOL@
+LINT_FLAGS = @LINT_FLAGS@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LOGDIR = @LOGDIR@
+LOGROTATEDIR = @LOGROTATEDIR@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+QUORUM_SONAME = @QUORUM_SONAME@
+RANLIB = @RANLIB@
+RUSTC = @RUSTC@
+RUSTDOC = @RUSTDOC@
+RUSTFMT = @RUSTFMT@
+RUST_FLAGS = @RUST_FLAGS@
+RUST_TARGET_DIR = @RUST_TARGET_DIR@
+SAM_SONAME = @SAM_SONAME@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SNMPCONFIG = @SNMPCONFIG@
+SNMP_LIBS = @SNMP_LIBS@
+SOMAJOR = @SOMAJOR@
+SOMICRO = @SOMICRO@
+SOMINOR = @SOMINOR@
+SONAME = @SONAME@
+STRIP = @STRIP@
+SYSTEMDDIR = @SYSTEMDDIR@
+VERSCRIPT_LDFLAGS = @VERSCRIPT_LDFLAGS@
+VERSION = @VERSION@
+VOTEQUORUM_SONAME = @VOTEQUORUM_SONAME@
+WITH_LIST = @WITH_LIST@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+corosyncrustver = @corosyncrustver@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+knet_CFLAGS = @knet_CFLAGS@
+knet_LIBS = @knet_LIBS@
+libdir = @libdir@
+libexecdir = @libexecdir@
+libsystemd_CFLAGS = @libsystemd_CFLAGS@
+libsystemd_LIBS = @libsystemd_LIBS@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+nozzle_CFLAGS = @nozzle_CFLAGS@
+nozzle_LIBS = @nozzle_LIBS@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+statgrab_CFLAGS = @statgrab_CFLAGS@
+statgrab_LIBS = @statgrab_LIBS@
+statgrabge090_CFLAGS = @statgrabge090_CFLAGS@
+statgrabge090_LIBS = @statgrabge090_LIBS@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+MAINTAINERCLEANFILES = Makefile.in
+EXTRA_DIST = libtemplate.pc.in corosync.pc.in
+pkgconfigdir = $(libdir)/pkgconfig
+target_LIBS = $(LIBS:%=lib%.pc)
+target_PACKAGE = corosync.pc
+pkgconfig_DATA = $(target_LIBS) $(target_PACKAGE)
+CLEANFILES = $(pkgconfig_DATA)
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign pkgconfig/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign pkgconfig/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+install-pkgconfigDATA: $(pkgconfig_DATA)
+ @$(NORMAL_INSTALL)
+ @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(pkgconfigdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(pkgconfigdir)" || exit 1; \
+ fi; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgconfigdir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgconfigdir)" || exit $$?; \
+ done
+
+uninstall-pkgconfigDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ dir='$(DESTDIR)$(pkgconfigdir)'; $(am__uninstall_files_from_dir)
+tags TAGS:
+
+ctags CTAGS:
+
+cscope cscopelist:
+
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(DATA)
+installdirs:
+ for dir in "$(DESTDIR)$(pkgconfigdir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+ -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+clean: clean-am
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-am
+ -rm -f Makefile
+distclean-am: clean-am distclean-generic
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-pkgconfigDATA
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-pkgconfigDATA
+
+.MAKE: install-am install-strip
+
+.PHONY: all all-am check check-am clean clean-generic clean-libtool \
+ cscopelist-am ctags-am distclean distclean-generic \
+ distclean-libtool distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-pkgconfigDATA install-ps \
+ install-ps-am install-strip installcheck installcheck-am \
+ installdirs maintainer-clean maintainer-clean-generic \
+ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \
+ ps ps-am tags-am uninstall uninstall-am \
+ uninstall-pkgconfigDATA
+
+
+lib%.pc: libtemplate.pc.in Makefile
+ rm -f $@-t $@
+ $(SED) \
+ -e 's#@''PREFIX@#$(exec_prefix)#g' \
+ -e 's#@''LIBDIR@#$(libdir)#g' \
+ -e 's#@''LIBVERSION@#$(VERSION)#g' \
+ -e 's#@''LIB@#'$(*:lib%=%)'#g' \
+ $< > $@-t
+ chmod a-w $@-t
+ mv $@-t $@
+
+%: %.in Makefile
+ rm -f $@-t $@
+ $(SED) \
+ -e 's#@''PREFIX@#$(exec_prefix)#g' \
+ -e 's#@''LIBDIR@#$(libdir)#g' \
+ -e 's#@''LIBVERSION@#$(VERSION)#g' \
+ -e 's#@''LOGDIR@#$(LOGDIR)#g' \
+ -e 's#@''COROSYSCONFDIR@#$(COROSYSCONFDIR)#g' \
+ $< > $@-t
+ chmod a-w $@-t
+ mv $@-t $@
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/pkgconfig/corosync.pc.in b/pkgconfig/corosync.pc.in
new file mode 100644
index 0000000..52029d3
--- /dev/null
+++ b/pkgconfig/corosync.pc.in
@@ -0,0 +1,12 @@
+prefix=@PREFIX@
+exec_prefix=${prefix}
+libdir=@LIBDIR@
+includedir=${prefix}/include
+logdir=@LOGDIR@
+corosysconfdir=@COROSYSCONFDIR@
+
+Name: corosync
+Version: @LIBVERSION@
+Description: corosync
+Requires: libqb
+Cflags: -I${includedir}
diff --git a/pkgconfig/libtemplate.pc.in b/pkgconfig/libtemplate.pc.in
new file mode 100644
index 0000000..49d08fd
--- /dev/null
+++ b/pkgconfig/libtemplate.pc.in
@@ -0,0 +1,11 @@
+prefix=@PREFIX@
+exec_prefix=${prefix}
+libdir=@LIBDIR@
+includedir=${prefix}/include
+
+Name: @LIB@
+Version: @LIBVERSION@
+Description: @LIB@
+Requires: libqb
+Libs: -L${libdir} -l@LIB@
+Cflags: -I${includedir}
diff --git a/test-driver b/test-driver
new file mode 100755
index 0000000..32bf39e
--- /dev/null
+++ b/test-driver
@@ -0,0 +1,127 @@
+#! /bin/sh
+# test-driver - basic testsuite driver script.
+
+scriptversion=2012-06-27.10; # UTC
+
+# Copyright (C) 2011-2013 Free Software Foundation, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, 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, see <http://www.gnu.org/licenses/>.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# This file is maintained in Automake, please report
+# bugs to <bug-automake@gnu.org> or send patches to
+# <automake-patches@gnu.org>.
+
+# Make unconditional expansion of undefined variables an error. This
+# helps a lot in preventing typo-related bugs.
+set -u
+
+usage_error ()
+{
+ echo "$0: $*" >&2
+ print_usage >&2
+ exit 2
+}
+
+print_usage ()
+{
+ cat <<END
+Usage:
+ test-driver --test-name=NAME --log-file=PATH --trs-file=PATH
+ [--expect-failure={yes|no}] [--color-tests={yes|no}]
+ [--enable-hard-errors={yes|no}] [--] TEST-SCRIPT
+The '--test-name', '--log-file' and '--trs-file' options are mandatory.
+END
+}
+
+# TODO: better error handling in option parsing (in particular, ensure
+# TODO: $log_file, $trs_file and $test_name are defined).
+test_name= # Used for reporting.
+log_file= # Where to save the output of the test script.
+trs_file= # Where to save the metadata of the test run.
+expect_failure=no
+color_tests=no
+enable_hard_errors=yes
+while test $# -gt 0; do
+ case $1 in
+ --help) print_usage; exit $?;;
+ --version) echo "test-driver $scriptversion"; exit $?;;
+ --test-name) test_name=$2; shift;;
+ --log-file) log_file=$2; shift;;
+ --trs-file) trs_file=$2; shift;;
+ --color-tests) color_tests=$2; shift;;
+ --expect-failure) expect_failure=$2; shift;;
+ --enable-hard-errors) enable_hard_errors=$2; shift;;
+ --) shift; break;;
+ -*) usage_error "invalid option: '$1'";;
+ esac
+ shift
+done
+
+if test $color_tests = yes; then
+ # Keep this in sync with 'lib/am/check.am:$(am__tty_colors)'.
+ red='' # Red.
+ grn='' # Green.
+ lgn='' # Light green.
+ blu='' # Blue.
+ mgn='' # Magenta.
+ std='' # No color.
+else
+ red= grn= lgn= blu= mgn= std=
+fi
+
+do_exit='rm -f $log_file $trs_file; (exit $st); exit $st'
+trap "st=129; $do_exit" 1
+trap "st=130; $do_exit" 2
+trap "st=141; $do_exit" 13
+trap "st=143; $do_exit" 15
+
+# Test script is run here.
+"$@" >$log_file 2>&1
+estatus=$?
+if test $enable_hard_errors = no && test $estatus -eq 99; then
+ estatus=1
+fi
+
+case $estatus:$expect_failure in
+ 0:yes) col=$red res=XPASS recheck=yes gcopy=yes;;
+ 0:*) col=$grn res=PASS recheck=no gcopy=no;;
+ 77:*) col=$blu res=SKIP recheck=no gcopy=yes;;
+ 99:*) col=$mgn res=ERROR recheck=yes gcopy=yes;;
+ *:yes) col=$lgn res=XFAIL recheck=no gcopy=yes;;
+ *:*) col=$red res=FAIL recheck=yes gcopy=yes;;
+esac
+
+# Report outcome to console.
+echo "${col}${res}${std}: $test_name"
+
+# Register the test result, and other relevant metadata.
+echo ":test-result: $res" > $trs_file
+echo ":global-test-result: $res" >> $trs_file
+echo ":recheck: $recheck" >> $trs_file
+echo ":copy-in-global-log: $gcopy" >> $trs_file
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
diff --git a/test/Makefile.am b/test/Makefile.am
new file mode 100644
index 0000000..c8a7462
--- /dev/null
+++ b/test/Makefile.am
@@ -0,0 +1,81 @@
+#
+# Copyright (c) 2009-2020 Red Hat, Inc.
+#
+# Authors: Andrew Beekhof
+# Steven Dake (sdake@redhat.com)
+#
+# This software licensed under BSD license, the text of which follows:
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# - Redistributions of source code must retain the above copyright notice,
+# this list of conditions and the following disclaimer.
+# - Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+# - Neither the name of the MontaVista Software, Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from this
+# software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+# THE POSSIBILITY OF SUCH DAMAGE.
+
+MAINTAINERCLEANFILES = Makefile.in
+
+EXTRA_DIST = ploadstart.sh
+
+noinst_PROGRAMS = testcpg testcpg2 cpgbench \
+ testquorum testvotequorum1 testvotequorum2 \
+ stress_cpgfdget stress_cpgcontext cpgbound testsam \
+ testcpgzc cpgbenchzc testzcgc stress_cpgzc \
+ testquorummodel testcfg
+
+noinst_SCRIPTS = ploadstart
+
+testcpg_LDADD = $(LIBQB_LIBS) $(top_builddir)/lib/libcpg.la
+testcpg2_LDADD = $(LIBQB_LIBS) $(top_builddir)/lib/libcpg.la
+testcpgzc_LDADD = $(LIBQB_LIBS) $(top_builddir)/lib/libcpg.la
+testzcgc_LDADD = $(LIBQB_LIBS) $(top_builddir)/lib/libcpg.la
+stress_cpgzc_LDADD = $(LIBQB_LIBS) $(top_builddir)/lib/libcpg.la
+stress_cpgfdget_LDADD = $(LIBQB_LIBS) $(top_builddir)/lib/libcpg.la
+stress_cpgcontext_LDADD = $(LIBQB_LIBS) $(top_builddir)/lib/libcpg.la
+testquorum_LDADD = $(LIBQB_LIBS) $(top_builddir)/lib/libquorum.la
+testquorummodel_LDADD = $(LIBQB_LIBS) $(top_builddir)/lib/libquorum.la
+testvotequorum1_LDADD = $(LIBQB_LIBS) $(top_builddir)/lib/libvotequorum.la
+testvotequorum2_LDADD = $(LIBQB_LIBS) $(top_builddir)/lib/libvotequorum.la
+cpgbound_LDADD = $(LIBQB_LIBS) $(top_builddir)/lib/libcpg.la
+cpgbench_LDADD = $(LIBQB_LIBS) $(top_builddir)/lib/libcpg.la
+cpgbenchzc_LDADD = $(LIBQB_LIBS) $(top_builddir)/lib/libcpg.la \
+ $(top_builddir)/common_lib/libcorosync_common.la
+testsam_LDADD = $(LIBQB_LIBS) $(top_builddir)/lib/libsam.la \
+ $(top_builddir)/lib/libcmap.la
+testcfg_LDADD = $(LIBQB_LIBS) $(top_builddir)/lib/libcfg.la
+
+if HAVE_CRC32
+noinst_PROGRAMS += cpghum cpgverify
+cpghum_LDADD = $(LIBQB_LIBS) $(top_builddir)/lib/libcpg.la -lz
+cpgverify_LDADD = $(LIBQB_LIBS) $(top_builddir)/lib/libcpg.la -lz
+endif
+
+ploadstart: ploadstart.sh
+ $(SED) -e 's#@''BASHPATH@#${BASHPATH}#g' $< > $@
+ chmod 755 $@
+
+LINT_FILES1:=$(filter-out sa_error.c, $(wildcard *.c))
+LINT_FILES:=$(filter-out testparse.c, $(LINT_FILES1))
+
+lint:
+ -for f in $(LINT_FILES) ; do echo Splint $$f ; splint $(LINT_FLAGS) $(CPPFLAGS) $(CFLAGS) $$f ; done
+
+clean-local:
+ rm -f ploadstart
diff --git a/test/Makefile.in b/test/Makefile.in
new file mode 100644
index 0000000..c8b29d2
--- /dev/null
+++ b/test/Makefile.in
@@ -0,0 +1,869 @@
+# Makefile.in generated by automake 1.13.4 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+#
+# Copyright (c) 2009-2020 Red Hat, Inc.
+#
+# Authors: Andrew Beekhof
+# Steven Dake (sdake@redhat.com)
+#
+# This software licensed under BSD license, the text of which follows:
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# - Redistributions of source code must retain the above copyright notice,
+# this list of conditions and the following disclaimer.
+# - Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+# - Neither the name of the MontaVista Software, Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from this
+# software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+# THE POSSIBILITY OF SUCH DAMAGE.
+
+
+VPATH = @srcdir@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+noinst_PROGRAMS = testcpg$(EXEEXT) testcpg2$(EXEEXT) cpgbench$(EXEEXT) \
+ testquorum$(EXEEXT) testvotequorum1$(EXEEXT) \
+ testvotequorum2$(EXEEXT) stress_cpgfdget$(EXEEXT) \
+ stress_cpgcontext$(EXEEXT) cpgbound$(EXEEXT) testsam$(EXEEXT) \
+ testcpgzc$(EXEEXT) cpgbenchzc$(EXEEXT) testzcgc$(EXEEXT) \
+ stress_cpgzc$(EXEEXT) testquorummodel$(EXEEXT) \
+ testcfg$(EXEEXT) $(am__EXEEXT_1)
+@HAVE_CRC32_TRUE@am__append_1 = cpghum cpgverify
+subdir = test
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+ $(top_srcdir)/depcomp
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/lib/libcfg.verso $(top_srcdir)/lib/libcpg.verso \
+ $(top_srcdir)/lib/libquorum.verso \
+ $(top_srcdir)/lib/libsam.verso \
+ $(top_srcdir)/lib/libvotequorum.verso \
+ $(top_srcdir)/lib/libcmap.verso $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/include/corosync/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+@HAVE_CRC32_TRUE@am__EXEEXT_1 = cpghum$(EXEEXT) cpgverify$(EXEEXT)
+PROGRAMS = $(noinst_PROGRAMS)
+cpgbench_SOURCES = cpgbench.c
+cpgbench_OBJECTS = cpgbench.$(OBJEXT)
+am__DEPENDENCIES_1 =
+cpgbench_DEPENDENCIES = $(am__DEPENDENCIES_1) \
+ $(top_builddir)/lib/libcpg.la
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 =
+cpgbenchzc_SOURCES = cpgbenchzc.c
+cpgbenchzc_OBJECTS = cpgbenchzc.$(OBJEXT)
+cpgbenchzc_DEPENDENCIES = $(am__DEPENDENCIES_1) \
+ $(top_builddir)/lib/libcpg.la \
+ $(top_builddir)/common_lib/libcorosync_common.la
+cpgbound_SOURCES = cpgbound.c
+cpgbound_OBJECTS = cpgbound.$(OBJEXT)
+cpgbound_DEPENDENCIES = $(am__DEPENDENCIES_1) \
+ $(top_builddir)/lib/libcpg.la
+cpghum_SOURCES = cpghum.c
+cpghum_OBJECTS = cpghum.$(OBJEXT)
+@HAVE_CRC32_TRUE@cpghum_DEPENDENCIES = $(am__DEPENDENCIES_1) \
+@HAVE_CRC32_TRUE@ $(top_builddir)/lib/libcpg.la
+cpgverify_SOURCES = cpgverify.c
+cpgverify_OBJECTS = cpgverify.$(OBJEXT)
+@HAVE_CRC32_TRUE@cpgverify_DEPENDENCIES = $(am__DEPENDENCIES_1) \
+@HAVE_CRC32_TRUE@ $(top_builddir)/lib/libcpg.la
+stress_cpgcontext_SOURCES = stress_cpgcontext.c
+stress_cpgcontext_OBJECTS = stress_cpgcontext.$(OBJEXT)
+stress_cpgcontext_DEPENDENCIES = $(am__DEPENDENCIES_1) \
+ $(top_builddir)/lib/libcpg.la
+stress_cpgfdget_SOURCES = stress_cpgfdget.c
+stress_cpgfdget_OBJECTS = stress_cpgfdget.$(OBJEXT)
+stress_cpgfdget_DEPENDENCIES = $(am__DEPENDENCIES_1) \
+ $(top_builddir)/lib/libcpg.la
+stress_cpgzc_SOURCES = stress_cpgzc.c
+stress_cpgzc_OBJECTS = stress_cpgzc.$(OBJEXT)
+stress_cpgzc_DEPENDENCIES = $(am__DEPENDENCIES_1) \
+ $(top_builddir)/lib/libcpg.la
+testcfg_SOURCES = testcfg.c
+testcfg_OBJECTS = testcfg.$(OBJEXT)
+testcfg_DEPENDENCIES = $(am__DEPENDENCIES_1) \
+ $(top_builddir)/lib/libcfg.la
+testcpg_SOURCES = testcpg.c
+testcpg_OBJECTS = testcpg.$(OBJEXT)
+testcpg_DEPENDENCIES = $(am__DEPENDENCIES_1) \
+ $(top_builddir)/lib/libcpg.la
+testcpg2_SOURCES = testcpg2.c
+testcpg2_OBJECTS = testcpg2.$(OBJEXT)
+testcpg2_DEPENDENCIES = $(am__DEPENDENCIES_1) \
+ $(top_builddir)/lib/libcpg.la
+testcpgzc_SOURCES = testcpgzc.c
+testcpgzc_OBJECTS = testcpgzc.$(OBJEXT)
+testcpgzc_DEPENDENCIES = $(am__DEPENDENCIES_1) \
+ $(top_builddir)/lib/libcpg.la
+testquorum_SOURCES = testquorum.c
+testquorum_OBJECTS = testquorum.$(OBJEXT)
+testquorum_DEPENDENCIES = $(am__DEPENDENCIES_1) \
+ $(top_builddir)/lib/libquorum.la
+testquorummodel_SOURCES = testquorummodel.c
+testquorummodel_OBJECTS = testquorummodel.$(OBJEXT)
+testquorummodel_DEPENDENCIES = $(am__DEPENDENCIES_1) \
+ $(top_builddir)/lib/libquorum.la
+testsam_SOURCES = testsam.c
+testsam_OBJECTS = testsam.$(OBJEXT)
+testsam_DEPENDENCIES = $(am__DEPENDENCIES_1) \
+ $(top_builddir)/lib/libsam.la $(top_builddir)/lib/libcmap.la
+testvotequorum1_SOURCES = testvotequorum1.c
+testvotequorum1_OBJECTS = testvotequorum1.$(OBJEXT)
+testvotequorum1_DEPENDENCIES = $(am__DEPENDENCIES_1) \
+ $(top_builddir)/lib/libvotequorum.la
+testvotequorum2_SOURCES = testvotequorum2.c
+testvotequorum2_OBJECTS = testvotequorum2.$(OBJEXT)
+testvotequorum2_DEPENDENCIES = $(am__DEPENDENCIES_1) \
+ $(top_builddir)/lib/libvotequorum.la
+testzcgc_SOURCES = testzcgc.c
+testzcgc_OBJECTS = testzcgc.$(OBJEXT)
+testzcgc_DEPENDENCIES = $(am__DEPENDENCIES_1) \
+ $(top_builddir)/lib/libcpg.la
+SCRIPTS = $(noinst_SCRIPTS)
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/corosync
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo " CC " $@;
+am__v_CC_1 =
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo " CCLD " $@;
+am__v_CCLD_1 =
+SOURCES = cpgbench.c cpgbenchzc.c cpgbound.c cpghum.c cpgverify.c \
+ stress_cpgcontext.c stress_cpgfdget.c stress_cpgzc.c testcfg.c \
+ testcpg.c testcpg2.c testcpgzc.c testquorum.c \
+ testquorummodel.c testsam.c testvotequorum1.c \
+ testvotequorum2.c testzcgc.c
+DIST_SOURCES = cpgbench.c cpgbenchzc.c cpgbound.c cpghum.c cpgverify.c \
+ stress_cpgcontext.c stress_cpgfdget.c stress_cpgzc.c testcfg.c \
+ testcpg.c testcpg2.c testcpgzc.c testquorum.c \
+ testquorummodel.c testsam.c testvotequorum1.c \
+ testvotequorum2.c testzcgc.c
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALLOCA = @ALLOCA@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUGTOOL = @AUGTOOL@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BASHPATH = @BASHPATH@
+BINDGEN = @BINDGEN@
+CARGO = @CARGO@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFG_SONAME = @CFG_SONAME@
+CFLAGS = @CFLAGS@
+CLIPPY = @CLIPPY@
+CMAP_SONAME = @CMAP_SONAME@
+COROSYSCONFDIR = @COROSYSCONFDIR@
+CPG_SONAME = @CPG_SONAME@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DBUS_CFLAGS = @DBUS_CFLAGS@
+DBUS_LIBS = @DBUS_LIBS@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DOT = @DOT@
+DOXYGEN = @DOXYGEN@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GREP = @GREP@
+GROFF = @GROFF@
+INITCONFIGDIR = @INITCONFIGDIR@
+INITDDIR = @INITDDIR@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBQB_CFLAGS = @LIBQB_CFLAGS@
+LIBQB_LIBS = @LIBQB_LIBS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LINT_FLAGS = @LINT_FLAGS@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LOGDIR = @LOGDIR@
+LOGROTATEDIR = @LOGROTATEDIR@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+QUORUM_SONAME = @QUORUM_SONAME@
+RANLIB = @RANLIB@
+RUSTC = @RUSTC@
+RUSTDOC = @RUSTDOC@
+RUSTFMT = @RUSTFMT@
+RUST_FLAGS = @RUST_FLAGS@
+RUST_TARGET_DIR = @RUST_TARGET_DIR@
+SAM_SONAME = @SAM_SONAME@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SNMPCONFIG = @SNMPCONFIG@
+SNMP_LIBS = @SNMP_LIBS@
+SOMAJOR = @SOMAJOR@
+SOMICRO = @SOMICRO@
+SOMINOR = @SOMINOR@
+SONAME = @SONAME@
+STRIP = @STRIP@
+SYSTEMDDIR = @SYSTEMDDIR@
+VERSCRIPT_LDFLAGS = @VERSCRIPT_LDFLAGS@
+VERSION = @VERSION@
+VOTEQUORUM_SONAME = @VOTEQUORUM_SONAME@
+WITH_LIST = @WITH_LIST@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+corosyncrustver = @corosyncrustver@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+knet_CFLAGS = @knet_CFLAGS@
+knet_LIBS = @knet_LIBS@
+libdir = @libdir@
+libexecdir = @libexecdir@
+libsystemd_CFLAGS = @libsystemd_CFLAGS@
+libsystemd_LIBS = @libsystemd_LIBS@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+nozzle_CFLAGS = @nozzle_CFLAGS@
+nozzle_LIBS = @nozzle_LIBS@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+statgrab_CFLAGS = @statgrab_CFLAGS@
+statgrab_LIBS = @statgrab_LIBS@
+statgrabge090_CFLAGS = @statgrabge090_CFLAGS@
+statgrabge090_LIBS = @statgrabge090_LIBS@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+MAINTAINERCLEANFILES = Makefile.in
+EXTRA_DIST = ploadstart.sh
+noinst_SCRIPTS = ploadstart
+testcpg_LDADD = $(LIBQB_LIBS) $(top_builddir)/lib/libcpg.la
+testcpg2_LDADD = $(LIBQB_LIBS) $(top_builddir)/lib/libcpg.la
+testcpgzc_LDADD = $(LIBQB_LIBS) $(top_builddir)/lib/libcpg.la
+testzcgc_LDADD = $(LIBQB_LIBS) $(top_builddir)/lib/libcpg.la
+stress_cpgzc_LDADD = $(LIBQB_LIBS) $(top_builddir)/lib/libcpg.la
+stress_cpgfdget_LDADD = $(LIBQB_LIBS) $(top_builddir)/lib/libcpg.la
+stress_cpgcontext_LDADD = $(LIBQB_LIBS) $(top_builddir)/lib/libcpg.la
+testquorum_LDADD = $(LIBQB_LIBS) $(top_builddir)/lib/libquorum.la
+testquorummodel_LDADD = $(LIBQB_LIBS) $(top_builddir)/lib/libquorum.la
+testvotequorum1_LDADD = $(LIBQB_LIBS) $(top_builddir)/lib/libvotequorum.la
+testvotequorum2_LDADD = $(LIBQB_LIBS) $(top_builddir)/lib/libvotequorum.la
+cpgbound_LDADD = $(LIBQB_LIBS) $(top_builddir)/lib/libcpg.la
+cpgbench_LDADD = $(LIBQB_LIBS) $(top_builddir)/lib/libcpg.la
+cpgbenchzc_LDADD = $(LIBQB_LIBS) $(top_builddir)/lib/libcpg.la \
+ $(top_builddir)/common_lib/libcorosync_common.la
+
+testsam_LDADD = $(LIBQB_LIBS) $(top_builddir)/lib/libsam.la \
+ $(top_builddir)/lib/libcmap.la
+
+testcfg_LDADD = $(LIBQB_LIBS) $(top_builddir)/lib/libcfg.la
+@HAVE_CRC32_TRUE@cpghum_LDADD = $(LIBQB_LIBS) $(top_builddir)/lib/libcpg.la -lz
+@HAVE_CRC32_TRUE@cpgverify_LDADD = $(LIBQB_LIBS) $(top_builddir)/lib/libcpg.la -lz
+LINT_FILES1 := $(filter-out sa_error.c, $(wildcard *.c))
+LINT_FILES := $(filter-out testparse.c, $(LINT_FILES1))
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign test/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign test/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+clean-noinstPROGRAMS:
+ @list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \
+ echo " rm -f" $$list; \
+ rm -f $$list || exit $$?; \
+ test -n "$(EXEEXT)" || exit 0; \
+ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f" $$list; \
+ rm -f $$list
+
+cpgbench$(EXEEXT): $(cpgbench_OBJECTS) $(cpgbench_DEPENDENCIES) $(EXTRA_cpgbench_DEPENDENCIES)
+ @rm -f cpgbench$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(cpgbench_OBJECTS) $(cpgbench_LDADD) $(LIBS)
+
+cpgbenchzc$(EXEEXT): $(cpgbenchzc_OBJECTS) $(cpgbenchzc_DEPENDENCIES) $(EXTRA_cpgbenchzc_DEPENDENCIES)
+ @rm -f cpgbenchzc$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(cpgbenchzc_OBJECTS) $(cpgbenchzc_LDADD) $(LIBS)
+
+cpgbound$(EXEEXT): $(cpgbound_OBJECTS) $(cpgbound_DEPENDENCIES) $(EXTRA_cpgbound_DEPENDENCIES)
+ @rm -f cpgbound$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(cpgbound_OBJECTS) $(cpgbound_LDADD) $(LIBS)
+
+cpghum$(EXEEXT): $(cpghum_OBJECTS) $(cpghum_DEPENDENCIES) $(EXTRA_cpghum_DEPENDENCIES)
+ @rm -f cpghum$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(cpghum_OBJECTS) $(cpghum_LDADD) $(LIBS)
+
+cpgverify$(EXEEXT): $(cpgverify_OBJECTS) $(cpgverify_DEPENDENCIES) $(EXTRA_cpgverify_DEPENDENCIES)
+ @rm -f cpgverify$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(cpgverify_OBJECTS) $(cpgverify_LDADD) $(LIBS)
+
+stress_cpgcontext$(EXEEXT): $(stress_cpgcontext_OBJECTS) $(stress_cpgcontext_DEPENDENCIES) $(EXTRA_stress_cpgcontext_DEPENDENCIES)
+ @rm -f stress_cpgcontext$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(stress_cpgcontext_OBJECTS) $(stress_cpgcontext_LDADD) $(LIBS)
+
+stress_cpgfdget$(EXEEXT): $(stress_cpgfdget_OBJECTS) $(stress_cpgfdget_DEPENDENCIES) $(EXTRA_stress_cpgfdget_DEPENDENCIES)
+ @rm -f stress_cpgfdget$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(stress_cpgfdget_OBJECTS) $(stress_cpgfdget_LDADD) $(LIBS)
+
+stress_cpgzc$(EXEEXT): $(stress_cpgzc_OBJECTS) $(stress_cpgzc_DEPENDENCIES) $(EXTRA_stress_cpgzc_DEPENDENCIES)
+ @rm -f stress_cpgzc$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(stress_cpgzc_OBJECTS) $(stress_cpgzc_LDADD) $(LIBS)
+
+testcfg$(EXEEXT): $(testcfg_OBJECTS) $(testcfg_DEPENDENCIES) $(EXTRA_testcfg_DEPENDENCIES)
+ @rm -f testcfg$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(testcfg_OBJECTS) $(testcfg_LDADD) $(LIBS)
+
+testcpg$(EXEEXT): $(testcpg_OBJECTS) $(testcpg_DEPENDENCIES) $(EXTRA_testcpg_DEPENDENCIES)
+ @rm -f testcpg$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(testcpg_OBJECTS) $(testcpg_LDADD) $(LIBS)
+
+testcpg2$(EXEEXT): $(testcpg2_OBJECTS) $(testcpg2_DEPENDENCIES) $(EXTRA_testcpg2_DEPENDENCIES)
+ @rm -f testcpg2$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(testcpg2_OBJECTS) $(testcpg2_LDADD) $(LIBS)
+
+testcpgzc$(EXEEXT): $(testcpgzc_OBJECTS) $(testcpgzc_DEPENDENCIES) $(EXTRA_testcpgzc_DEPENDENCIES)
+ @rm -f testcpgzc$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(testcpgzc_OBJECTS) $(testcpgzc_LDADD) $(LIBS)
+
+testquorum$(EXEEXT): $(testquorum_OBJECTS) $(testquorum_DEPENDENCIES) $(EXTRA_testquorum_DEPENDENCIES)
+ @rm -f testquorum$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(testquorum_OBJECTS) $(testquorum_LDADD) $(LIBS)
+
+testquorummodel$(EXEEXT): $(testquorummodel_OBJECTS) $(testquorummodel_DEPENDENCIES) $(EXTRA_testquorummodel_DEPENDENCIES)
+ @rm -f testquorummodel$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(testquorummodel_OBJECTS) $(testquorummodel_LDADD) $(LIBS)
+
+testsam$(EXEEXT): $(testsam_OBJECTS) $(testsam_DEPENDENCIES) $(EXTRA_testsam_DEPENDENCIES)
+ @rm -f testsam$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(testsam_OBJECTS) $(testsam_LDADD) $(LIBS)
+
+testvotequorum1$(EXEEXT): $(testvotequorum1_OBJECTS) $(testvotequorum1_DEPENDENCIES) $(EXTRA_testvotequorum1_DEPENDENCIES)
+ @rm -f testvotequorum1$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(testvotequorum1_OBJECTS) $(testvotequorum1_LDADD) $(LIBS)
+
+testvotequorum2$(EXEEXT): $(testvotequorum2_OBJECTS) $(testvotequorum2_DEPENDENCIES) $(EXTRA_testvotequorum2_DEPENDENCIES)
+ @rm -f testvotequorum2$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(testvotequorum2_OBJECTS) $(testvotequorum2_LDADD) $(LIBS)
+
+testzcgc$(EXEEXT): $(testzcgc_OBJECTS) $(testzcgc_DEPENDENCIES) $(EXTRA_testzcgc_DEPENDENCIES)
+ @rm -f testzcgc$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(testzcgc_OBJECTS) $(testzcgc_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpgbench.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpgbenchzc.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpgbound.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpghum.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpgverify.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stress_cpgcontext.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stress_cpgfdget.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stress_cpgzc.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testcfg.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testcpg.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testcpg2.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testcpgzc.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testquorum.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testquorummodel.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testsam.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testvotequorum1.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testvotequorum2.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testzcgc.Po@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(PROGRAMS) $(SCRIPTS)
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+ -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-local clean-noinstPROGRAMS \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
+ clean-libtool clean-local clean-noinstPROGRAMS cscopelist-am \
+ ctags ctags-am distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-dvi install-dvi-am install-exec \
+ install-exec-am install-html install-html-am install-info \
+ install-info-am install-man install-pdf install-pdf-am \
+ install-ps install-ps-am install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags tags-am uninstall uninstall-am
+
+
+ploadstart: ploadstart.sh
+ $(SED) -e 's#@''BASHPATH@#${BASHPATH}#g' $< > $@
+ chmod 755 $@
+
+lint:
+ -for f in $(LINT_FILES) ; do echo Splint $$f ; splint $(LINT_FLAGS) $(CPPFLAGS) $(CFLAGS) $$f ; done
+
+clean-local:
+ rm -f ploadstart
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/test/cpgbench.c b/test/cpgbench.c
new file mode 100644
index 0000000..059effe
--- /dev/null
+++ b/test/cpgbench.c
@@ -0,0 +1,197 @@
+/*
+ * Copyright (c) 2006, 2009 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Author: Steven Dake (sdake@redhat.com)
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of the MontaVista Software, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <signal.h>
+#include <unistd.h>
+#include <errno.h>
+#include <time.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/select.h>
+#include <sys/uio.h>
+#include <sys/un.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <pthread.h>
+
+#include <qb/qblog.h>
+#include <qb/qbutil.h>
+
+#include <corosync/corotypes.h>
+#include <corosync/cpg.h>
+
+static cpg_handle_t handle;
+
+static pthread_t thread;
+
+#ifndef timersub
+#define timersub(a, b, result) \
+ do { \
+ (result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \
+ (result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \
+ if ((result)->tv_usec < 0) { \
+ --(result)->tv_sec; \
+ (result)->tv_usec += 1000000; \
+ } \
+ } while (0)
+#endif /* timersub */
+
+static int alarm_notice;
+
+static void cpg_bm_confchg_fn (
+ cpg_handle_t handle_in,
+ const struct cpg_name *group_name,
+ const struct cpg_address *member_list, size_t member_list_entries,
+ const struct cpg_address *left_list, size_t left_list_entries,
+ const struct cpg_address *joined_list, size_t joined_list_entries)
+{
+}
+
+static unsigned int write_count;
+
+static void cpg_bm_deliver_fn (
+ cpg_handle_t handle_in,
+ const struct cpg_name *group_name,
+ uint32_t nodeid,
+ uint32_t pid,
+ void *msg,
+ size_t msg_len)
+{
+ write_count++;
+}
+
+static cpg_callbacks_t callbacks = {
+ .cpg_deliver_fn = cpg_bm_deliver_fn,
+ .cpg_confchg_fn = cpg_bm_confchg_fn
+};
+
+#define ONE_MEG 1048576
+static char data[ONE_MEG];
+
+static void cpg_benchmark (
+ cpg_handle_t handle_in,
+ int write_size)
+{
+ struct timeval tv1, tv2, tv_elapsed;
+ struct iovec iov;
+ unsigned int res;
+
+ alarm_notice = 0;
+ iov.iov_base = data;
+ iov.iov_len = write_size;
+
+ write_count = 0;
+ alarm (10);
+
+ gettimeofday (&tv1, NULL);
+ do {
+ res = cpg_mcast_joined (handle_in, CPG_TYPE_AGREED, &iov, 1);
+ } while (alarm_notice == 0 && (res == CS_OK || res == CS_ERR_TRY_AGAIN));
+ gettimeofday (&tv2, NULL);
+ timersub (&tv2, &tv1, &tv_elapsed);
+
+ printf ("%5d messages received ", write_count);
+ printf ("%5d bytes per write ", write_size);
+ printf ("%7.3f Seconds runtime ",
+ (tv_elapsed.tv_sec + (tv_elapsed.tv_usec / 1000000.0)));
+ printf ("%9.3f TP/s ",
+ ((float)write_count) / (tv_elapsed.tv_sec + (tv_elapsed.tv_usec / 1000000.0)));
+ printf ("%7.3f MB/s.\n",
+ ((float)write_count) * ((float)write_size) / ((tv_elapsed.tv_sec + (tv_elapsed.tv_usec / 1000000.0)) * 1000000.0));
+}
+
+static void sigalrm_handler (int num)
+{
+ alarm_notice = 1;
+}
+
+static struct cpg_name group_name = {
+ .value = "cpg_bm",
+ .length = 6
+};
+
+static void* dispatch_thread (void *arg)
+{
+ cpg_dispatch (handle, CS_DISPATCH_BLOCKING);
+ return NULL;
+}
+
+int main (void) {
+ unsigned int size;
+ int i;
+ unsigned int res;
+
+ qb_log_init("cpgbench", LOG_USER, LOG_EMERG);
+ qb_log_ctl(QB_LOG_SYSLOG, QB_LOG_CONF_ENABLED, QB_FALSE);
+ qb_log_filter_ctl(QB_LOG_STDERR, QB_LOG_FILTER_ADD,
+ QB_LOG_FILTER_FILE, "*", LOG_DEBUG);
+ qb_log_ctl(QB_LOG_STDERR, QB_LOG_CONF_ENABLED, QB_TRUE);
+
+ size = 64;
+ signal (SIGALRM, sigalrm_handler);
+ res = cpg_initialize (&handle, &callbacks);
+ if (res != CS_OK) {
+ printf ("cpg_initialize failed with result %d\n", res);
+ exit (1);
+ }
+ pthread_create (&thread, NULL, dispatch_thread, NULL);
+
+ res = cpg_join (handle, &group_name);
+ if (res != CS_OK) {
+ printf ("cpg_join failed with result %d\n", res);
+ exit (1);
+ }
+
+ for (i = 0; i < 10; i++) { /* number of repetitions - up to 50k */
+ cpg_benchmark (handle, size);
+ signal (SIGALRM, sigalrm_handler);
+ size *= 5;
+ if (size >= (ONE_MEG - 100)) {
+ break;
+ }
+ }
+
+ res = cpg_finalize (handle);
+ if (res != CS_OK) {
+ printf ("cpg_finalize failed with result %d\n", res);
+ exit (1);
+ }
+ return (0);
+}
diff --git a/test/cpgbenchzc.c b/test/cpgbenchzc.c
new file mode 100644
index 0000000..92f55ee
--- /dev/null
+++ b/test/cpgbenchzc.c
@@ -0,0 +1,193 @@
+/*
+ * Copyright (c) 2006, 2009 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Author: Steven Dake (sdake@redhat.com)
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of the MontaVista Software, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <signal.h>
+#include <unistd.h>
+#include <errno.h>
+#include <time.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/select.h>
+#include <sys/un.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include <corosync/corotypes.h>
+#include <corosync/cpg.h>
+#include "../lib/util.h"
+
+#ifndef timersub
+#define timersub(a, b, result) \
+ do { \
+ (result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \
+ (result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \
+ if ((result)->tv_usec < 0) { \
+ --(result)->tv_sec; \
+ (result)->tv_usec += 1000000; \
+ } \
+ } while (0)
+#endif
+
+static int alarm_notice;
+
+static void cpg_bm_confchg_fn (
+ cpg_handle_t handle,
+ const struct cpg_name *group_name,
+ const struct cpg_address *member_list, size_t member_list_entries,
+ const struct cpg_address *left_list, size_t left_list_entries,
+ const struct cpg_address *joined_list, size_t joined_list_entries)
+{
+}
+
+static unsigned int write_count;
+
+static void cpg_bm_deliver_fn (
+ cpg_handle_t handle,
+ const struct cpg_name *group_name,
+ uint32_t nodeid,
+ uint32_t pid,
+ void *msg,
+ size_t msg_len)
+{
+ write_count++;
+}
+
+static cpg_callbacks_t callbacks = {
+ .cpg_deliver_fn = cpg_bm_deliver_fn,
+ .cpg_confchg_fn = cpg_bm_confchg_fn
+};
+
+
+void *data;
+
+static void cpg_benchmark (
+ cpg_handle_t handle,
+ int write_size)
+{
+ struct timeval tv1, tv2, tv_elapsed;
+ unsigned int res;
+ cpg_flow_control_state_t flow_control_state;
+
+ alarm_notice = 0;
+
+ write_count = 0;
+ alarm (10);
+
+ gettimeofday (&tv1, NULL);
+ do {
+ /*
+ * Test checkpoint write
+ */
+ cpg_flow_control_state_get (handle, &flow_control_state);
+ if (flow_control_state == CPG_FLOW_CONTROL_DISABLED) {
+retry:
+ res = cpg_zcb_mcast_joined (handle, CPG_TYPE_AGREED, data, write_size);
+ if (res == CS_ERR_TRY_AGAIN) {
+ goto retry;
+ }
+ }
+ res = cpg_dispatch (handle, CS_DISPATCH_ALL);
+ if (res != CS_OK) {
+ printf ("cpg dispatch returned error %d\n", res);
+ exit (1);
+ }
+ } while (alarm_notice == 0);
+ gettimeofday (&tv2, NULL);
+ timersub (&tv2, &tv1, &tv_elapsed);
+
+ printf ("%5d messages received ", write_count);
+ printf ("%5d bytes per write ", write_size);
+ printf ("%7.3f Seconds runtime ",
+ (tv_elapsed.tv_sec + (tv_elapsed.tv_usec / 1000000.0)));
+ printf ("%9.3f TP/s ",
+ ((float)write_count) / (tv_elapsed.tv_sec + (tv_elapsed.tv_usec / 1000000.0)));
+ printf ("%7.3f MB/s.\n",
+ ((float)write_count) * ((float)write_size) / ((tv_elapsed.tv_sec + (tv_elapsed.tv_usec / 1000000.0)) * 1000000.0));
+}
+
+static void sigalrm_handler (int num)
+{
+ alarm_notice = 1;
+}
+
+static struct cpg_name group_name = {
+ .value = "cpg_bm",
+ .length = 6
+};
+
+int main (void) {
+ cpg_handle_t handle;
+ unsigned int size;
+ int i;
+ unsigned int res;
+
+
+
+ size = 1000;
+ signal (SIGALRM, sigalrm_handler);
+ res = cpg_initialize (&handle, &callbacks);
+ if (res != CS_OK) {
+ printf ("cpg_initialize failed with result %d\n", res);
+ exit (1);
+ }
+ cpg_zcb_alloc (handle, 500000, &data);
+ if (res != CS_OK) {
+ printf ("cpg_zcb_alloc couldn't allocate zero copy buffer %d\n", res);
+ exit (1);
+ }
+
+ res = cpg_join (handle, &group_name);
+ if (res != CS_OK) {
+ printf ("cpg_join failed with result %s\n", cs_strerror(res));
+ exit (1);
+ }
+
+ for (i = 0; i < 50; i++) { /* number of repetitions - up to 50k */
+ cpg_benchmark (handle, size);
+ size += 1000;
+ }
+
+ res = cpg_finalize (handle);
+ if (res != CS_OK) {
+ printf ("cpg_finalize failed with result %s\n", cs_strerror(res));
+ exit (1);
+ }
+ return (0);
+}
diff --git a/test/cpgbound.c b/test/cpgbound.c
new file mode 100644
index 0000000..f3ac375
--- /dev/null
+++ b/test/cpgbound.c
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 2009 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Author: Steven Dake (sdake@redhat.com)
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of the MontaVista Software, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/socket.h>
+#include <sys/uio.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <errno.h>
+#include <string.h>
+#include <corosync/corotypes.h>
+#include <corosync/cpg.h>
+
+static void cpg_deliver_fn (
+ cpg_handle_t handle,
+ const struct cpg_name *group_name,
+ uint32_t nodeid,
+ uint32_t pid,
+ void *m,
+ size_t msg_len)
+{
+}
+
+static void cpg_confchg_fn (
+ cpg_handle_t handle,
+ const struct cpg_name *group_name,
+ const struct cpg_address *member_list, size_t member_list_entries,
+ const struct cpg_address *left_list, size_t left_list_entries,
+ const struct cpg_address *joined_list, size_t joined_list_entries)
+{
+}
+
+static cpg_callbacks_t callbacks = {
+ cpg_deliver_fn,
+ cpg_confchg_fn
+};
+
+static struct cpg_name group_name = {
+ .value = "cpg_bm",
+ .length = 6
+};
+
+
+static unsigned char buffer[2000000];
+int main (void)
+{
+ cpg_handle_t handle;
+ cs_error_t result;
+ unsigned int i = 0;
+ struct iovec iov;
+ int res;
+ unsigned int msg_size;
+
+ result = cpg_initialize (&handle, &callbacks);
+ if (result != CS_OK) {
+ printf ("Couldn't initialize CPG service %d\n", result);
+ exit (0);
+ }
+
+ res = cpg_join (handle, &group_name);
+ if (res != CS_OK) {
+ printf ("cpg_join failed with result %d\n", res);
+ exit (1);
+ }
+
+ iov.iov_base = (void *)buffer;
+
+ /*
+ * Demonstrate cpg_mcast_joined
+ */
+ msg_size = 1025000;
+ for (i = 0; i < 1000000000; i++) {
+ iov.iov_len = msg_size;
+try_again_one:
+ result = cpg_mcast_joined (handle, CPG_TYPE_AGREED,
+ &iov, 1);
+ if (result == CS_ERR_TRY_AGAIN) {
+ goto try_again_one;
+ }
+ if (result == CS_ERR_INVALID_PARAM) {
+ printf ("found boundary at %d\n", msg_size);
+ exit (1);
+ }
+ msg_size += 1;
+ printf ("msg size %d\n", msg_size);
+ result = cpg_dispatch (handle, CS_DISPATCH_ALL);
+ if (result != CS_OK && result != CS_ERR_TRY_AGAIN) {
+ printf ("cpg_dispatch failed with result %d\n", res);
+ exit (1);
+ }
+ }
+
+ cpg_finalize (handle);
+
+ return (0);
+}
diff --git a/test/cpghum.c b/test/cpghum.c
new file mode 100644
index 0000000..fd1e388
--- /dev/null
+++ b/test/cpghum.c
@@ -0,0 +1,884 @@
+/*
+ * Copyright (c) 2015-2017 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Author: Christine Caulfield <ccaulfie@redhat.com>
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of the MontaVista Software, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <signal.h>
+#include <unistd.h>
+#include <assert.h>
+#include <errno.h>
+#include <time.h>
+#include <limits.h>
+#include <ctype.h>
+#include <syslog.h>
+#include <stdarg.h>
+#include <inttypes.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/select.h>
+#include <sys/uio.h>
+#include <sys/un.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <pthread.h>
+#include <zlib.h>
+#include <libgen.h>
+#include <getopt.h>
+
+#include <corosync/corotypes.h>
+#include <corosync/cpg.h>
+
+static cpg_handle_t handle;
+
+static pthread_t thread;
+
+#ifndef timersub
+#define timersub(a, b, result) \
+ do { \
+ (result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \
+ (result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \
+ if ((result)->tv_usec < 0) { \
+ --(result)->tv_sec; \
+ (result)->tv_usec += 1000000; \
+ } \
+ } while (0)
+#endif /* timersub */
+
+static int alarm_notice;
+#define MAX_NODEID 65536
+#define ONE_MEG 1048576
+#define DATASIZE (ONE_MEG*20)
+static char data[DATASIZE];
+static int send_counter = 0;
+static int do_syslog = 0;
+static int quiet = 0;
+static int report_rtt = 0;
+static int abort_on_error = 0;
+static int machine_readable = 0;
+static char delimiter = ',';
+static int to_stderr = 0;
+static unsigned int g_our_nodeid;
+static volatile int stopped;
+static unsigned int flood_start = 64;
+static unsigned int flood_multiplier = 5;
+static unsigned long flood_max = (ONE_MEG - 100);
+
+// stats
+static unsigned int length_errors=0;
+static unsigned int crc_errors=0;
+static unsigned int sequence_errors=0;
+static unsigned int packets_sent=0;
+static unsigned int packets_recvd=0;
+static unsigned int packets_recvd1=0; /* For flood intermediates */
+static unsigned int send_retries=0;
+static unsigned int send_fails=0;
+static unsigned long avg_rtt=0;
+static unsigned long max_rtt=0;
+static unsigned long min_rtt=LONG_MAX;
+static unsigned long interim_avg_rtt=0;
+static unsigned long interim_max_rtt=0;
+static unsigned long interim_min_rtt=LONG_MAX;
+
+struct cpghum_header {
+ unsigned int counter;
+ unsigned int crc;
+ unsigned int size;
+ struct timeval timestamp;
+};
+
+static void cpg_bm_confchg_fn (
+ cpg_handle_t handle_in,
+ const struct cpg_name *group_name,
+ const struct cpg_address *member_list, size_t member_list_entries,
+ const struct cpg_address *left_list, size_t left_list_entries,
+ const struct cpg_address *joined_list, size_t joined_list_entries)
+{
+}
+
+static unsigned int g_recv_count;
+static unsigned int g_recv_length;
+static int g_recv_start[MAX_NODEID+1];
+static int g_recv_counter[MAX_NODEID+1];
+static int g_recv_size[MAX_NODEID+1];
+static int g_log_mask = 0xFFFF;
+typedef enum
+{
+ CPGH_LOG_INFO = 1,
+ CPGH_LOG_PERF = 2,
+ CPGH_LOG_RTT = 4,
+ CPGH_LOG_STATS = 8,
+ CPGH_LOG_ERR = 16
+} log_type_t;
+
+static void cpgh_print_message(int syslog_level, const char *facility_name, const char *format, va_list ap)
+ __attribute__((format(printf, 3, 0)));
+
+static void cpgh_log_printf(log_type_t type, const char *format, ...)
+ __attribute__((format(printf, 2, 3)));
+
+static void cpgh_print_message(int syslog_level, const char *facility_name, const char *format, va_list ap)
+{
+ char msg[1024];
+ int start = 0;
+
+ if (machine_readable) {
+ snprintf(msg, sizeof(msg), "%s%c", facility_name, delimiter);
+ start = strlen(msg);
+ }
+
+ assert(vsnprintf(msg+start, sizeof(msg)-start, format, ap) < sizeof(msg)-start);
+
+ if (to_stderr || (syslog_level <= LOG_ERR)) {
+ fprintf(stderr, "%s", msg);
+ }
+ else {
+ printf("%s", msg);
+ }
+ if (do_syslog) {
+ syslog(syslog_level, "%s", msg);
+ }
+}
+
+static void cpgh_log_printf(log_type_t type, const char *format, ...)
+{
+ va_list ap;
+
+ if (!(type & g_log_mask)) {
+ return;
+ }
+
+ va_start(ap, format);
+
+ switch (type) {
+ case CPGH_LOG_INFO:
+ cpgh_print_message(LOG_INFO, "[Info]", format, ap);
+ break;
+ case CPGH_LOG_PERF:
+ cpgh_print_message(LOG_INFO, "[Perf]", format, ap);
+ break;
+ case CPGH_LOG_RTT:
+ cpgh_print_message(LOG_INFO, "[RTT]", format, ap);
+ break;
+ case CPGH_LOG_STATS:
+ cpgh_print_message(LOG_INFO, "[Stats]", format, ap);
+ break;
+ case CPGH_LOG_ERR:
+ cpgh_print_message(LOG_ERR, "[Err]", format, ap);
+ break;
+ default:
+ break;
+ }
+
+ va_end(ap);
+}
+
+static unsigned long update_rtt(struct timeval *header_timestamp, int packet_count,
+ unsigned long *rtt_min, unsigned long *rtt_avg, unsigned long *rtt_max)
+{
+ struct timeval tv1;
+ struct timeval rtt;
+ unsigned long rtt_usecs;
+
+ gettimeofday (&tv1, NULL);
+ timersub(&tv1, header_timestamp, &rtt);
+
+ rtt_usecs = rtt.tv_usec + rtt.tv_sec*1000000;
+ if (rtt_usecs > *rtt_max) {
+ *rtt_max = rtt_usecs;
+ }
+ if (rtt_usecs < *rtt_min) {
+ *rtt_min = rtt_usecs;
+ }
+
+ /* Don't start the average with 0 */
+ if (*rtt_avg == 0) {
+ *rtt_avg = rtt_usecs;
+ }
+ else {
+ *rtt_avg = ((*rtt_avg * packet_count) + rtt_usecs) / (packet_count+1);
+ }
+
+ return rtt_usecs;
+}
+
+
+static void cpg_bm_deliver_fn (
+ cpg_handle_t handle_in,
+ const struct cpg_name *group_name,
+ uint32_t nodeid,
+ uint32_t pid,
+ void *msg,
+ size_t msg_len)
+{
+ uLong crc=0;
+ struct cpghum_header *header = (struct cpghum_header *)msg;
+ uLong recv_crc = header->crc & 0xFFFFFFFF;
+ unsigned int *dataint = (unsigned int *)((char*)msg + sizeof(struct cpghum_header));
+ unsigned int datalen;
+
+ if (nodeid > MAX_NODEID) {
+ cpgh_log_printf(CPGH_LOG_ERR, "Got message from invalid nodeid " CS_PRI_NODE_ID " (too high for us). Quitting\n", nodeid);
+ exit(1);
+ }
+
+ packets_recvd++;
+ packets_recvd1++;
+ g_recv_length = msg_len;
+ datalen = header->size - sizeof(struct cpghum_header);
+
+ // Report RTT first in case abort_on_error is set
+ if (nodeid == g_our_nodeid) {
+ unsigned long rtt_usecs;
+
+ // For flood
+ update_rtt(&header->timestamp, packets_recvd1, &interim_min_rtt, &interim_avg_rtt, &interim_max_rtt);
+
+ rtt_usecs = update_rtt(&header->timestamp, g_recv_counter[nodeid], &min_rtt, &avg_rtt, &max_rtt);
+
+ if (report_rtt) {
+ if (machine_readable) {
+ cpgh_log_printf(CPGH_LOG_RTT, "%ld%c%ld%c%ld%c%ld\n", rtt_usecs, delimiter, min_rtt, delimiter, avg_rtt, delimiter, max_rtt);
+ }
+ else {
+ cpgh_log_printf(CPGH_LOG_RTT, "%s: RTT %ld uS (min/avg/max): %ld/%ld/%ld\n", group_name->value, rtt_usecs, min_rtt, avg_rtt, max_rtt);
+ }
+ }
+ }
+
+ // Basic check, packets should all be the right size
+ if (msg_len != header->size) {
+ length_errors++;
+ cpgh_log_printf(CPGH_LOG_ERR, "%s: message sizes don't match. got %zu, expected %u from node " CS_PRI_NODE_ID "\n", group_name->value, msg_len, header->size, nodeid);
+
+ if (abort_on_error) {
+ exit(2);
+ }
+ }
+ g_recv_size[nodeid] = msg_len;
+
+ // Sequence counters are incrementing in step?
+ if (header->counter != g_recv_counter[nodeid]) {
+
+ /* Don't report the first mismatch or a newly restarted sender, we're just catching up */
+ if (g_recv_counter[nodeid] && header->counter) {
+ sequence_errors++;
+ cpgh_log_printf(CPGH_LOG_ERR, "%s: counters don't match. got %d, expected %d from node " CS_PRI_NODE_ID "\n", group_name->value, header->counter, g_recv_counter[nodeid], nodeid);
+
+ if (abort_on_error) {
+ exit(2);
+ }
+ }
+ else {
+ g_recv_start[nodeid] = header->counter;
+ }
+
+ /* Catch up or we'll be printing errors for ever */
+ g_recv_counter[nodeid] = header->counter+1;
+ }
+ else {
+ g_recv_counter[nodeid]++;
+ }
+
+ /* Check crc */
+ crc = crc32(0, NULL, 0);
+ crc = crc32(crc, (Bytef *)dataint, datalen) & 0xFFFFFFFF;
+ if (crc != recv_crc) {
+ crc_errors++;
+ cpgh_log_printf(CPGH_LOG_ERR, "%s: CRCs don't match. got %lx, expected %lx from nodeid " CS_PRI_NODE_ID "\n", group_name->value, recv_crc, crc, nodeid);
+
+ if (abort_on_error) {
+ exit(2);
+ }
+
+ }
+
+ g_recv_count++;
+
+}
+
+static cpg_model_v1_data_t model1_data = {
+ .cpg_deliver_fn = cpg_bm_deliver_fn,
+ .cpg_confchg_fn = cpg_bm_confchg_fn,
+};
+
+static cpg_callbacks_t callbacks = {
+ .cpg_deliver_fn = cpg_bm_deliver_fn,
+ .cpg_confchg_fn = cpg_bm_confchg_fn
+};
+
+static struct cpg_name group_name = {
+ .value = "cpghum",
+ .length = 7
+};
+
+static void set_packet(int write_size, int counter)
+{
+ struct cpghum_header *header = (struct cpghum_header *)data;
+ int i;
+ unsigned int *dataint = (unsigned int *)(data + sizeof(struct cpghum_header));
+ unsigned int datalen = write_size - sizeof(struct cpghum_header);
+ struct timeval tv1;
+ uLong crc;
+
+ header->counter = counter;
+ for (i=0; i<(datalen/4); i++) {
+ dataint[i] = rand();
+ }
+ crc = crc32(0, NULL, 0);
+ header->crc = crc32(crc, (Bytef*)&dataint[0], datalen);
+ header->size = write_size;
+
+ gettimeofday (&tv1, NULL);
+ memcpy(&header->timestamp, &tv1, sizeof(struct timeval));
+}
+
+/* Basically this is cpgbench.c */
+static void cpg_flood (
+ cpg_handle_t handle_in,
+ int write_size)
+{
+ struct timeval tv1, tv2, tv_elapsed;
+ struct iovec iov;
+ unsigned int res = CS_OK;
+
+ alarm_notice = 0;
+ iov.iov_base = data;
+ iov.iov_len = write_size;
+
+ alarm (10);
+ packets_recvd1 = 0;
+ interim_avg_rtt = 0;
+ interim_max_rtt = 0;
+ interim_min_rtt = LONG_MAX;
+
+ gettimeofday (&tv1, NULL);
+ do {
+ if (res == CS_OK) {
+ set_packet(write_size, send_counter);
+ }
+
+ res = cpg_mcast_joined (handle_in, CPG_TYPE_AGREED, &iov, 1);
+ if (res == CS_OK) {
+ /* Only increment the packet counter if it was sucessfully sent */
+ packets_sent++;
+ send_counter++;
+ }
+ else {
+ if (res == CS_ERR_TRY_AGAIN) {
+ send_retries++;
+ }
+ else {
+ send_fails++;
+ }
+ }
+ } while (!stopped && alarm_notice == 0 && (res == CS_OK || res == CS_ERR_TRY_AGAIN));
+ gettimeofday (&tv2, NULL);
+ timersub (&tv2, &tv1, &tv_elapsed);
+
+ if (!quiet) {
+ if (machine_readable) {
+ cpgh_log_printf (CPGH_LOG_PERF, "%d%c%d%c%f%c%f%c%f%c%ld%c%ld%c%ld\n", packets_recvd1, delimiter, write_size, delimiter,
+ (tv_elapsed.tv_sec + (tv_elapsed.tv_usec / 1000000.0)), delimiter,
+ ((float)packets_recvd1) / (tv_elapsed.tv_sec + (tv_elapsed.tv_usec / 1000000.0)), delimiter,
+ ((float)packets_recvd1) * ((float)write_size) / ((tv_elapsed.tv_sec + (tv_elapsed.tv_usec / 1000000.0)) * 1000000.0), delimiter,
+ interim_min_rtt, delimiter, interim_avg_rtt, delimiter, interim_max_rtt);
+ }
+ else {
+ cpgh_log_printf (CPGH_LOG_PERF, "%5d messages received ", packets_recvd1);
+ cpgh_log_printf (CPGH_LOG_PERF, "%5d bytes per write ", write_size);
+ cpgh_log_printf (CPGH_LOG_PERF, "%7.3f Seconds runtime ",
+ (tv_elapsed.tv_sec + (tv_elapsed.tv_usec / 1000000.0)));
+ cpgh_log_printf (CPGH_LOG_PERF, "%9.3f TP/s ",
+ ((float)packets_recvd1) / (tv_elapsed.tv_sec + (tv_elapsed.tv_usec / 1000000.0)));
+ cpgh_log_printf (CPGH_LOG_PERF, "%7.3f MB/s ",
+ ((float)packets_recvd1) * ((float)write_size) / ((tv_elapsed.tv_sec + (tv_elapsed.tv_usec / 1000000.0)) * 1000000.0));
+ cpgh_log_printf (CPGH_LOG_PERF, "RTT for this size (min/avg/max) %ld/%ld/%ld\n",
+ interim_min_rtt, interim_avg_rtt, interim_max_rtt);
+ }
+ }
+}
+
+static int cpg_test (
+ cpg_handle_t handle_in,
+ int write_size,
+ int delay_time,
+ int print_time)
+{
+ struct iovec iov;
+ unsigned int res;
+
+ alarm_notice = 0;
+ iov.iov_base = data;
+ iov.iov_len = write_size;
+
+ g_recv_count = 0;
+ alarm (print_time);
+
+ do {
+ send_counter++;
+ resend:
+ set_packet(write_size, send_counter);
+
+ res = cpg_mcast_joined (handle_in, CPG_TYPE_AGREED, &iov, 1);
+ if (res == CS_ERR_TRY_AGAIN) {
+ usleep(10000);
+ send_retries++;
+ goto resend;
+ }
+ if (res == CS_ERR_LIBRARY) {
+ send_counter--;
+ return -1;
+ }
+ if (res != CS_OK) {
+ cpgh_log_printf(CPGH_LOG_ERR, "send failed: %d\n", res);
+ send_fails++;
+ }
+ else {
+ packets_sent++;
+ }
+ usleep(delay_time*1000);
+ } while (alarm_notice == 0 && (res == CS_OK || res == CS_ERR_TRY_AGAIN) && stopped == 0);
+
+ if (!quiet) {
+ if (machine_readable) {
+ cpgh_log_printf(CPGH_LOG_RTT, "%d%c%ld%c%ld%c%ld\n", 0, delimiter, min_rtt, delimiter, avg_rtt, delimiter, max_rtt);
+ }
+ else {
+ cpgh_log_printf(CPGH_LOG_PERF, "%s: %5d message%s received, ", group_name.value, g_recv_count, g_recv_count==1?"":"s");
+ cpgh_log_printf(CPGH_LOG_PERF, "%5d bytes per write. ", write_size);
+ cpgh_log_printf(CPGH_LOG_RTT, "RTT min/avg/max: %ld/%ld/%ld\n", min_rtt, avg_rtt, max_rtt);
+ }
+ }
+ return 0;
+}
+
+static void sigalrm_handler (int num)
+{
+ alarm_notice = 1;
+}
+
+static void sigint_handler (int num)
+{
+ stopped = 1;
+}
+
+static void* dispatch_thread (void *arg)
+{
+ cpg_dispatch (handle, CS_DISPATCH_BLOCKING);
+ return NULL;
+}
+
+static void usage(char *cmd)
+{
+ fprintf(stderr, "%s [OPTIONS]\n", cmd);
+ fprintf(stderr, "\n");
+ fprintf(stderr, "%s sends CPG messages to all registered users of the CPG.\n", cmd);
+ fprintf(stderr, "The messages have a sequence number and a CRC so that missing or\n");
+ fprintf(stderr, "corrupted messages will be detected and reported.\n");
+ fprintf(stderr, "\n");
+ fprintf(stderr, "%s can also be asked to simply listen for (and check) packets\n", cmd);
+ fprintf(stderr, "so that there is another node in the cluster connected to the CPG.\n");
+ fprintf(stderr, "\n");
+ fprintf(stderr, "Multiple copies, in different CPGs, can also be run on the same or\n");
+ fprintf(stderr, "different nodes by using the -n option.\n");
+ fprintf(stderr, "\n");
+ fprintf(stderr, "%s can handle more than 1 sender in the same CPG provided they are on\n", cmd);
+ fprintf(stderr, "different nodes.\n");
+ fprintf(stderr, "\n");
+ fprintf(stderr, " -w<num>, --size-bytes Write size in Kbytes, default 4\n");
+ fprintf(stderr, " -W<num>, --size-kb Write size in bytes, default 4096\n");
+ fprintf(stderr, " -n<name>, --name CPG name to use, default 'cpghum'\n");
+ fprintf(stderr, " -M Write machine-readable results\n");
+ fprintf(stderr, " -D<char> Delimiter for machine-readable results (default ',')\n");
+ fprintf(stderr, " -E Send normal output to stderr instead of stdout\n");
+ fprintf(stderr, " -d<num>, --delay Delay between sending packets (mS), default 1000\n");
+ fprintf(stderr, " -r<num> Number of repetitions, default 100\n");
+ fprintf(stderr, " -p<num> Delay between printing output (seconds), default 10s\n");
+ fprintf(stderr, " -l, --listen Listen and check CRCs only, don't send (^C to quit)\n");
+ fprintf(stderr, " -t, --rtt Report Round Trip Times for each packet.\n");
+ fprintf(stderr, " -m<num> cpg_initialise() model. Default 1.\n");
+ fprintf(stderr, " -s Also send errors to syslog.\n");
+ fprintf(stderr, " -f, --flood Flood test CPG (cpgbench). see --flood-* long options\n");
+ fprintf(stderr, " -a Abort on crc/length/sequence error\n");
+ fprintf(stderr, " -q, --quiet Quiet. Don't print messages every 10s (see also -p)\n");
+ fprintf(stderr, " -qq Very quiet. Don't print stats at the end\n");
+ fprintf(stderr, " --flood-start=bytes Start value for --flood\n");
+ fprintf(stderr, " --flood-mult=value Packet size multiplier value for --flood\n");
+ fprintf(stderr, " --flood-max=bytes Maximum packet size for --flood\n");
+ fprintf(stderr, "\n");
+ fprintf(stderr, " values for --flood* and -W can have K or M suffixes to indicate\n");
+ fprintf(stderr, " Kilobytes or Megabytes\n");
+ fprintf(stderr, "\n");
+ fprintf(stderr, "%s exit code is 0 if no error happened, 1 on generic error and 2 on\n", cmd);
+ fprintf(stderr, "send/crc/length/sequence error");
+ fprintf(stderr, "\n");
+}
+
+/* Parse a size, optionally ending in 'K', 'M' */
+static long parse_bytes(const char *valstring)
+{
+ unsigned int value;
+ int multiplier = 1;
+ char suffix = '\0';
+ int have_suffix = 0;
+
+ /* Suffix is optional */
+ if (sscanf(valstring, "%u%c", &value, &suffix) == 0) {
+ return 0;
+ }
+
+ if (toupper(suffix) == 'M') {
+ multiplier = 1024*1024;
+ have_suffix = 1;
+ }
+ if (toupper(suffix) == 'K') {
+ multiplier = 1024;
+ have_suffix = 1;
+ }
+
+ if (!have_suffix && suffix != '\0') {
+ fprintf(stderr, "Invalid suffix '%c', only K or M supported\n", suffix);
+ return 0;
+ }
+ return value * multiplier;
+}
+
+static int connect_and_join(int model, int verbose)
+{
+ int res;
+
+ switch (model) {
+ case 0:
+ res = cpg_initialize (&handle, &callbacks);
+ break;
+ case 1:
+ res = cpg_model_initialize (&handle, CPG_MODEL_V1, (cpg_model_data_t *)&model1_data, NULL);
+ break;
+ default:
+ res=999; // can't get here but it keeps the compiler happy
+ break;
+ }
+
+ if (res != CS_OK) {
+ if (verbose) {
+ cpgh_log_printf(CPGH_LOG_ERR, "cpg_initialize failed with result %d\n", res);
+ }
+ return -1;
+ }
+
+ res = cpg_join (handle, &group_name);
+ if (res != CS_OK) {
+ if (verbose) {
+ cpgh_log_printf(CPGH_LOG_ERR, "cpg_join failed with result %d\n", res);
+ }
+ cpg_finalize(handle);
+ return -1;
+ }
+ pthread_create (&thread, NULL, dispatch_thread, NULL);
+ return CS_OK;
+}
+
+
+int main (int argc, char *argv[]) {
+ int i;
+ unsigned int res;
+ uint32_t maxsize;
+ int opt;
+ int bs;
+ int write_size = 4096;
+ int delay_time = 1000;
+ int repetitions = 100;
+ int print_time = 10;
+ int have_size = 0;
+ int listen_only = 0;
+ int flood = 0;
+ int model = 1;
+ int option_index = 0;
+ struct option long_options[] = {
+ {"flood-start", required_argument, 0, 0 },
+ {"flood-mult", required_argument, 0, 0 },
+ {"flood-max", required_argument, 0, 0 },
+ {"size-kb", required_argument, 0, 'w' },
+ {"size-bytes", required_argument, 0, 'W' },
+ {"name", required_argument, 0, 'n' },
+ {"rtt", no_argument, 0, 't' },
+ {"flood", no_argument, 0, 'f' },
+ {"quiet", no_argument, 0, 'q' },
+ {"listen", no_argument, 0, 'l' },
+ {"help", no_argument, 0, '?' },
+ {0, 0, 0, 0 }
+ };
+
+ while ( (opt = getopt_long(argc, argv, "qlstafMEn:d:r:p:m:w:W:D:",
+ long_options, &option_index)) != -1 ) {
+ switch (opt) {
+ case 0: // Long-only options
+ if (strcmp(long_options[option_index].name, "flood-start") == 0) {
+ flood_start = parse_bytes(optarg);
+ if (flood_start == 0) {
+ fprintf(stderr, "flood-start value invalid\n");
+ exit(1);
+ }
+ }
+ if (strcmp(long_options[option_index].name, "flood-mult") == 0) {
+ flood_multiplier = parse_bytes(optarg);
+ if (flood_multiplier == 0) {
+ fprintf(stderr, "flood-mult value invalid\n");
+ exit(1);
+ }
+ }
+ if (strcmp(long_options[option_index].name, "flood-max") == 0) {
+ flood_max = parse_bytes(optarg);
+ if (flood_max == 0) {
+ fprintf(stderr, "flood-max value invalid\n");
+ exit(1);
+ }
+ }
+ break;
+ case 'w': // Write size in K
+ bs = atoi(optarg);
+ if (bs > 0) {
+ write_size = bs*1024;
+ have_size = 1;
+ }
+ break;
+ case 'W': // Write size in bytes (or with a suffix)
+ bs = parse_bytes(optarg);
+ if (bs > 0) {
+ write_size = bs;
+ have_size = 1;
+ }
+ break;
+ case 'n':
+ if (strlen(optarg) >= CPG_MAX_NAME_LENGTH) {
+ fprintf(stderr, "CPG name too long\n");
+ exit(1);
+ }
+
+ strcpy(group_name.value, optarg);
+ group_name.length = strlen(group_name.value);
+ break;
+ case 't':
+ report_rtt = 1;
+ break;
+ case 'E':
+ to_stderr = 1;
+ break;
+ case 'M':
+ machine_readable = 1;
+ break;
+ case 'f':
+ flood = 1;
+ break;
+ case 'a':
+ abort_on_error = 1;
+ break;
+ case 'd':
+ delay_time = atoi(optarg);
+ break;
+ case 'D':
+ delimiter = optarg[0];
+ break;
+ case 'r':
+ repetitions = atoi(optarg);
+ break;
+ case 'p':
+ print_time = atoi(optarg);
+ break;
+ case 'l':
+ listen_only = 1;
+ break;
+ case 's':
+ do_syslog = 1;
+ break;
+ case 'q':
+ quiet++;
+ break;
+ case 'm':
+ model = atoi(optarg);
+ if (model < 0 || model > 1) {
+ fprintf(stderr, "%s: Model must be 0-1\n", argv[0]);
+ exit(1);
+ }
+ break;
+ case '?':
+ usage(basename(argv[0]));
+ exit(1);
+ }
+ }
+
+ if (!have_size && flood) {
+ write_size = flood_start;
+ }
+
+ signal (SIGALRM, sigalrm_handler);
+ signal (SIGINT, sigint_handler);
+
+ if (connect_and_join(model, 1) != CS_OK) {
+ exit(1);
+ }
+
+ res = cpg_local_get(handle, &g_our_nodeid);
+ if (res != CS_OK) {
+ cpgh_log_printf(CPGH_LOG_ERR, "cpg_local_get failed with result %d\n", res);
+ exit (1);
+ }
+
+ if (listen_only) {
+ int secs = 0;
+
+ while (!stopped) {
+ sleep(1);
+ if (++secs > print_time && !quiet) {
+ int nodes_printed = 0;
+
+ if (!machine_readable) {
+ for (i=1; i<MAX_NODEID; i++) {
+ if (g_recv_counter[i]) {
+ cpgh_log_printf(CPGH_LOG_INFO, "%s: %5d message%s of %d bytes received from node " CS_PRI_NODE_ID "\n",
+ group_name.value, g_recv_counter[i] - g_recv_start[i],
+ g_recv_counter[i]==1?"":"s",
+ g_recv_size[i], i);
+ nodes_printed++;
+ }
+ }
+ }
+
+ /* Separate list of nodes if more than one */
+ if (nodes_printed > 1) {
+ cpgh_log_printf(CPGH_LOG_INFO, "\n");
+ }
+ secs = 0;
+ }
+ }
+ }
+ else {
+ cpg_max_atomic_msgsize_get (handle, &maxsize);
+ if (write_size > maxsize) {
+ fprintf(stderr, "INFO: packet size (%d) is larger than the maximum atomic size (%d), libcpg will fragment\n",
+ write_size, maxsize);
+ }
+
+ /* The main job starts here */
+ if (flood) {
+ for (i = 0; i < 10; i++) { /* number of repetitions - up to 50k */
+ cpg_flood (handle, write_size);
+ signal (SIGALRM, sigalrm_handler);
+ write_size *= flood_multiplier;
+ if (write_size > flood_max) {
+ break;
+ }
+ }
+ }
+ else {
+ send_counter = -1; /* So we start from zero to allow listeners to sync */
+ for (i = 0; i < repetitions && !stopped; i++) {
+ if (cpg_test (handle, write_size, delay_time, print_time) == -1) {
+ /* Try to reconnect when corosync stops */
+ res = -1;
+ cpg_finalize(handle);
+ pthread_cancel(thread);
+ signal (SIGINT, SIG_DFL);
+ printf("Reconnecting...");
+ fflush(stdout);
+ while (res != CS_OK) {
+ sleep(1);
+ printf(".");
+ fflush(stdout);
+ res = connect_and_join(model, 0);
+ }
+ printf("done\n");
+ signal (SIGINT, sigint_handler);
+ }
+ signal (SIGALRM, sigalrm_handler);
+ }
+ }
+ }
+
+ res = cpg_finalize (handle);
+ if (res != CS_OK) {
+ cpgh_log_printf(CPGH_LOG_ERR, "cpg_finalize failed with result %d\n", res);
+ exit (1);
+ }
+
+ if (quiet < 2) {
+ /* Don't print LONG_MAX for min_rtt if we don't have a value */
+ if (min_rtt == LONG_MAX) {
+ min_rtt = 0L;
+ }
+
+ if (machine_readable) {
+ cpgh_log_printf(CPGH_LOG_STATS, "%d%c%d%c%d%c%d%c%d%c%d%c%d%c%ld%c%ld%c%ld\n",
+ packets_sent, delimiter,
+ send_fails, delimiter,
+ send_retries, delimiter,
+ length_errors, delimiter,
+ packets_recvd, delimiter,
+ sequence_errors, delimiter,
+ crc_errors, delimiter,
+ min_rtt, delimiter,
+ avg_rtt, delimiter,
+ max_rtt);
+ }
+ else {
+ cpgh_log_printf(CPGH_LOG_STATS, "\n");
+ cpgh_log_printf(CPGH_LOG_STATS, "Stats:\n");
+ if (!listen_only) {
+ cpgh_log_printf(CPGH_LOG_STATS, " packets sent: %d\n", packets_sent);
+ cpgh_log_printf(CPGH_LOG_STATS, " send failures: %d\n", send_fails);
+ cpgh_log_printf(CPGH_LOG_STATS, " send retries: %d\n", send_retries);
+ }
+ cpgh_log_printf(CPGH_LOG_STATS, " length errors: %d\n", length_errors);
+ cpgh_log_printf(CPGH_LOG_STATS, " packets recvd: %d\n", packets_recvd);
+ cpgh_log_printf(CPGH_LOG_STATS, " sequence errors: %d\n", sequence_errors);
+ cpgh_log_printf(CPGH_LOG_STATS, " crc errors: %d\n", crc_errors);
+ if (!listen_only) {
+ cpgh_log_printf(CPGH_LOG_STATS, " min RTT: %ld\n", min_rtt);
+ cpgh_log_printf(CPGH_LOG_STATS, " max RTT: %ld\n", max_rtt);
+ cpgh_log_printf(CPGH_LOG_STATS, " avg RTT: %ld\n", avg_rtt);
+ }
+ cpgh_log_printf(CPGH_LOG_STATS, "\n");
+ }
+ }
+
+ res = 0;
+
+ if (send_fails > 0 || (have_size && length_errors > 0) || sequence_errors > 0 || crc_errors > 0) {
+ res = 2;
+ }
+
+ return (res);
+}
diff --git a/test/cpgverify.c b/test/cpgverify.c
new file mode 100644
index 0000000..6d72cff
--- /dev/null
+++ b/test/cpgverify.c
@@ -0,0 +1,183 @@
+/*
+ * Copyright (c) 2009 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Author: Steven Dake (sdake@redhat.com)
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of the MontaVista Software, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/socket.h>
+#include <sys/uio.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <errno.h>
+#include <string.h>
+#include <inttypes.h>
+#include <corosync/corotypes.h>
+#include <corosync/cpg.h>
+
+#include <zlib.h>
+
+struct my_msg {
+ unsigned int msg_size;
+ unsigned char crc32[4];
+ unsigned char buffer[0];
+};
+
+static int deliveries = 0;
+
+static void cpg_deliver_fn (
+ cpg_handle_t handle,
+ const struct cpg_name *group_name,
+ uint32_t nodeid,
+ uint32_t pid,
+ void *m,
+ size_t msg_len)
+{
+ const struct my_msg *msg2 = m;
+ uLong chsum;
+ uint32_t nchsum;
+
+ printf ("msg '%s'\n", msg2->buffer);
+
+ chsum = crc32(0L, Z_NULL, 0);
+ chsum = crc32(chsum, msg2->buffer, msg2->msg_size) & 0xFFFFFFFF;
+
+ printf ("SIZE %d HASH: 0x%08"PRIx32"\n", msg2->msg_size, (uint32_t)chsum);
+
+ nchsum = htonl((uint32_t)chsum);
+
+ if (memcmp(&nchsum, msg2->crc32, sizeof(nchsum)) != 0) {
+ printf ("incorrect hash\n");
+ exit (1);
+ }
+ deliveries++;
+}
+
+static void cpg_confchg_fn (
+ cpg_handle_t handle,
+ const struct cpg_name *group_name,
+ const struct cpg_address *member_list, size_t member_list_entries,
+ const struct cpg_address *left_list, size_t left_list_entries,
+ const struct cpg_address *joined_list, size_t joined_list_entries)
+{
+}
+
+static cpg_callbacks_t callbacks = {
+ cpg_deliver_fn,
+ cpg_confchg_fn
+};
+
+static struct cpg_name group_name = {
+ .value = "cpg_bm",
+ .length = 6
+};
+
+
+static unsigned char buffer[200000];
+int main (int argc, char *argv[])
+{
+ cpg_handle_t handle;
+ cs_error_t result;
+ int i = 0;
+ int j;
+ struct my_msg msg;
+ struct iovec iov[2];
+ const char *options = "i:";
+ int iter = 1000;
+ int opt;
+ int run_forever = 1;
+ uLong chsum;
+ uint32_t nchsum;
+
+ while ((opt = getopt(argc, argv, options)) != -1) {
+ switch (opt) {
+ case 'i':
+ run_forever = 0;
+ iter = atoi(optarg);
+ break;
+ }
+ }
+
+ result = cpg_initialize (&handle, &callbacks);
+ if (result != CS_OK) {
+ printf ("Couldn't initialize CPG service %d\n", result);
+ exit (0);
+ }
+
+ result = cpg_join (handle, &group_name);
+ if (result != CS_OK) {
+ printf ("cpg_join failed with result %d\n", result);
+ exit (1);
+ }
+
+ iov[0].iov_base = (void *)&msg;
+ iov[0].iov_len = sizeof (struct my_msg);
+ iov[1].iov_base = (void *)buffer;
+
+ /*
+ * Demonstrate cpg_mcast_joined
+ */
+ i = 0;
+ do {
+ msg.msg_size = 100 + rand() % 100000;
+ iov[1].iov_len = msg.msg_size;
+ for (j = 0; j < msg.msg_size; j++) {
+ buffer[j] = j;
+ }
+ sprintf ((char *)buffer,
+ "cpg_mcast_joined: This is message %12d", i);
+
+ chsum = crc32(0L, Z_NULL, 0);
+ chsum = crc32(chsum, buffer, msg.msg_size) & 0xFFFFFFFF;
+ nchsum = htonl((uint32_t)chsum);
+ memcpy(msg.crc32, &nchsum, sizeof(nchsum)) ;
+try_again_one:
+ result = cpg_mcast_joined (handle, CPG_TYPE_AGREED,
+ iov, 2);
+ if (result == CS_ERR_TRY_AGAIN) {
+ goto try_again_one;
+ }
+ result = cpg_dispatch (handle, CS_DISPATCH_ALL);
+ if (result != CS_OK && result != CS_ERR_TRY_AGAIN) {
+ printf("cpg_dispatch failed with result %d\n", result);
+ exit(1);
+ }
+ i++;
+ } while (run_forever || i < iter);
+
+ cpg_finalize (handle);
+
+ return (0);
+}
diff --git a/test/ploadstart.sh b/test/ploadstart.sh
new file mode 100644
index 0000000..bea065b
--- /dev/null
+++ b/test/ploadstart.sh
@@ -0,0 +1,60 @@
+#!@BASHPATH@
+
+set -e
+
+msg_count=""
+msg_size=""
+
+usage() {
+ echo "ploadstart [options]"
+ echo ""
+ echo "Options:"
+ echo " -c msg_count Number of messages to send (max UINT32_T default 1500000)"
+ echo " -s msg_size Size of messages in bytes (max 1000000 default 300)"
+ echo " -h display this help"
+}
+
+while getopts "hs:c:" optflag; do
+ case "$optflag" in
+ h)
+ usage
+ exit 0
+ ;;
+ c)
+ msg_count="$OPTARG"
+ ;;
+ s)
+ msg_size="$OPTARG"
+ ;;
+ \?|:)
+ usage
+ exit 1
+ ;;
+ esac
+done
+
+[ -n "$msg_count" ] && corosync-cmapctl -s pload.count u32 $msg_count
+[ -n "$msg_size" ] && corosync-cmapctl -s pload.size u32 $msg_size
+
+echo "***** WARNING *****"
+echo ""
+echo "Running pload test will kill your cluster and all corosync daemons will exit"
+echo "at the end of the load test"
+echo ""
+echo "***** END OF WARNING *****"
+echo ""
+echo "YOU HAVE BEEN WARNED"
+echo ""
+echo "If you agree, and want to proceed, please type:"
+echo "Yes, I fully understand the risks of what I am doing"
+echo ""
+read -p "type here: " ans
+
+[ "$ans" = "Yes, I fully understand the risks of what I am doing" ] || {
+ echo "Wise choice.. or you simply didn't type it right"
+ exit 0
+}
+
+corosync-cmapctl -s pload.start str i_totally_understand_pload_will_crash_my_cluster_and_kill_corosync_on_exit
+
+echo "PLOAD started, please see corosync.log for final results"
diff --git a/test/stress_cpgcontext.c b/test/stress_cpgcontext.c
new file mode 100644
index 0000000..ba14f63
--- /dev/null
+++ b/test/stress_cpgcontext.c
@@ -0,0 +1,134 @@
+/*
+ * Copyright (c) 2009 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Author: Steven Dake (sdake@redhat.com)
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of the MontaVista Software, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <errno.h>
+#include <string.h>
+#include <corosync/corotypes.h>
+#include <corosync/cpg.h>
+#include <signal.h>
+
+struct my_msg {
+ unsigned int msg_size;
+ unsigned char sha1[20];
+ unsigned char buffer[0];
+};
+
+static void cpg_deliver_fn (
+ cpg_handle_t handle,
+ const struct cpg_name *group_name,
+ uint32_t nodeid,
+ uint32_t pid,
+ void *m,
+ size_t msg_len)
+{
+}
+
+static void cpg_confchg_fn (
+ cpg_handle_t handle,
+ const struct cpg_name *group_name,
+ const struct cpg_address *member_list, size_t member_list_entries,
+ const struct cpg_address *left_list, size_t left_list_entries,
+ const struct cpg_address *joined_list, size_t joined_list_entries)
+{
+}
+
+static cpg_callbacks_t callbacks = {
+ cpg_deliver_fn,
+ cpg_confchg_fn
+};
+
+static void sigintr_handler (int num)
+{
+ exit (1);
+}
+
+#define ITERATIONS (1000000)
+
+#define INSTANCES 100
+
+int main (void)
+{
+ cpg_handle_t handle[INSTANCES];
+ cs_error_t res;
+ void *context[INSTANCES];
+ int i, j;
+ void *ctx;
+
+ signal (SIGINT, sigintr_handler);
+ for (i = 0; i < INSTANCES; i++) {
+ res = cpg_initialize (&handle[i], &callbacks);
+ if (res != CS_OK) {
+ printf ("FAIL %d\n", res);
+ exit (-1);
+ }
+ }
+
+ for (j = 0; j < ITERATIONS; j++) {
+ for (i = 0; i < INSTANCES; i++) {
+ context[i] = malloc (20);
+ res = cpg_context_set (handle[i], context[i]);
+ if (res != CS_OK) {
+ printf ("FAIL %d\n", res);
+ exit (-1);
+ }
+ }
+
+ for (i = 0; i < INSTANCES; i++) {
+ res = cpg_context_get (handle[i], &ctx);
+ if (res != CS_OK) {
+ printf ("FAIL %d\n", res);
+ exit (-1);
+ }
+ if (ctx != context[i]) {
+ printf ("FAIL\n");
+ exit (-1);
+ }
+ free (ctx);
+ }
+ }
+
+ for (i = 0; i < INSTANCES; i++) {
+ cpg_finalize (handle[i]);
+ }
+
+ printf ("PASS\n");
+ return (0);
+}
diff --git a/test/stress_cpgfdget.c b/test/stress_cpgfdget.c
new file mode 100644
index 0000000..af1357e
--- /dev/null
+++ b/test/stress_cpgfdget.c
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2009 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Author: Steven Dake (sdake@redhat.com)
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of the MontaVista Software, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <errno.h>
+#include <string.h>
+#include <corosync/corotypes.h>
+#include <corosync/cpg.h>
+#include <signal.h>
+
+struct my_msg {
+ unsigned int msg_size;
+ unsigned char sha1[20];
+ unsigned char buffer[0];
+};
+
+static void cpg_deliver_fn (
+ cpg_handle_t handle,
+ const struct cpg_name *group_name,
+ uint32_t nodeid,
+ uint32_t pid,
+ void *m,
+ size_t msg_len)
+{
+}
+
+static void cpg_confchg_fn (
+ cpg_handle_t handle,
+ const struct cpg_name *group_name,
+ const struct cpg_address *member_list, size_t member_list_entries,
+ const struct cpg_address *left_list, size_t left_list_entries,
+ const struct cpg_address *joined_list, size_t joined_list_entries)
+{
+}
+
+static cpg_callbacks_t callbacks = {
+ cpg_deliver_fn,
+ cpg_confchg_fn
+};
+
+static void sigintr_handler (int num)
+{
+ exit (1);
+}
+
+
+#define ITERATIONS (1000*2000)
+
+int main (void)
+{
+ cpg_handle_t handle;
+ cs_error_t res;
+ int original_fd;
+ int i;
+ int fd;
+
+ signal (SIGINT, sigintr_handler);
+ res = cpg_initialize (&handle, &callbacks);
+ if (res != CS_OK) {
+ printf ("FAIL %d\n", res);
+ exit (-1);
+ }
+
+ res = cpg_fd_get (handle, &original_fd);
+ if (res != CS_OK) {
+ printf ("FAIL %d\n", res);
+ }
+ for (i = 0; i < ITERATIONS; i++) {
+ res = cpg_fd_get (handle, &fd);
+ if (original_fd != fd) {
+ printf ("FAIL\n");
+ exit (-1);
+ }
+ }
+
+ cpg_finalize (handle);
+
+ printf ("PASS\n");
+ return (0);
+}
diff --git a/test/stress_cpgzc.c b/test/stress_cpgzc.c
new file mode 100644
index 0000000..ba9499b
--- /dev/null
+++ b/test/stress_cpgzc.c
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) 2009 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Author: Steven Dake (sdake@redhat.com)
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of the MontaVista Software, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <errno.h>
+#include <string.h>
+#include <corosync/corotypes.h>
+#include <corosync/cpg.h>
+#include <signal.h>
+#include <assert.h>
+
+struct my_msg {
+ unsigned int msg_size;
+ unsigned char sha1[20];
+ unsigned char buffer[0];
+};
+
+static int deliveries = 0;
+static void cpg_deliver_fn (
+ cpg_handle_t handle,
+ const struct cpg_name *group_name,
+ uint32_t nodeid,
+ uint32_t pid,
+ void *m,
+ size_t msg_len)
+{
+ deliveries++;
+}
+
+static void cpg_confchg_fn (
+ cpg_handle_t handle,
+ const struct cpg_name *group_name,
+ const struct cpg_address *member_list, size_t member_list_entries,
+ const struct cpg_address *left_list, size_t left_list_entries,
+ const struct cpg_address *joined_list, size_t joined_list_entries)
+{
+}
+
+static cpg_callbacks_t callbacks = {
+ cpg_deliver_fn,
+ cpg_confchg_fn
+};
+
+static void sigintr_handler (int num)
+{
+ exit (1);
+}
+
+#define ITERATIONS 100
+#define ALLOCATIONS 2000
+#define MAX_SIZE 100000
+int main (void)
+{
+ cs_error_t res;
+ cpg_handle_t handle;
+ size_t buffer_lens[ALLOCATIONS];
+ void *buffers[ALLOCATIONS];
+ int i, j;
+
+ printf ("stress cpgzc running %d allocations for %d iterations\n",
+ ALLOCATIONS, ITERATIONS);
+
+ signal (SIGINT, sigintr_handler);
+
+ res = cpg_initialize (&handle, &callbacks);
+ if (res != CS_OK) {
+ printf ("FAIL %d\n", res);
+ exit (-1);
+ }
+
+ for (j = 0; j < ITERATIONS; j++) {
+ for (i = 0; i < ALLOCATIONS; i++) {
+ buffer_lens[i] = (random() % MAX_SIZE) + 1;
+ res = cpg_zcb_alloc (
+ handle,
+ buffer_lens[i],
+ &buffers[i]);
+ if (res != CS_OK) {
+ printf ("FAIL %d\n", res);
+ exit (-1);
+ }
+ }
+
+ for (i = 0; i < ALLOCATIONS; i++) {
+ res = cpg_zcb_free (
+ handle,
+ buffers[i]);
+ if (res != CS_OK) {
+ printf ("FAIL %d\n", res);
+ exit (-1);
+ }
+ }
+
+ if ((j != 0) &&
+ (j % 20) == 0) {
+ printf ("iteration %d\n", j);
+ }
+ }
+
+ cpg_finalize (handle);
+
+ printf ("PASS\n");
+ exit (0);
+}
diff --git a/test/testcfg.c b/test/testcfg.c
new file mode 100644
index 0000000..fa98cc2
--- /dev/null
+++ b/test/testcfg.c
@@ -0,0 +1,159 @@
+/*
+ * Copyright (c) 2021 Red Hat Inc
+ *
+ * All rights reserved.
+ *
+ * Author: Christine Caulfield <ccaulfie@redhat.com>
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of the MontaVista Software, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include <inttypes.h>
+#include <stdio.h>
+#include <errno.h>
+#include <pthread.h>
+
+#include <corosync/corotypes.h>
+#include <corosync/cfg.h>
+
+static void shutdown_callback(corosync_cfg_handle_t handle, corosync_cfg_shutdown_flags_t flags)
+{
+ /* Prevent shutdown */
+ printf("In shutdown callback - denying corosync shutdown\n");
+ corosync_cfg_replyto_shutdown(handle, COROSYNC_CFG_SHUTDOWN_FLAG_NO);
+}
+
+static void *dispatch_thread(void *arg)
+{
+ corosync_cfg_handle_t handle = (corosync_cfg_handle_t) arg;
+ int res = CS_OK;
+ while (res == CS_OK) {
+ res = corosync_cfg_dispatch(handle, CS_DISPATCH_ONE);
+ }
+ fprintf(stderr, "ERROR: Corosync shut down\n");
+ return (void*)0;
+}
+
+
+int main (int argc, char *argv[]) {
+ corosync_cfg_handle_t cfg_handle;
+ corosync_cfg_handle_t cfg_handle1;
+ unsigned int local_nodeid;
+ int i;
+ int res;
+ struct corosync_cfg_node_status_v1 ns;
+ pthread_t thread;
+ corosync_cfg_callbacks_t callbacks = {
+ .corosync_cfg_shutdown_callback = shutdown_callback
+ };
+
+ res = corosync_cfg_initialize(&cfg_handle, &callbacks);
+ if (res != CS_OK) {
+ fprintf(stderr, "corosync_Cfg_initialize(0) failed: %d\n", res);
+ return 1;
+ }
+
+ /* Start a new handle & thread to prevent the shutdown we request later on */
+ res = corosync_cfg_initialize(&cfg_handle1, &callbacks);
+ if (res != CS_OK) {
+ fprintf(stderr, "corosync_cfg_initialize(1) failed: %d\n", res);
+ return 1;
+ }
+ res = corosync_cfg_trackstart(cfg_handle1, 0);
+ if (res != CS_OK) {
+ fprintf(stderr, "corosync_cfg_initialize(1) failed: %d\n", res);
+ return 1;
+ }
+ res = pthread_create(&thread, NULL, dispatch_thread, (void*)cfg_handle1);
+ if (res != 0) {
+ perror("pthread_create failed");
+ return 1;
+ }
+
+ /* Exercise a few functions */
+ res = corosync_cfg_local_get(cfg_handle, &local_nodeid);
+ if (res != CS_OK) {
+ fprintf(stderr, "corosync_cfg_local_get failed: %d\n", res);
+ return 1;
+ }
+
+ printf("Local nodeid is %d\n", local_nodeid);
+
+ /*
+ * Test node_status_get.
+ * node status for the local node looks odd (cos it's the loopback connection), so
+ * we try for a node ID one less or more than us just to get output that looks
+ * sensible to the user.
+ */
+ res = corosync_cfg_node_status_get(cfg_handle, local_nodeid-1, CFG_NODE_STATUS_V1, &ns);
+ if (res != CS_OK) {
+ res = corosync_cfg_node_status_get(cfg_handle, local_nodeid+1, CFG_NODE_STATUS_V1, &ns);
+ }
+ if (res != CS_OK) {
+ fprintf(stderr, "corosync_cfg_node_status_get failed: %d\n", res);
+ return 1;
+ }
+ printf("Node Status for nodeid %d\n", ns.nodeid);
+ printf(" reachable: %d\n", ns.reachable);
+ printf(" remote: %d\n", ns.remote);
+ printf(" onwire_min: %d\n", ns.onwire_min);
+ printf(" onwire_max: %d\n", ns.onwire_max);
+ printf(" onwire_ver: %d\n", ns.onwire_ver);
+ for (i = 0; i<CFG_MAX_LINKS; i++) {
+ if (ns.link_status[i].enabled) {
+ printf(" Link %d\n", i);
+ printf(" connected: %d\n", ns.link_status[i].connected);
+ printf(" mtu: %d\n", ns.link_status[i].mtu);
+ printf(" src: %s\n", ns.link_status[i].src_ipaddr);
+ printf(" dst: %s\n", ns.link_status[i].dst_ipaddr);
+ }
+ }
+
+ /* This shutdown request should be denied by the thread */
+ res = corosync_cfg_try_shutdown(cfg_handle, COROSYNC_CFG_SHUTDOWN_FLAG_REQUEST);
+
+ if (res == CS_OK) {
+ fprintf(stderr, "ERROR: corosync_cfg_try_shutdown suceeded. should have been prevented\n");
+ }
+ if (res != CS_ERR_BUSY && res != CS_OK) {
+ fprintf(stderr, "corosync_cfg_try_shutdown failed: %d\n", res);
+ return 1;
+ }
+
+ /*
+ * Test bug presented in 3.1.1 and 3.1.2 that makes trackstop blocks forever
+ */
+ res = corosync_cfg_trackstop(cfg_handle1);
+ if (res != CS_OK) {
+ fprintf(stderr, "corosync_cfg_trackstop failed: %d\n", res);
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/test/testcpg.c b/test/testcpg.c
new file mode 100644
index 0000000..68c2929
--- /dev/null
+++ b/test/testcpg.c
@@ -0,0 +1,438 @@
+/*
+ * Copyright (c) 2006-2009 Red Hat Inc
+ *
+ * All rights reserved.
+ *
+ * Author: Christine Caulfield <ccaulfie@redhat.com>
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of the MontaVista Software, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/select.h>
+#include <sys/uio.h>
+#include <sys/un.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <time.h>
+#include <sys/time.h>
+#include <assert.h>
+#include <limits.h>
+
+#include <corosync/corotypes.h>
+#include <corosync/cpg.h>
+#include <corosync/swab.h>
+
+#ifdef QBLOG
+#include <qb/qblog.h>
+#endif
+
+#ifndef HOST_NAME_MAX
+#define HOST_NAME_MAX _POSIX_HOST_NAME_MAX
+#endif
+
+static int quit = 0;
+static int show_ip = 0;
+static int restart = 0;
+static uint32_t nodeidStart = 0;
+
+static void print_localnodeid(cpg_handle_t handle);
+
+static void print_cpgname (const struct cpg_name *name)
+{
+ unsigned int i;
+
+ for (i = 0; i < name->length; i++) {
+ printf ("%c", name->value[i]);
+ }
+}
+
+static char * node_pid_format(unsigned int nodeid, unsigned int pid) {
+ static char buffer[100];
+ if (show_ip) {
+ struct in_addr saddr;
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+ saddr.s_addr = swab32(nodeid);
+#else
+ saddr.s_addr = nodeid;
+#endif
+ sprintf(buffer, "node/pid %s/%d", inet_ntoa(saddr),pid);
+ }
+ else {
+ sprintf(buffer, "node/pid " CS_PRI_NODE_ID "/%d", nodeid, pid);
+ }
+ return buffer;
+}
+
+static void
+print_time(void)
+{
+#define MAXLEN (256)
+ char buf[MAXLEN];
+ char hostname[HOST_NAME_MAX];
+ struct timeval tnow;
+ time_t t;
+ size_t len;
+ char *s = buf;
+
+ len = sizeof(hostname);
+ if(gethostname(hostname, len) == 0) {
+ char *longName;
+ hostname[len-1] = '\0';
+ longName = hostname;
+ if( (longName = strstr( hostname, "." )) != NULL )
+ *longName = '\0';
+ }
+
+ strcpy(s, hostname);
+ s += strlen(hostname);
+ s += snprintf(s, sizeof(buf)-(s-buf), ":%d", getpid());
+ t = time(0);
+ gettimeofday( &tnow, 0 );
+ s += strftime(s, sizeof(buf)-(s-buf) , " %Y-%m-%d %T", localtime(&t));
+ s += snprintf(s, sizeof(buf)-(s-buf), ".%03ld", tnow.tv_usec/1000);
+ assert(s-buf < (int)sizeof(buf));
+ printf("%s\n", buf);
+}
+
+
+static void DeliverCallback (
+ cpg_handle_t handle,
+ const struct cpg_name *groupName,
+ uint32_t nodeid,
+ uint32_t pid,
+ void *msg,
+ size_t msg_len)
+{
+ print_time();
+ printf("DeliverCallback: message (len=%lu)from %s: '%s'\n",
+ (unsigned long int) msg_len, node_pid_format(nodeid, pid),
+ (const char *)msg);
+}
+
+static void ConfchgCallback (
+ cpg_handle_t handle,
+ const struct cpg_name *groupName,
+ const struct cpg_address *member_list, size_t member_list_entries,
+ const struct cpg_address *left_list, size_t left_list_entries,
+ const struct cpg_address *joined_list, size_t joined_list_entries)
+{
+ unsigned int i;
+ int result;
+ uint32_t nodeid;
+
+ print_time();
+ printf("ConfchgCallback: group '");
+ print_cpgname(groupName);
+ printf("'\n");
+ print_localnodeid(handle);
+
+ for (i=0; i<joined_list_entries; i++) {
+ printf("joined %s reason: %d\n",
+ node_pid_format(joined_list[i].nodeid, joined_list[i].pid),
+ joined_list[i].reason);
+ }
+
+ for (i=0; i<left_list_entries; i++) {
+ printf("left %s reason: %d\n",
+ node_pid_format(left_list[i].nodeid, left_list[i].pid),
+ left_list[i].reason);
+ }
+
+ printf("nodes in group now %lu\n",
+ (unsigned long int) member_list_entries);
+ for (i=0; i<member_list_entries; i++) {
+ printf("%s\n",
+ node_pid_format(member_list[i].nodeid, member_list[i].pid));
+ }
+
+ result = cpg_local_get(handle, &nodeid);
+ if(result != CS_OK) {
+ printf("failed to get local nodeid %d\n", result);
+ nodeid = 0;
+ }
+ /* Is it us??
+ NOTE: in reality we should also check the nodeid */
+ if (left_list_entries && (pid_t)left_list[0].pid == getpid()) {
+ printf("We might have left the building pid %d\n", left_list[0].pid);
+ /* can only use nodeidStart as a reliable check (version <= 1.4.2) */
+ if(nodeidStart) {
+ /* report dynamic nature of nodeid returned from local_get */
+ /* local get of nodeid might change identity from original! */
+ if(htonl((uint32_t)nodeid) == INADDR_LOOPBACK) {
+ printf("We probably left the building switched identity? start nodeid " CS_PRI_NODE_ID " nodeid " CS_PRI_NODE_ID " current nodeid " CS_PRI_NODE_ID " pid %d\n", nodeidStart, left_list[0].nodeid, nodeid, left_list[0].pid);
+ } else if(htonl((uint32_t)left_list[0].nodeid) == INADDR_LOOPBACK) {
+ printf("We probably left the building started alone? start nodeid " CS_PRI_NODE_ID " nodeid " CS_PRI_NODE_ID " current nodeid " CS_PRI_NODE_ID " pid %d\n", nodeidStart, left_list[0].nodeid, nodeid, left_list[0].pid);
+ }
+ /* a possibly reliable way to check is based on original address */
+ if(left_list[0].nodeid == nodeidStart) {
+ printf("We have left the building direct match start nodeid " CS_PRI_NODE_ID " nodeid " CS_PRI_NODE_ID " local get current nodeid " CS_PRI_NODE_ID " pid %d\n", nodeidStart, left_list[0].nodeid, nodeid, left_list[0].pid);
+ // quit = 1;
+ restart = 1;
+ } else {
+ printf("Probably another node with matching pid start nodeid " CS_PRI_NODE_ID " nodeid " CS_PRI_NODE_ID " current nodeid " CS_PRI_NODE_ID " pid %d\n", nodeidStart, left_list[0].nodeid, nodeid, left_list[0].pid);
+ }
+ }
+ }
+}
+
+static void TotemConfchgCallback (
+ cpg_handle_t handle,
+ struct cpg_ring_id ring_id,
+ uint32_t member_list_entries,
+ const uint32_t *member_list)
+{
+ unsigned int i;
+
+ printf("\n");
+ print_time();
+ printf ("TotemConfchgCallback: ringid (" CS_PRI_RING_ID ")\n",
+ ring_id.nodeid, ring_id.seq);
+
+ printf("active processors %lu: ",
+ (unsigned long int) member_list_entries);
+ for (i=0; i<member_list_entries; i++) {
+ printf(CS_PRI_NODE_ID " ", member_list[i]);
+ }
+ printf ("\n");
+}
+
+static cpg_model_v1_data_t model_data = {
+ .cpg_deliver_fn = DeliverCallback,
+ .cpg_confchg_fn = ConfchgCallback,
+ .cpg_totem_confchg_fn = TotemConfchgCallback,
+ .flags = CPG_MODEL_V1_DELIVER_INITIAL_TOTEM_CONF,
+};
+
+static struct cpg_name group_name;
+
+#define retrybackoff(counter) { \
+ counter++; \
+ printf("Restart operation after %ds\n", counter); \
+ sleep((unsigned int)counter); \
+ restart = 1; \
+ continue; \
+}
+
+#define cs_repeat_init(counter, max, code) do { \
+ code; \
+ if (result == CS_ERR_TRY_AGAIN || result == CS_ERR_QUEUE_FULL || result == CS_ERR_LIBRARY) { \
+ counter++; \
+ printf("Retrying operation after %ds\n", counter); \
+ sleep((unsigned int)counter); \
+ } else { \
+ break; \
+ } \
+} while (counter < max)
+
+#define cs_repeat(counter, max, code) do { \
+ code; \
+ if (result == CS_ERR_TRY_AGAIN || result == CS_ERR_QUEUE_FULL) { \
+ counter++; \
+ printf("Retrying operation after %ds\n", counter); \
+ sleep((unsigned int)counter); \
+ } else { \
+ break; \
+ } \
+} while (counter < max)
+
+static void print_localnodeid(cpg_handle_t handle)
+{
+ char addrStr[128];
+ unsigned int retries;
+ unsigned int nodeid;
+ struct sockaddr_storage addr;
+ struct sockaddr_in *v4addr = (struct sockaddr_in *)&addr;
+ int result;
+
+ retries = 0;
+
+ cs_repeat(retries, 30, result = cpg_local_get(handle, &nodeid));
+ if (result != CS_OK) {
+ printf ("Could not get local node id\n");
+ } else {
+ v4addr->sin_addr.s_addr = nodeid;
+ if(inet_ntop(AF_INET, (const void *)&v4addr->sin_addr.s_addr,
+ addrStr, (socklen_t)sizeof(addrStr)) == NULL) {
+ addrStr[0] = 0;
+ }
+ printf ("Local node id is %s/" CS_PRI_NODE_ID " result %d\n", addrStr, nodeid, result);
+ }
+}
+
+int main (int argc, char *argv[]) {
+ cpg_handle_t handle;
+ fd_set read_fds;
+ int select_fd;
+ int result;
+ int retries;
+ const char *options = "i";
+ int opt;
+ unsigned int nodeid;
+ char *fgets_res;
+ struct cpg_address member_list[CPG_MEMBERS_MAX];
+ int member_list_entries;
+ int i;
+ int recnt;
+ int doexit;
+ const char *exitStr = "EXIT";
+
+ doexit = 0;
+
+#ifdef QBLOG
+ qb_log_init("testcpg", LOG_USER, LOG_ERR);
+ qb_log_ctl(QB_LOG_SYSLOG, QB_LOG_CONF_ENABLED, QB_FALSE);
+ qb_log_filter_ctl(QB_LOG_STDERR, QB_LOG_FILTER_ADD,
+ QB_LOG_FILTER_FILE, "*", LOG_TRACE);
+ qb_log_ctl(QB_LOG_STDERR, QB_LOG_CONF_ENABLED, QB_TRUE);
+ qb_log_format_set(QB_LOG_STDERR, "[%p] %f %b");
+#endif
+
+ while ( (opt = getopt(argc, argv, options)) != -1 ) {
+ switch (opt) {
+ case 'i':
+ show_ip = 1;
+ break;
+ }
+ }
+
+ if (argc > optind) {
+ if (strlen(argv[optind]) >= CPG_MAX_NAME_LENGTH) {
+ fprintf(stderr, "Invalid name for cpg group\n");
+ return (1);
+ }
+
+ strcpy(group_name.value, argv[optind]);
+ group_name.length = strlen(argv[optind]);
+ }
+ else {
+ strcpy(group_name.value, "GROUP");
+ group_name.length = 6;
+ }
+ recnt = 0;
+
+ printf ("Type %s to finish\n", exitStr);
+ restart = 1;
+
+ do {
+ if(restart) {
+ restart = 0;
+ retries = 0;
+ cs_repeat_init(retries, 30, result = cpg_model_initialize (&handle, CPG_MODEL_V1, (cpg_model_data_t *)&model_data, NULL));
+ if (result != CS_OK) {
+ printf ("Could not initialize Cluster Process Group API instance error %d\n", result);
+ retrybackoff(recnt);
+ }
+ retries = 0;
+ cs_repeat(retries, 30, result = cpg_local_get(handle, &nodeid));
+ if (result != CS_OK) {
+ printf ("Could not get local node id\n");
+ retrybackoff(recnt);
+ }
+ printf ("Local node id is " CS_PRI_NODE_ID "\n", nodeid);
+ nodeidStart = nodeid;
+
+ retries = 0;
+ cs_repeat(retries, 30, result = cpg_join(handle, &group_name));
+ if (result != CS_OK) {
+ printf ("Could not join process group, error %d\n", result);
+ retrybackoff(recnt);
+ }
+
+ retries = 0;
+ cs_repeat(retries, 30, result = cpg_membership_get (handle, &group_name,
+ (struct cpg_address *)&member_list, &member_list_entries));
+ if (result != CS_OK) {
+ printf ("Could not get current membership list %d\n", result);
+ retrybackoff(recnt);
+ }
+ recnt = 0;
+
+ printf ("membership list\n");
+ for (i = 0; i < member_list_entries; i++) {
+ printf ("node id " CS_PRI_NODE_ID " pid %d\n", member_list[i].nodeid,
+ member_list[i].pid);
+ }
+
+ FD_ZERO (&read_fds);
+ cpg_fd_get(handle, &select_fd);
+ }
+ FD_SET (select_fd, &read_fds);
+ FD_SET (STDIN_FILENO, &read_fds);
+ result = select (select_fd + 1, &read_fds, 0, 0, 0);
+ if (result == -1) {
+ perror ("select\n");
+ }
+ if (FD_ISSET (STDIN_FILENO, &read_fds)) {
+ char inbuf[132];
+ struct iovec iov;
+
+ fgets_res = fgets(inbuf, (int)sizeof(inbuf), stdin);
+ if (fgets_res == NULL) {
+ doexit = 1;
+ cpg_leave(handle, &group_name);
+ }
+ if (strncmp(inbuf, exitStr, strlen(exitStr)) == 0) {
+ doexit = 1;
+ cpg_leave(handle, &group_name);
+ }
+ else {
+ iov.iov_base = inbuf;
+ iov.iov_len = strlen(inbuf)+1;
+ cpg_mcast_joined(handle, CPG_TYPE_AGREED, &iov, 1);
+ }
+ }
+ if (FD_ISSET (select_fd, &read_fds)) {
+ if (cpg_dispatch (handle, CS_DISPATCH_ALL) != CS_OK) {
+ if(doexit) {
+ exit(1);
+ }
+ restart = 1;
+ }
+ }
+ if(restart) {
+ if(!doexit) {
+ result = cpg_finalize (handle);
+ printf ("Finalize+restart result is %d (should be 1)\n", result);
+ continue;
+ }
+ }
+ } while (result && !quit && !doexit);
+
+ result = cpg_finalize (handle);
+ printf ("Finalize result is %d (should be 1)\n", result);
+ return (0);
+}
diff --git a/test/testcpg2.c b/test/testcpg2.c
new file mode 100644
index 0000000..d779cf3
--- /dev/null
+++ b/test/testcpg2.c
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2007, 2009 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Author: Alan Conway <aconway@redhat.com>
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of the MontaVista Software, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include <assert.h>
+#include <stdio.h>
+#include <poll.h>
+#include <inttypes.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/uio.h>
+
+#include <corosync/corotypes.h>
+#include <corosync/cpg.h>
+
+static void deliver(
+ cpg_handle_t handle,
+ const struct cpg_name *group_name,
+ uint32_t nodeid,
+ uint32_t pid,
+ void *msg,
+ size_t msg_len)
+{
+ printf("self delivered nodeid: " CS_PRI_NODE_ID "\n", nodeid);
+}
+
+static void confch(
+ cpg_handle_t handle,
+ const struct cpg_name *group_name,
+ const struct cpg_address *member_list, size_t member_list_entries,
+ const struct cpg_address *left_list, size_t left_list_entries,
+ const struct cpg_address *joined_list, size_t joined_list_entries)
+{
+ printf("confchg nodeid " CS_PRI_NODE_ID "\n", member_list[0].nodeid);
+}
+
+int main(int argc, char** argv) {
+ cpg_handle_t handle=0;
+ cpg_callbacks_t cb={&deliver,&confch};
+ unsigned int nodeid=0;
+ struct cpg_name group={3,"foo"};
+ struct iovec msg={(void *)"hello", 5}; /* discard const */
+
+ struct pollfd pfd;
+ int fd;
+
+ printf ("All of the nodeids should match on a single node configuration\n for the test to pass.");
+ assert(CS_OK==cpg_initialize(&handle, &cb));
+ assert(CS_OK==cpg_local_get(handle,&nodeid));
+ printf("local_get: " CS_PRI_NODE_ID "\n", nodeid);
+ assert(CS_OK==cpg_join(handle, &group));
+ assert(CS_OK==cpg_mcast_joined(handle,CPG_TYPE_AGREED,&msg,1));
+ cpg_fd_get (handle, &fd);
+ pfd.fd = fd;
+ pfd.events = POLLIN;
+
+ assert(poll (&pfd, 1, 1000) == 1);
+ assert(cpg_dispatch(handle, CS_DISPATCH_ALL) == CS_OK);
+ return (0);
+}
diff --git a/test/testcpgzc.c b/test/testcpgzc.c
new file mode 100644
index 0000000..6da36a1
--- /dev/null
+++ b/test/testcpgzc.c
@@ -0,0 +1,248 @@
+/*
+ * Copyright (c) 2006-2009 Red Hat Inc
+ *
+ * All rights reserved.
+ *
+ * Author: Christine Caulfield <ccaulfie@redhat.com>
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of the MontaVista Software, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <unistd.h>
+#include <string.h>
+#include <inttypes.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/select.h>
+#include <sys/un.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include <corosync/corotypes.h>
+#include <corosync/cpg.h>
+
+#define BUFFER_SIZE 8192
+#define DEFAULT_GROUP_NAME "GROUP"
+
+static int quit = 0;
+static int show_ip = 0;
+
+static void print_cpgname (const struct cpg_name *name)
+{
+ int i;
+
+ for (i = 0; i < name->length; i++) {
+ printf ("%c", name->value[i]);
+ }
+}
+
+static void DeliverCallback (
+ cpg_handle_t handle,
+ const struct cpg_name *groupName,
+ uint32_t nodeid,
+ uint32_t pid,
+ void *msg,
+ size_t msg_len)
+{
+ if (show_ip) {
+ struct in_addr saddr;
+ saddr.s_addr = nodeid;
+ printf("DeliverCallback: message (len=%lu)from node/pid %s/%d: '%s'\n",
+ (unsigned long int) msg_len,
+ inet_ntoa(saddr), pid, (const char *)msg);
+ }
+ else {
+ printf("DeliverCallback: message (len=%lu)from node/pid " CS_PRI_NODE_ID "/%d: '%s'\n",
+ (unsigned long int) msg_len, nodeid, pid,
+ (const char *)msg);
+ }
+}
+
+static void ConfchgCallback (
+ cpg_handle_t handle,
+ const struct cpg_name *groupName,
+ const struct cpg_address *member_list, size_t member_list_entries,
+ const struct cpg_address *left_list, size_t left_list_entries,
+ const struct cpg_address *joined_list, size_t joined_list_entries)
+{
+ int i;
+ struct in_addr saddr;
+
+ printf("\nConfchgCallback: group '");
+ print_cpgname(groupName);
+ printf("'\n");
+ for (i=0; i<joined_list_entries; i++) {
+ if (show_ip) {
+ saddr.s_addr = joined_list[i].nodeid;
+ printf("joined node/pid: %s/%d reason: %d\n",
+ inet_ntoa (saddr), joined_list[i].pid,
+ joined_list[i].reason);
+ }
+ else {
+ printf("joined node/pid: " CS_PRI_NODE_ID "/%d reason: %d\n",
+ joined_list[i].nodeid, joined_list[i].pid,
+ joined_list[i].reason);
+ }
+ }
+
+ for (i=0; i<left_list_entries; i++) {
+ if (show_ip) {
+ saddr.s_addr = left_list[i].nodeid;
+ printf("left node/pid: %s/%d reason: %d\n",
+ inet_ntoa (saddr), left_list[i].pid,
+ left_list[i].reason);
+ }
+ else {
+ printf("left node/pid: " CS_PRI_NODE_ID "/%d reason: %d\n",
+ left_list[i].nodeid, left_list[i].pid,
+ left_list[i].reason);
+ }
+ }
+
+ printf("nodes in group now %lu\n",
+ (unsigned long int) member_list_entries);
+ for (i=0; i<member_list_entries; i++) {
+ if (show_ip) {
+ saddr.s_addr = member_list[i].nodeid;
+ printf("node/pid: %s/%d\n",
+ inet_ntoa (saddr), member_list[i].pid);
+ }
+ else {
+ printf("node/pid: " CS_PRI_NODE_ID "/%d\n",
+ member_list[i].nodeid, member_list[i].pid);
+ }
+ }
+
+ /* Is it us??
+ NOTE: in reality we should also check the nodeid */
+ if (left_list_entries && left_list[0].pid == getpid()) {
+ printf("We have left the building\n");
+ quit = 1;
+ }
+}
+
+static cpg_callbacks_t callbacks = {
+ .cpg_deliver_fn = DeliverCallback,
+ .cpg_confchg_fn = ConfchgCallback,
+};
+
+static struct cpg_name group_name;
+
+int main (int argc, char *argv[]) {
+ cpg_handle_t handle;
+ fd_set read_fds;
+ int select_fd;
+ int result;
+ const char *options = "i";
+ int opt;
+ unsigned int nodeid;
+ char *fgets_res;
+ void *buffer;
+
+ while ( (opt = getopt(argc, argv, options)) != -1 ) {
+ switch (opt) {
+ case 'i':
+ show_ip = 1;
+ break;
+ }
+ }
+
+ if (argc > optind) {
+ if (strlen(argv[optind]) >= CPG_MAX_NAME_LENGTH) {
+ fprintf(stderr, "Invalid name for cpg group\n");
+ return (1);
+ }
+
+ strcpy(group_name.value, argv[optind]);
+ group_name.length = strlen(argv[optind])+1;
+ }
+ else {
+ strcpy(group_name.value, DEFAULT_GROUP_NAME);
+ group_name.length = strlen(DEFAULT_GROUP_NAME) + 1;
+ }
+
+ result = cpg_initialize (&handle, &callbacks);
+ if (result != CS_OK) {
+ printf ("Could not initialize Cluster Process Group API instance error %d\n", result);
+ exit (1);
+ }
+ cpg_zcb_alloc (handle, BUFFER_SIZE, &buffer);
+ cpg_zcb_free (handle, buffer);
+ cpg_zcb_alloc (handle, BUFFER_SIZE, &buffer);
+
+ result = cpg_local_get (handle, &nodeid);
+ if (result != CS_OK) {
+ printf ("Could not get local node id\n");
+ exit (1);
+ }
+
+ printf ("Local node id is " CS_PRI_NODE_ID "\n", nodeid);
+ result = cpg_join(handle, &group_name);
+ if (result != CS_OK) {
+ printf ("Could not join process group, error %d\n", result);
+ exit (1);
+ }
+
+ FD_ZERO (&read_fds);
+ cpg_fd_get(handle, &select_fd);
+ printf ("Type EXIT to finish\n");
+ do {
+ FD_SET (select_fd, &read_fds);
+ FD_SET (STDIN_FILENO, &read_fds);
+ result = select (select_fd + 1, &read_fds, 0, 0, 0);
+ if (result == -1) {
+ perror ("select\n");
+ }
+ if (FD_ISSET (STDIN_FILENO, &read_fds)) {
+ fgets_res = fgets(buffer, BUFFER_SIZE, stdin);
+ if (fgets_res == NULL) {
+ cpg_leave(handle, &group_name);
+ }
+ if (strncmp(buffer, "EXIT", 4) == 0) {
+ cpg_leave(handle, &group_name);
+ }
+ else {
+ cpg_zcb_mcast_joined (handle, CPG_TYPE_AGREED,
+ buffer, strlen (buffer) + 1);
+ }
+ }
+ if (FD_ISSET (select_fd, &read_fds)) {
+ if (cpg_dispatch (handle, CS_DISPATCH_ALL) != CS_OK)
+ exit(1);
+ }
+ } while (result && !quit);
+
+
+ result = cpg_finalize (handle);
+ printf ("Finalize result is %d (should be 1)\n", result);
+ return (0);
+}
diff --git a/test/testquorum.c b/test/testquorum.c
new file mode 100644
index 0000000..1323b25
--- /dev/null
+++ b/test/testquorum.c
@@ -0,0 +1,64 @@
+#include <config.h>
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <inttypes.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <corosync/corotypes.h>
+#include <corosync/quorum.h>
+
+static quorum_handle_t g_handle;
+
+static void quorum_notification_fn(
+ quorum_handle_t handle,
+ uint32_t quorate,
+ uint64_t ring_id,
+ uint32_t view_list_entries,
+ uint32_t *view_list)
+{
+ int i;
+
+ printf("quorum notification called \n");
+ printf(" quorate = %lu\n", (long unsigned int) quorate);
+ printf(" ring id = " CS_PRI_RING_ID_SEQ "\n", ring_id);
+ printf(" num nodes = %lu ", (long unsigned int) view_list_entries);
+
+ for (i=0; i<view_list_entries; i++) {
+ printf(" " CS_PRI_NODE_ID, view_list[i]);
+ }
+ printf("\n");
+}
+
+
+int main(int argc, char *argv[])
+{
+ int quorate;
+ quorum_callbacks_t callbacks;
+ uint32_t quorum_type;
+ int err;
+
+ callbacks.quorum_notify_fn = quorum_notification_fn;
+ if ( (err=quorum_initialize(&g_handle, &callbacks, &quorum_type)) != CS_OK)
+ fprintf(stderr, "quorum_initialize FAILED: %d\n", err);
+
+ if ( (err=quorum_trackstart(g_handle, CS_TRACK_CHANGES)) != CS_OK)
+ fprintf(stderr, "quorum_trackstart FAILED: %d\n", err);
+
+ if ( (err=quorum_getquorate(g_handle, &quorate)) != CS_OK)
+ fprintf(stderr, "quorum_getquorate FAILED: %d\n", err);
+ else {
+ printf("quorate %d\n", quorate);
+ }
+
+ printf("Waiting for quorum events, press ^C to finish\n");
+ printf("-------------------\n");
+
+ if (quorum_dispatch(g_handle, CS_DISPATCH_BLOCKING) != CS_OK) {
+ fprintf(stderr, "Error from quorum_dispatch\n");
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/test/testquorummodel.c b/test/testquorummodel.c
new file mode 100644
index 0000000..94ff869
--- /dev/null
+++ b/test/testquorummodel.c
@@ -0,0 +1,102 @@
+#include <config.h>
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <inttypes.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <corosync/corotypes.h>
+#include <corosync/quorum.h>
+
+static quorum_handle_t g_handle;
+
+static void quorum_notification_fn(
+ quorum_handle_t handle,
+ uint32_t quorate,
+ struct quorum_ring_id ring_id,
+ uint32_t view_list_entries,
+ const uint32_t *view_list)
+{
+ int i;
+
+ printf("quorum notification called \n");
+ printf(" quorate = %lu\n", (long unsigned int) quorate);
+ printf(" ring id = " CS_PRI_RING_ID "\n", ring_id.nodeid, ring_id.seq);
+ printf(" num nodes = %lu ", (long unsigned int) view_list_entries);
+
+ for (i=0; i<view_list_entries; i++) {
+ printf(" " CS_PRI_NODE_ID, view_list[i]);
+ }
+ printf("\n");
+}
+
+static void nodelist_notification_fn(
+ quorum_handle_t handle,
+ struct quorum_ring_id ring_id,
+ uint32_t member_list_entries, const uint32_t *member_list,
+ uint32_t joined_list_entries, const uint32_t *joined_list,
+ uint32_t left_list_entries, const uint32_t *left_list)
+{
+ int i;
+
+ printf("nodelist notification called \n");
+ printf(" ring id = " CS_PRI_RING_ID "\n", ring_id.nodeid, ring_id.seq);
+ printf(" num members = %" PRIu32 " ", member_list_entries);
+
+ for (i=0; i<member_list_entries; i++) {
+ printf(" " CS_PRI_NODE_ID, member_list[i]);
+ }
+ printf("\n");
+
+ printf(" num joined members = %" PRIu32 " ", joined_list_entries);
+ for (i=0; i<joined_list_entries; i++) {
+ printf(" " CS_PRI_NODE_ID, joined_list[i]);
+ }
+ printf("\n");
+
+ printf(" num left members = %" PRIu32 " ", left_list_entries);
+ for (i=0; i<left_list_entries; i++) {
+ printf(" " CS_PRI_NODE_ID, left_list[i]);
+ }
+ printf("\n");
+
+}
+
+int main(int argc, char *argv[])
+{
+ int quorate;
+ quorum_model_v1_data_t model_data;
+ uint32_t quorum_type;
+ int err;
+
+ memset(&model_data, 0, sizeof(model_data));
+ model_data.quorum_notify_fn = quorum_notification_fn;
+ model_data.nodelist_notify_fn = nodelist_notification_fn;
+
+ if ( (err=quorum_model_initialize (&g_handle, QUORUM_MODEL_V1,
+ (quorum_model_data_t *)&model_data, &quorum_type, NULL)) != CS_OK) {
+ fprintf(stderr, "quorum_initialize FAILED: %d\n", err);
+ exit(1);
+ }
+
+ if ( (err=quorum_trackstart(g_handle, CS_TRACK_CHANGES)) != CS_OK)
+ fprintf(stderr, "quorum_trackstart FAILED: %d\n", err);
+
+ if ( (err=quorum_getquorate(g_handle, &quorate)) != CS_OK)
+ fprintf(stderr, "quorum_getquorate FAILED: %d\n", err);
+ else {
+ printf("quorate %d\n", quorate);
+ }
+
+ printf("Waiting for quorum events, press ^C to finish\n");
+ printf("-------------------\n");
+
+ if (quorum_dispatch(g_handle, CS_DISPATCH_BLOCKING) != CS_OK) {
+ fprintf(stderr, "Error from quorum_dispatch\n");
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/test/testsam.c b/test/testsam.c
new file mode 100644
index 0000000..d31262a
--- /dev/null
+++ b/test/testsam.c
@@ -0,0 +1,1476 @@
+/*
+ * Copyright (c) 2009-2011 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Author: Jan Friesse (jfriesse@redhat.com)
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of the Red Hat, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Provides test of SAM API
+ */
+
+#include <config.h>
+
+#include <limits.h>
+#include <pthread.h>
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <corosync/corotypes.h>
+#include <corosync/sam.h>
+#include <signal.h>
+#include <string.h>
+#include <sys/wait.h>
+#include <corosync/cmap.h>
+extern const char *__progname;
+
+static int test2_sig_delivered = 0;
+static int test5_hc_cb_count = 0;
+static int test6_sig_delivered = 0;
+
+/*
+ * First test will just register SAM, with policy restart. First instance will
+ * sleep one second, send hc and sleep another 3 seconds. This should force restart.
+ * Second instance will sleep one second, send hc, stop hc and sleep 3 seconds.
+ * Then start hc again and sleep 3 seconds. This should force restart again.
+ * Last instance just calls initialize again. This should end with error.
+ * Then call start, followed by stop and start again. Finally, we will call finalize
+ * twice. One should succeed, second should fail. After this, we will call every function
+ * (none should succeed).
+ */
+static int test1 (void)
+{
+ cs_error_t error;
+ unsigned int instance_id;
+ int i;
+
+ printf ("%s: initialize\n", __FUNCTION__);
+ error = sam_initialize (2000, SAM_RECOVERY_POLICY_RESTART);
+ if (error != CS_OK) {
+ fprintf (stderr, "Can't initialize SAM API. Error %d\n", error);
+ return 1;
+ }
+ printf ("%s: register\n", __FUNCTION__);
+ error = sam_register (&instance_id);
+ if (error != CS_OK) {
+ fprintf (stderr, "Can't register. Error %d\n", error);
+ return 1;
+ }
+
+ if (instance_id == 1 || instance_id == 2) {
+ printf ("%s iid %d: start\n", __FUNCTION__, instance_id);
+ error = sam_start ();
+ if (error != CS_OK) {
+ fprintf (stderr, "Can't start hc. Error %d\n", error);
+ return 1;
+ }
+
+ for (i = 0; i < 10; i++) {
+ printf ("%s iid %d: sleep 1\n", __FUNCTION__, instance_id);
+ sleep (1);
+
+ printf ("%s iid %d: hc send\n", __FUNCTION__, instance_id);
+ error = sam_hc_send ();
+ if (error != CS_OK) {
+ fprintf (stderr, "Can't send hc. Error %d\n", error);
+ return 1;
+ }
+ }
+
+ if (instance_id == 2) {
+ printf ("%s iid %d: stop\n", __FUNCTION__, instance_id);
+ error = sam_stop ();
+
+ if (error != CS_OK) {
+ fprintf (stderr, "Can't send hc. Error %d\n", error);
+ return 1;
+ }
+ }
+
+ printf ("%s iid %d: sleep 3\n", __FUNCTION__, instance_id);
+ sleep (3);
+
+ printf ("%s iid %d: start\n", __FUNCTION__, instance_id);
+ error = sam_start ();
+ if (error != CS_OK) {
+ fprintf (stderr, "Can't start hc. Error %d\n", error);
+ return 1;
+ }
+
+ printf ("%s iid %d: sleep 3\n", __FUNCTION__, instance_id);
+ sleep (3);
+ return 0;
+ }
+
+ if (instance_id == 3) {
+ error = sam_initialize (2000, SAM_RECOVERY_POLICY_RESTART);
+ if (error == CS_OK) {
+ fprintf (stderr, "Can initialize SAM API after initialization");
+ return 1;
+ }
+
+ error = sam_start ();
+ if (error != CS_OK) {
+ fprintf (stderr, "Can't start hc. Error %d\n", error);
+ return 1;
+ }
+ error = sam_stop ();
+ if (error != CS_OK) {
+ fprintf (stderr, "Can't stop hc. Error %d\n", error);
+ return 1;
+ }
+ error = sam_finalize ();
+ if (error != CS_OK) {
+ fprintf (stderr, "Can't finalize sam. Error %d\n", error);
+ return 1;
+ }
+ error = sam_finalize ();
+ if (error == CS_OK) {
+ fprintf (stderr, "Can finalize sam after finalization!\n");
+ return 1;
+ }
+
+ if (sam_initialize (2, SAM_RECOVERY_POLICY_RESTART) == CS_OK ||
+ sam_start () == CS_OK || sam_stop () == CS_OK ||
+ sam_register (NULL) == CS_OK || sam_hc_send () == CS_OK ||
+ sam_hc_callback_register (NULL) == CS_OK) {
+
+ fprintf (stderr, "Can call one of function after finalization!\n");
+
+ return 1;
+ }
+
+ return 0;
+ }
+
+ return 1;
+}
+
+
+static void test2_signal (int sig) {
+ printf ("%s\n", __FUNCTION__);
+
+ test2_sig_delivered = 1;
+}
+
+/*
+ * This tests recovery policy quit and callback.
+ */
+static int test2 (void) {
+ cs_error_t error;
+ unsigned int instance_id;
+
+ printf ("%s: initialize\n", __FUNCTION__);
+ error = sam_initialize (2000, SAM_RECOVERY_POLICY_QUIT);
+ if (error != CS_OK) {
+ fprintf (stderr, "Can't initialize SAM API. Error %d\n", error);
+ return 1;
+ }
+ printf ("%s: register\n", __FUNCTION__);
+ error = sam_register (&instance_id);
+ if (error != CS_OK) {
+ fprintf (stderr, "Can't register. Error %d\n", error);
+ return 1;
+ }
+
+ if (instance_id == 1) {
+ signal (SIGTERM, test2_signal);
+
+ printf ("%s iid %d: start\n", __FUNCTION__, instance_id);
+ error = sam_start ();
+ if (error != CS_OK) {
+ fprintf (stderr, "Can't start hc. Error %d\n", error);
+ return 1;
+ }
+
+ printf ("%s iid %d: sleep 1\n", __FUNCTION__, instance_id);
+ sleep (1);
+
+ printf ("%s iid %d: hc send\n", __FUNCTION__, instance_id);
+ error = sam_hc_send ();
+ if (error != CS_OK) {
+ fprintf (stderr, "Can't send hc. Error %d\n", error);
+ return 1;
+ }
+
+
+ printf ("%s iid %d: wait for delivery of signal\n", __FUNCTION__, instance_id);
+ while (!test2_sig_delivered) {
+ sleep (1);
+ }
+
+ printf ("%s iid %d: wait for real kill\n", __FUNCTION__, instance_id);
+
+ sleep (3);
+ }
+
+ return 1;
+
+}
+
+/*
+ * Smoke test. Better to turn off coredump ;) This has no time limit, just restart process
+ * when it dies.
+ */
+static int test3 (void) {
+ cs_error_t error;
+ unsigned int instance_id;
+
+ printf ("%s: initialize\n", __FUNCTION__);
+ error = sam_initialize (0, SAM_RECOVERY_POLICY_RESTART);
+ if (error != CS_OK) {
+ fprintf (stderr, "Can't initialize SAM API. Error %d\n", error);
+ return 1;
+ }
+ printf ("%s: register\n", __FUNCTION__);
+ error = sam_register (&instance_id);
+ if (error != CS_OK) {
+ fprintf (stderr, "Can't register. Error %d\n", error);
+ return 1;
+ }
+
+ if (instance_id < 100) {
+ printf ("%s iid %d: start\n", __FUNCTION__, instance_id);
+ error = sam_start ();
+ if (error != CS_OK) {
+ fprintf (stderr, "Can't start hc. Error %d\n", error);
+ return 1;
+ }
+
+ printf ("%s iid %d: Sending signal\n", __FUNCTION__, instance_id);
+ kill(getpid(), SIGSEGV);
+ return 1;
+ }
+
+ return 0;
+
+}
+
+/*
+ * Test sam_data_store, sam_data_restore and sam_data_getsize
+ */
+static int test4 (void)
+{
+ size_t size;
+ cs_error_t err;
+ int i;
+ unsigned int instance_id;
+ char saved_data[128];
+ char saved_data2[128];
+
+ printf ("%s: sam_data_getsize 1\n", __FUNCTION__);
+ err = sam_data_getsize (&size);
+ if (err != CS_ERR_BAD_HANDLE) {
+ fprintf (stderr, "Test should return CS_ERR_BAD_HANDLE. Error returned %d\n", err);
+ return 1;
+ }
+
+ printf ("%s: sam_data_getsize 2\n", __FUNCTION__);
+ err = sam_data_getsize (NULL);
+ if (err != CS_ERR_INVALID_PARAM) {
+ fprintf (stderr, "Test should return CS_ERR_INVALID_PARAM. Error returned %d\n", err);
+ return 1;
+ }
+
+ printf ("%s: sam_data_store 1\n", __FUNCTION__);
+ err = sam_data_store (NULL, 0);
+ if (err != CS_ERR_BAD_HANDLE) {
+ fprintf (stderr, "Test should return CS_ERR_BAD_HANDLE. Error returned %d\n", err);
+ return 1;
+ }
+
+ printf ("%s: sam_data_restore 1\n", __FUNCTION__);
+ err = sam_data_restore (saved_data, sizeof (saved_data));
+ if (err != CS_ERR_BAD_HANDLE) {
+ fprintf (stderr, "Test should return CS_ERR_BAD_HANDLE. Error returned %d\n", err);
+ return 1;
+ }
+
+ printf ("%s: sam_initialize\n", __FUNCTION__);
+ err = sam_initialize (0, SAM_RECOVERY_POLICY_RESTART);
+ if (err != CS_OK) {
+ fprintf (stderr, "Can't initialize SAM API. Error %d\n", err);
+ return 1;
+ }
+
+ printf ("%s: sam_data_getsize 3\n", __FUNCTION__);
+ err = sam_data_getsize (&size);
+ if (err != CS_OK) {
+ fprintf (stderr, "Test should return CS_ERR_BAD_HANDLE. Error returned %d\n", err);
+ return 1;
+ }
+ if (size != 0) {
+ fprintf (stderr, "Test should return size of 0. Returned %zx\n", size);
+ return 1;
+ }
+
+ printf ("%s: sam_data_restore 2\n", __FUNCTION__);
+ err = sam_data_restore (NULL, sizeof (saved_data));
+ if (err != CS_ERR_INVALID_PARAM) {
+ fprintf (stderr, "Test should return CS_ERR_INVALID_PARAM. Error returned %d\n", err);
+ return 1;
+ }
+
+ /*
+ * Store some real data
+ */
+ for (i = 0; i < sizeof (saved_data); i++) {
+ saved_data[i] = (char)(i + 5);
+ }
+
+ printf ("%s: sam_data_store 2\n", __FUNCTION__);
+ err = sam_data_store (saved_data, sizeof (saved_data));
+ if (err != CS_OK) {
+ fprintf (stderr, "Test should return CS_OK. Error returned %d\n", err);
+ return 1;
+ }
+
+ printf ("%s: sam_data_getsize 4\n", __FUNCTION__);
+ err = sam_data_getsize (&size);
+ if (err != CS_OK) {
+ fprintf (stderr, "Test should return CS_OK. Error returned %d\n", err);
+ return 1;
+ }
+ if (size != sizeof (saved_data)) {
+ fprintf (stderr, "Test should return size of 0. Returned %zx\n", size);
+ return 1;
+ }
+
+ printf ("%s: sam_data_restore 3\n", __FUNCTION__);
+ err = sam_data_restore (saved_data2, sizeof (saved_data2) - 1);
+ if (err != CS_ERR_INVALID_PARAM) {
+ fprintf (stderr, "Test should return CS_ERR_INVALID_PARAM. Error returned %d\n", err);
+ return 1;
+ }
+
+ printf ("%s: sam_data_restore 4\n", __FUNCTION__);
+ err = sam_data_restore (saved_data2, sizeof (saved_data2));
+ if (err != CS_OK) {
+ fprintf (stderr, "Test should return CS_OK. Error returned %d\n", err);
+ return 1;
+ }
+
+ if (memcmp (saved_data, saved_data2, sizeof (saved_data2)) != 0) {
+ fprintf (stderr, "Retored data are not same\n");
+ return 1;
+ }
+
+ memset (saved_data2, 0, sizeof (saved_data2));
+
+ printf ("%s: sam_data_store 3\n", __FUNCTION__);
+ err = sam_data_store (NULL, 1);
+ if (err != CS_OK) {
+ fprintf (stderr, "Test should return CS_OK. Error returned %d\n", err);
+ return 1;
+ }
+
+ printf ("%s: sam_data_getsize 5\n", __FUNCTION__);
+ err = sam_data_getsize (&size);
+ if (err != CS_OK) {
+ fprintf (stderr, "Test should return CS_OK. Error returned %d\n", err);
+ return 1;
+ }
+ if (size != 0) {
+ fprintf (stderr, "Test should return size of 0. Returned %zx\n", size);
+ return 1;
+ }
+
+ printf ("%s: sam_data_store 4\n", __FUNCTION__);
+ err = sam_data_store (saved_data, sizeof (saved_data));
+ if (err != CS_OK) {
+ fprintf (stderr, "Test should return CS_OK. Error returned %d\n", err);
+ return 1;
+ }
+
+ printf ("%s: register\n", __FUNCTION__);
+ err = sam_register (&instance_id);
+ if (err != CS_OK) {
+ fprintf (stderr, "Can't register. Error %d\n", err);
+ return 1;
+ }
+
+ if (instance_id == 1) {
+ printf ("%s iid %d: sam_start\n", __FUNCTION__, instance_id);
+ err = sam_start ();
+ if (err != CS_OK) {
+ fprintf (stderr, "Can't start hc. Error %d\n", err);
+ return 1;
+ }
+
+ printf ("%s iid %d: sam_data_getsize 6\n", __FUNCTION__, instance_id);
+ err = sam_data_getsize (&size);
+ if (err != CS_OK) {
+ fprintf (stderr, "Test should return CS_OK. Error returned %d\n", err);
+ return 1;
+ }
+ if (size != sizeof (saved_data2)) {
+ fprintf (stderr, "Test should return size of 0. Returned %zx\n", size);
+ return 1;
+ }
+
+ printf ("%s iid %d: sam_data_restore 5\n", __FUNCTION__, instance_id);
+ err = sam_data_restore (saved_data2, sizeof (saved_data2));
+ if (err != CS_OK) {
+ fprintf (stderr, "Test should return CS_OK. Error returned %d\n", err);
+ return 1;
+ }
+
+ if (memcmp (saved_data, saved_data2, sizeof (saved_data2)) != 0) {
+ fprintf (stderr, "Retored data are not same\n");
+ return 1;
+ }
+
+ for (i = 0; i < sizeof (saved_data); i++) {
+ saved_data[i] = (char)(i - 5);
+ }
+
+ printf ("%s iid %d: sam_data_store 5\n", __FUNCTION__, instance_id);
+ err = sam_data_store (saved_data, sizeof (saved_data) - 7);
+ if (err != CS_OK) {
+ fprintf (stderr, "Test should return CS_OK. Error returned %d\n", err);
+ return 1;
+ }
+
+ exit (1);
+ }
+
+ if (instance_id == 2) {
+ printf ("%s iid %d: sam_start\n", __FUNCTION__, instance_id);
+ err = sam_start ();
+ if (err != CS_OK) {
+ fprintf (stderr, "Can't start hc. Error %d\n", err);
+ return 1;
+ }
+
+ printf ("%s iid %d: sam_data_getsize 7\n", __FUNCTION__, instance_id);
+ err = sam_data_getsize (&size);
+ if (err != CS_OK) {
+ fprintf (stderr, "Test should return CS_OK. Error returned %d\n", err);
+ return 1;
+ }
+ if (size != sizeof (saved_data2) - 7) {
+ fprintf (stderr, "Test should return size of 0. Returned %zx\n", size);
+ return 1;
+ }
+
+ printf ("%s iid %d: sam_data_restore 6\n", __FUNCTION__, instance_id);
+ err = sam_data_restore (saved_data2, sizeof (saved_data2));
+ if (err != CS_OK) {
+ fprintf (stderr, "Test should return CS_OK. Error returned %d\n", err);
+ return 1;
+ }
+
+ for (i = 0; i < sizeof (saved_data); i++) {
+ saved_data[i] = (char)(i - 5);
+ }
+
+ if (memcmp (saved_data, saved_data2, sizeof (saved_data2) - 7) != 0) {
+ fprintf (stderr, "Retored data are not same\n");
+ return 1;
+ }
+
+ printf ("%s iid %d: sam_data_store 6\n", __FUNCTION__, instance_id);
+ err = sam_data_store (NULL, 0);
+ if (err != CS_OK) {
+ fprintf (stderr, "Test should return CS_OK. Error returned %d\n", err);
+ return 1;
+ }
+
+ exit (1);
+ }
+
+ if (instance_id == 3) {
+ printf ("%s iid %d: sam_data_getsize 8\n", __FUNCTION__, instance_id);
+ err = sam_data_getsize (&size);
+ if (err != CS_OK) {
+ fprintf (stderr, "Test should return CS_OK. Error returned %d\n", err);
+ return 1;
+ }
+ if (size != 0) {
+ fprintf (stderr, "Test should return size of 0. Returned %zx\n", size);
+ return 1;
+ }
+ }
+
+ return (0);
+}
+
+static int test5_hc_cb (void)
+{
+ cs_error_t res;
+ printf ("%s %d\n", __FUNCTION__, ++test5_hc_cb_count);
+
+ res = sam_data_store (&test5_hc_cb_count, sizeof (test5_hc_cb_count));
+ if (res != CS_OK)
+ return 1;
+
+ if (test5_hc_cb_count > 10)
+ return 1;
+
+ return 0;
+}
+/*
+ * Test event driven healtchecking.
+ */
+static int test5 (void)
+{
+ cs_error_t error;
+ unsigned int instance_id;
+ int hc_cb_count;
+
+ printf ("%s: initialize\n", __FUNCTION__);
+ error = sam_initialize (100, SAM_RECOVERY_POLICY_RESTART);
+ if (error != CS_OK) {
+ fprintf (stderr, "Can't initialize SAM API. Error %d\n", error);
+ return 1;
+ }
+ printf ("%s: register\n", __FUNCTION__);
+ error = sam_register (&instance_id);
+ if (error != CS_OK) {
+ fprintf (stderr, "Can't register. Error %d\n", error);
+ return 1;
+ }
+
+ if (instance_id == 1) {
+ printf ("%s iid %d: hc callback register\n", __FUNCTION__, instance_id);
+ error = sam_hc_callback_register (test5_hc_cb);
+ if (error != CS_OK) {
+ fprintf (stderr, "Can't register hc cb. Error %d\n", error);
+ return 1;
+ }
+
+
+ printf ("%s iid %d: start\n", __FUNCTION__, instance_id);
+ error = sam_start ();
+ if (error != CS_OK) {
+ fprintf (stderr, "Can't start hc. Error %d\n", error);
+ return 1;
+ }
+
+ sleep (2);
+
+ printf ("%s iid %d: Failed. Wasn't killed.\n", __FUNCTION__, instance_id);
+ return 1;
+ }
+
+ if (instance_id == 2) {
+ error = sam_data_restore (&hc_cb_count, sizeof (hc_cb_count));
+ if (error != CS_OK) {
+ fprintf (stderr, "sam_data_restore should return CS_OK. Error returned %d\n", error);
+ return 1;
+ }
+
+ if (hc_cb_count != 11) {
+ fprintf (stderr, "%s iid %d: Premature killed. hc_cb_count should be 11 and it is %d\n",
+ __FUNCTION__, instance_id - 1, hc_cb_count);
+ return 1;
+
+ }
+ return 0;
+ }
+
+ return 1;
+}
+
+static void test6_signal (int sig) {
+ cs_error_t error;
+
+ printf ("%s\n", __FUNCTION__);
+ test6_sig_delivered++;
+
+ if ((error = sam_data_store (&test6_sig_delivered, sizeof (test6_sig_delivered))) != CS_OK) {
+ fprintf (stderr, "Can't store data! Error : %d\n", error);
+ }
+}
+
+/*
+ * Test warn signal set.
+ */
+static int test6 (void) {
+ cs_error_t error;
+ unsigned int instance_id;
+ int test6_sig_del;
+
+ printf ("%s: initialize\n", __FUNCTION__);
+ error = sam_initialize (2000, SAM_RECOVERY_POLICY_RESTART);
+ if (error != CS_OK) {
+ fprintf (stderr, "Can't initialize SAM API. Error %d\n", error);
+ return 1;
+ }
+ printf ("%s: register\n", __FUNCTION__);
+ error = sam_register (&instance_id);
+ if (error != CS_OK) {
+ fprintf (stderr, "Can't register. Error %d\n", error);
+ return 1;
+ }
+
+ if (instance_id == 1) {
+ error = sam_warn_signal_set (SIGUSR1);
+ if (error != CS_OK) {
+ fprintf (stderr, "Can't set warn signal. Error %d\n", error);
+ return 1;
+ }
+
+ signal (SIGUSR1, test6_signal);
+
+ printf ("%s iid %d: start\n", __FUNCTION__, instance_id);
+ error = sam_start ();
+ if (error != CS_OK) {
+ fprintf (stderr, "Can't start hc. Error %d\n", error);
+ return 1;
+ }
+
+ printf ("%s iid %d: sleep 1\n", __FUNCTION__, instance_id);
+ sleep (1);
+
+ printf ("%s iid %d: hc send\n", __FUNCTION__, instance_id);
+ error = sam_hc_send ();
+ if (error != CS_OK) {
+ fprintf (stderr, "Can't send hc. Error %d\n", error);
+ return 1;
+ }
+
+
+ printf ("%s iid %d: wait for delivery of signal\n", __FUNCTION__, instance_id);
+ while (!test6_sig_delivered) {
+ sleep (1);
+ }
+
+ printf ("%s iid %d: wait for real kill\n", __FUNCTION__, instance_id);
+
+ sleep (3);
+
+ printf ("%s iid %d: wasn't killed\n", __FUNCTION__, instance_id);
+ return (1);
+ }
+
+ if (instance_id == 2) {
+ error = sam_data_restore (&test6_sig_del, sizeof (test6_sig_del));
+ if (error != CS_OK) {
+ fprintf (stderr, "Can't restore data. Error %d\n", error);
+ return 1;
+ }
+
+ if (test6_sig_del != 1) {
+ fprintf (stderr, "Previous test failed. Signal was not delivered\n");
+ return 1;
+ }
+
+ error = sam_warn_signal_set (SIGKILL);
+ if (error != CS_OK) {
+ fprintf (stderr, "Can't set warn signal. Error %d\n", error);
+ return 1;
+ }
+
+ signal (SIGUSR1, test6_signal);
+
+ printf ("%s iid %d: start\n", __FUNCTION__, instance_id);
+ error = sam_start ();
+ if (error != CS_OK) {
+ fprintf (stderr, "Can't start hc. Error %d\n", error);
+ return 1;
+ }
+
+ printf ("%s iid %d: sleep 1\n", __FUNCTION__, instance_id);
+ sleep (1);
+
+ printf ("%s iid %d: hc send\n", __FUNCTION__, instance_id);
+ error = sam_hc_send ();
+ if (error != CS_OK) {
+ fprintf (stderr, "Can't send hc. Error %d\n", error);
+ return 1;
+ }
+
+
+ printf ("%s iid %d: wait for delivery of signal\n", __FUNCTION__, instance_id);
+ while (!test6_sig_delivered) {
+ sleep (1);
+ }
+
+ printf ("%s iid %d: wasn't killed\n", __FUNCTION__, instance_id);
+ return (1);
+ }
+
+ if (instance_id == 3) {
+ error = sam_data_restore (&test6_sig_del, sizeof (test6_sig_del));
+ if (error != CS_OK) {
+ fprintf (stderr, "Can't restore data. Error %d\n", error);
+ return 1;
+ }
+
+ if (test6_sig_del != 1) {
+ fprintf (stderr, "Previous test failed. Signal WAS delivered\n");
+ return 1;
+ }
+
+ return (0);
+ }
+
+ return 1;
+}
+
+static void *test7_thread (void *arg)
+{
+ /* Wait 5s */
+ sleep (5);
+ exit (0);
+}
+
+/*
+ * Test quorum
+ */
+static int test7 (void) {
+ cmap_handle_t cmap_handle;
+ cs_error_t err;
+ unsigned int instance_id;
+ pthread_t kill_thread;
+ char *str;
+
+ err = cmap_initialize (&cmap_handle);
+ if (err != CS_OK) {
+ printf ("Could not initialize Cluster Map API instance error %d. Test skipped\n", err);
+ return (1);
+ }
+
+
+ if (cmap_get_string(cmap_handle, "quorum.provider", &str) != CS_OK) {
+ printf ("Could not get \"provider\" key: %d. Test skipped\n", err);
+ return (1);
+ }
+ if (strcmp(str, "testquorum") != 0) {
+ printf ("Provider is not testquorum. Test skipped\n");
+ free(str);
+ return (1);
+ }
+ free(str);
+
+ /*
+ * Set to not quorate
+ */
+ err = cmap_set_uint8(cmap_handle, "quorum.quorate", 0);
+ if (err != CS_OK) {
+ printf ("Can't set map key. Error %d\n", err);
+ return (2);
+ }
+
+ printf ("%s: initialize\n", __FUNCTION__);
+ err = sam_initialize (2000, SAM_RECOVERY_POLICY_QUORUM_RESTART);
+ if (err != CS_OK) {
+ fprintf (stderr, "Can't initialize SAM API. Error %d\n", err);
+ return 2;
+ }
+
+ printf ("%s: register\n", __FUNCTION__);
+ err = sam_register (&instance_id);
+ if (err != CS_OK) {
+ fprintf (stderr, "Can't register. Error %d\n", err);
+ return 2;
+ }
+
+ if (instance_id == 1) {
+ /*
+ * Sam start should block forever, but 10s for us should be enough
+ */
+ pthread_create (&kill_thread, NULL, test7_thread, NULL);
+
+ printf ("%s iid %d: start - should block forever (waiting 5s)\n", __FUNCTION__, instance_id);
+ err = sam_start ();
+ if (err != CS_OK) {
+ fprintf (stderr, "Can't start hc. Error %d\n", err);
+ return 2;
+ }
+
+ printf ("%s iid %d: wasn't killed\n", __FUNCTION__, instance_id);
+ return (2);
+ }
+
+ if (instance_id == 2) {
+ /*
+ * Set to quorate
+ */
+ err = cmap_set_uint8(cmap_handle, "quorum.quorate", 1);
+ if (err != CS_OK) {
+ printf ("Can't set map key. Error %d\n", err);
+ return (2);
+ }
+
+ printf ("%s iid %d: start\n", __FUNCTION__, instance_id);
+ err = sam_start ();
+ if (err != CS_OK) {
+ fprintf (stderr, "Can't start hc. Error %d\n", err);
+ return 2;
+ }
+
+ /*
+ * Set corosync unquorate
+ */
+ err = cmap_set_uint8(cmap_handle, "quorum.quorate", 0);
+ if (err != CS_OK) {
+ printf ("Can't set map key. Error %d\n", err);
+ return (2);
+ }
+
+ printf ("%s iid %d: sleep 3\n", __FUNCTION__, instance_id);
+ sleep (3);
+
+ printf ("%s iid %d: wasn't killed\n", __FUNCTION__, instance_id);
+ return (2);
+ }
+
+ if (instance_id == 3) {
+ return (0);
+ }
+
+ return (2);
+}
+
+/*
+ * Test cmap integration + quit policy
+ */
+static int test8 (pid_t pid, pid_t old_pid, int test_n) {
+ cmap_handle_t cmap_handle;
+ cs_error_t err;
+ uint64_t tstamp1, tstamp2;
+ int32_t msec_diff;
+ unsigned int instance_id;
+ char key_name[CMAP_KEYNAME_MAXLEN];
+ char *str;
+
+ err = cmap_initialize (&cmap_handle);
+ if (err != CS_OK) {
+ printf ("Could not initialize Cluster Map API instance error %d. Test skipped\n", err);
+ return (1);
+ }
+
+ printf ("%s test %d\n", __FUNCTION__, test_n);
+
+ if (test_n == 2) {
+ /*
+ * Object should not exist
+ */
+ printf ("%s Testing if object exists (it shouldn't)\n", __FUNCTION__);
+
+ snprintf(key_name, CMAP_KEYNAME_MAXLEN, "resources.process.%d.state", pid);
+ err = cmap_get_string(cmap_handle, key_name, &str);
+ if (err == CS_OK) {
+ printf ("Could find key \"%s\": %d.\n", key_name, err);
+ free(str);
+ return (2);
+ }
+ }
+
+ if (test_n == 1 || test_n == 2) {
+ printf ("%s: initialize\n", __FUNCTION__);
+ err = sam_initialize (2000, SAM_RECOVERY_POLICY_QUIT | SAM_RECOVERY_POLICY_CMAP);
+ if (err != CS_OK) {
+ fprintf (stderr, "Can't initialize SAM API. Error %d\n", err);
+ return 2;
+ }
+
+ printf ("%s: register\n", __FUNCTION__);
+ err = sam_register (&instance_id);
+ if (err != CS_OK) {
+ fprintf (stderr, "Can't register. Error %d\n", err);
+ return 2;
+ }
+
+ snprintf(key_name, CMAP_KEYNAME_MAXLEN, "resources.process.%d.recovery", pid);
+ err = cmap_get_string(cmap_handle, key_name, &str);
+ if (err != CS_OK) {
+ printf ("Could not get \"recovery\" key: %d.\n", err);
+ return (2);
+ }
+
+ if (strcmp(str, "quit") != 0) {
+ printf ("Recovery key \"%s\" is not \"quit\".\n", key_name);
+ free(str);
+ return (2);
+ }
+ free(str);
+
+ snprintf(key_name, CMAP_KEYNAME_MAXLEN, "resources.process.%d.state", pid);
+ err = cmap_get_string(cmap_handle, key_name, &str);
+ if (err != CS_OK) {
+ printf ("Could not get \"state\" key: %d.\n", err);
+ return (2);
+ }
+
+ if (strcmp(str, "stopped") != 0) {
+ printf ("State key is not \"stopped\".\n");
+ free(str);
+ return (2);
+ }
+ free(str);
+
+ printf ("%s iid %d: start\n", __FUNCTION__, instance_id);
+ err = sam_start ();
+ if (err != CS_OK) {
+ fprintf (stderr, "Can't start hc. Error %d\n", err);
+ return 2;
+ }
+
+ err = cmap_get_string(cmap_handle, key_name, &str);
+ if (err != CS_OK) {
+ printf ("Could not get \"state\" key: %d.\n", err);
+ return (2);
+ }
+
+ if (strcmp(str, "running") != 0) {
+ printf ("State key is not \"running\".\n");
+ free(str);
+ return (2);
+ }
+ free(str);
+
+ printf ("%s iid %d: stop\n", __FUNCTION__, instance_id);
+ err = sam_stop ();
+ if (err != CS_OK) {
+ fprintf (stderr, "Can't stop hc. Error %d\n", err);
+ return 2;
+ }
+
+ err = cmap_get_string(cmap_handle, key_name, &str);
+ if (err != CS_OK) {
+ printf ("Could not get \"state\" key: %d.\n", err);
+ return (2);
+ }
+
+ if (strcmp(str, "stopped") != 0) {
+ printf ("State key is not \"stopped\".\n");
+ free(str);
+ return (2);
+ }
+ free(str);
+
+ printf ("%s iid %d: sleeping 5\n", __FUNCTION__, instance_id);
+ sleep (5);
+
+ err = cmap_get_string(cmap_handle, key_name, &str);
+ if (err != CS_OK) {
+ printf ("Could not get \"state\" key: %d.\n", err);
+ return (2);
+ }
+
+ if (strcmp(str, "stopped") != 0) {
+ printf ("State key is not \"stopped\".\n");
+ free(str);
+ return (2);
+ }
+ free(str);
+
+ printf ("%s iid %d: start 2\n", __FUNCTION__, instance_id);
+ err = sam_start ();
+ if (err != CS_OK) {
+ fprintf (stderr, "Can't start hc. Error %d\n", err);
+ return 2;
+ }
+
+ err = cmap_get_string(cmap_handle, key_name, &str);
+ if (err != CS_OK) {
+ printf ("Could not get \"state\" key: %d.\n", err);
+ return (2);
+ }
+
+ if (strcmp(str, "running") != 0) {
+ printf ("State key is not \"running\".\n");
+ free(str);
+ return (2);
+ }
+ free(str);
+
+ if (test_n == 2) {
+ printf ("%s iid %d: sleeping 5. Should be killed\n", __FUNCTION__, instance_id);
+ sleep (5);
+
+ return (2);
+ } else {
+ printf ("%s iid %d: Test HC\n", __FUNCTION__, instance_id);
+ err = sam_hc_send ();
+ if (err != CS_OK) {
+ fprintf (stderr, "Can't send hc. Error %d\n", err);
+ return 2;
+ }
+
+ snprintf(key_name, CMAP_KEYNAME_MAXLEN, "resources.process.%d.last_updated", pid);
+ err = cmap_get_uint64(cmap_handle, key_name, &tstamp1);
+ if (err != CS_OK) {
+ printf ("Could not get \"last_updated\" key: %d.\n", err);
+ return (2);
+ }
+ printf ("%s iid %d: Sleep 1\n", __FUNCTION__, instance_id);
+ sleep (1);
+ err = sam_hc_send ();
+ if (err != CS_OK) {
+ fprintf (stderr, "Can't send hc. Error %d\n", err);
+ return 2;
+ }
+ sleep (1);
+ err = cmap_get_uint64(cmap_handle, key_name, &tstamp2);
+ if (err != CS_OK) {
+ printf ("Could not get \"last_updated\" key: %d.\n", err);
+ return (2);
+ }
+ msec_diff = (tstamp2 - tstamp1)/CS_TIME_NS_IN_MSEC;
+
+ if (msec_diff < 500 || msec_diff > 2000) {
+ printf ("Difference %d is not within <500, 2000> interval.\n", msec_diff);
+ return (2);
+ }
+
+ printf ("%s iid %d: stop 2\n", __FUNCTION__, instance_id);
+ err = sam_stop ();
+ if (err != CS_OK) {
+ fprintf (stderr, "Can't stop hc. Error %d\n", err);
+ return 2;
+ }
+
+ snprintf(key_name, CMAP_KEYNAME_MAXLEN, "resources.process.%d.state", pid);
+ err = cmap_get_string(cmap_handle, key_name, &str);
+ if (err != CS_OK) {
+ printf ("Could not get \"state\" key: %d.\n", err);
+ return (2);
+ }
+
+ if (strcmp(str, "stopped") != 0) {
+ printf ("State key is not \"stopped\".\n");
+ free(str);
+ return (2);
+ }
+ free(str);
+
+ printf ("%s iid %d: exiting\n", __FUNCTION__, instance_id);
+ return (0);
+ }
+ }
+
+ if (test_n == 3) {
+ printf ("%s Testing if status is failed\n", __FUNCTION__);
+
+ /*
+ * Previous should be FAILED
+ */
+
+ snprintf(key_name, CMAP_KEYNAME_MAXLEN, "resources.process.%d.state", pid);
+ err = cmap_get_string(cmap_handle, key_name, &str);
+ if (err != CS_OK) {
+ printf ("Could not get \"state\" key: %d.\n", err);
+ return (2);
+ }
+
+ if (strcmp(str, "failed") != 0) {
+ printf ("State key is not \"failed\".\n");
+ free(str);
+ return (2);
+ }
+ free(str);
+
+ return (0);
+ }
+
+ return (2);
+}
+
+/*
+ * Test cmap integration + restart policy
+ */
+static int test9 (pid_t pid, pid_t old_pid, int test_n) {
+ cs_error_t err;
+ cmap_handle_t cmap_handle;
+ unsigned int instance_id;
+ char *str;
+ char key_name[CMAP_KEYNAME_MAXLEN];
+
+ err = cmap_initialize (&cmap_handle);
+ if (err != CS_OK) {
+ printf ("Could not initialize Cluster Map API instance error %d. Test skipped\n", err);
+ return (1);
+ }
+
+ printf ("%s test %d\n", __FUNCTION__, test_n);
+
+ if (test_n == 1) {
+ printf ("%s: initialize\n", __FUNCTION__);
+ err = sam_initialize (2000, SAM_RECOVERY_POLICY_RESTART | SAM_RECOVERY_POLICY_CMAP);
+ if (err != CS_OK) {
+ fprintf (stderr, "Can't initialize SAM API. Error %d\n", err);
+ return 2;
+ }
+
+ printf ("%s: register\n", __FUNCTION__);
+ err = sam_register (&instance_id);
+ if (err != CS_OK) {
+ fprintf (stderr, "Can't register. Error %d\n", err);
+ return 2;
+ }
+ printf ("%s: iid %d\n", __FUNCTION__, instance_id);
+
+ if (instance_id < 3) {
+ snprintf(key_name, CMAP_KEYNAME_MAXLEN, "resources.process.%d.recovery", pid);
+ err = cmap_get_string(cmap_handle, key_name, &str);
+ if (err != CS_OK) {
+ printf ("Could not get \"recovery\" key: %d.\n", err);
+ return (2);
+ }
+
+ if (strcmp(str, "restart") != 0) {
+ printf ("Recovery key \"%s\" is not \"restart\".\n", str);
+ free(str);
+ return (2);
+ }
+ free(str);
+
+ snprintf(key_name, CMAP_KEYNAME_MAXLEN, "resources.process.%d.state", pid);
+ err = cmap_get_string(cmap_handle, key_name, &str);
+ if (err != CS_OK) {
+ printf ("Could not get \"state\" key: %d.\n", err);
+ return (2);
+ }
+
+ if (strcmp(str, "stopped") != 0) {
+ printf ("State key is not \"stopped\".\n");
+ free(str);
+ return (2);
+ }
+ free(str);
+
+ printf ("%s iid %d: start\n", __FUNCTION__, instance_id);
+ err = sam_start ();
+ if (err != CS_OK) {
+ fprintf (stderr, "Can't start hc. Error %d\n", err);
+ return 2;
+ }
+
+ err = cmap_get_string(cmap_handle, key_name, &str);
+ if (err != CS_OK) {
+ printf ("Could not get \"state\" key: %d.\n", err);
+ return (2);
+ }
+
+ if (strcmp(str, "running") != 0) {
+ printf ("State key is not \"running\".\n");
+ free(str);
+ return (2);
+ }
+ free(str);
+
+ printf ("%s iid %d: waiting for kill\n", __FUNCTION__, instance_id);
+ sleep (10);
+
+ return (2);
+ }
+
+ if (instance_id == 3) {
+ printf ("%s iid %d: mark failed\n", __FUNCTION__, instance_id);
+
+ err = sam_mark_failed ();
+ if (err != CS_OK) {
+ fprintf (stderr, "Can't mark failed. Error %d\n", err);
+ return 2;
+ }
+
+ sleep (10);
+
+ return (2);
+ }
+
+ return (2);
+ }
+
+ if (test_n == 2) {
+ printf ("%s Testing if status is failed\n", __FUNCTION__);
+
+ /*
+ * Previous should be FAILED
+ */
+ snprintf(key_name, CMAP_KEYNAME_MAXLEN, "resources.process.%d.state", pid);
+ err = cmap_get_string(cmap_handle, key_name, &str);
+ if (err != CS_OK) {
+ printf ("Could not get \"state\" key: %d.\n", err);
+ return (2);
+ }
+
+ if (strcmp(str, "failed") != 0) {
+ printf ("State key is not \"failed\".\n");
+ free(str);
+ return (2);
+ }
+ free(str);
+
+ return (0);
+ }
+
+ return (2);
+}
+
+int main(int argc, char *argv[])
+{
+ pid_t pid, old_pid;
+ int err;
+ int stat;
+ int all_passed = 1;
+ int no_skipped = 0;
+
+ pid = fork ();
+
+ if (pid == -1) {
+ fprintf (stderr, "Can't fork\n");
+ return 1;
+ }
+
+ if (pid == 0) {
+ err = test1 ();
+ sam_finalize ();
+ return err;
+ }
+
+ waitpid (pid, &stat, 0);
+
+ fprintf (stderr, "test1 %s\n", (WEXITSTATUS (stat) == 0 ? "passed" : "failed"));
+ if (WEXITSTATUS (stat) != 0)
+ all_passed = 0;
+
+ pid = fork ();
+
+ if (pid == -1) {
+ fprintf (stderr, "Can't fork\n");
+ return 1;
+ }
+
+ if (pid == 0) {
+ err = test2 ();
+
+ sam_finalize ();
+ return (err);
+ }
+
+ waitpid (pid, &stat, 0);
+
+ fprintf (stderr, "test2 %s\n", (WEXITSTATUS (stat) == 0 ? "passed" : "failed"));
+ if (WEXITSTATUS (stat) != 0)
+ all_passed = 0;
+
+ pid = fork ();
+
+ if (pid == -1) {
+ fprintf (stderr, "Can't fork\n");
+ return 1;
+ }
+
+ if (pid == 0) {
+ err = test3 ();
+ sam_finalize ();
+ return (err);
+ }
+
+ waitpid (pid, &stat, 0);
+
+ fprintf (stderr, "test3 %s\n", (WEXITSTATUS (stat) == 0 ? "passed" : "failed"));
+ if (WEXITSTATUS (stat) != 0)
+ all_passed = 0;
+
+ pid = fork ();
+
+ if (pid == -1) {
+ fprintf (stderr, "Can't fork\n");
+ return 1;
+ }
+
+ if (pid == 0) {
+ err = test4 ();
+ sam_finalize ();
+ return (err);
+ }
+
+ waitpid (pid, &stat, 0);
+
+ fprintf (stderr, "test4 %s\n", (WEXITSTATUS (stat) == 0 ? "passed" : "failed"));
+ if (WEXITSTATUS (stat) != 0)
+ all_passed = 0;
+
+ pid = fork ();
+
+ if (pid == -1) {
+ fprintf (stderr, "Can't fork\n");
+ return 1;
+ }
+
+ if (pid == 0) {
+ err = test5 ();
+
+ sam_finalize ();
+ return (err);
+ }
+
+ waitpid (pid, &stat, 0);
+ fprintf (stderr, "test5 %s\n", (WEXITSTATUS (stat) == 0 ? "passed" : "failed"));
+ if (WEXITSTATUS (stat) != 0)
+ all_passed = 0;
+
+ pid = fork ();
+
+ if (pid == -1) {
+ fprintf (stderr, "Can't fork\n");
+ return 1;
+ }
+
+ if (pid == 0) {
+ err = test6 ();
+ sam_finalize ();
+ return (err);
+ }
+
+ waitpid (pid, &stat, 0);
+ fprintf (stderr, "test6 %s\n", (WEXITSTATUS (stat) == 0 ? "passed" : "failed"));
+ if (WEXITSTATUS (stat) != 0)
+ all_passed = 0;
+
+ pid = fork ();
+
+ if (pid == -1) {
+ fprintf (stderr, "Can't fork\n");
+ return 2;
+ }
+
+ if (pid == 0) {
+ err = test7 ();
+ sam_finalize ();
+ return (err);
+ }
+
+ waitpid (pid, &stat, 0);
+ fprintf (stderr, "test7 %s\n", (WEXITSTATUS (stat) == 0 ? "passed" : (WEXITSTATUS (stat) == 1 ? "skipped" : "failed")));
+ if (WEXITSTATUS (stat) == 1)
+ no_skipped++;
+ if (WEXITSTATUS (stat) > 1)
+ all_passed = 0;
+
+ pid = fork ();
+
+ if (pid == -1) {
+ fprintf (stderr, "Can't fork\n");
+ return 2;
+ }
+
+ if (pid == 0) {
+ err = test8 (getpid (), 0, 1);
+ sam_finalize ();
+ return (err);
+ }
+
+ waitpid (pid, &stat, 0);
+ old_pid = pid;
+
+ if (WEXITSTATUS (stat) == 0) {
+ pid = fork ();
+
+ if (pid == -1) {
+ fprintf (stderr, "Can't fork\n");
+ return 2;
+ }
+
+ if (pid == 0) {
+ err = test8 (getpid (), old_pid, 2);
+ sam_finalize ();
+ return (err);
+ }
+
+ waitpid (pid, &stat, 0);
+ old_pid = pid;
+
+ if (WEXITSTATUS (stat) == 0) {
+ pid = fork ();
+
+ if (pid == -1) {
+ fprintf (stderr, "Can't fork\n");
+ return 2;
+ }
+
+ if (pid == 0) {
+ err = test8 (old_pid, 0, 3);
+ sam_finalize ();
+ return (err);
+ }
+
+ waitpid (pid, &stat, 0);
+ }
+ }
+
+ fprintf (stderr, "test8 %s\n", (WEXITSTATUS (stat) == 0 ? "passed" : (WEXITSTATUS (stat) == 1 ? "skipped" : "failed")));
+ if (WEXITSTATUS (stat) == 1)
+ no_skipped++;
+ if (WEXITSTATUS (stat) > 1)
+ all_passed = 0;
+
+ pid = fork ();
+
+ if (pid == -1) {
+ fprintf (stderr, "Can't fork\n");
+ return 2;
+ }
+
+ if (pid == 0) {
+ err = test9 (getpid (), 0, 1);
+ sam_finalize ();
+ return (err);
+ }
+
+ waitpid (pid, &stat, 0);
+ old_pid = pid;
+
+ if (WEXITSTATUS (stat) == 0) {
+ pid = fork ();
+
+ if (pid == -1) {
+ fprintf (stderr, "Can't fork\n");
+ return 2;
+ }
+
+ if (pid == 0) {
+ err = test9 (old_pid, 0, 2);
+ sam_finalize ();
+ return (err);
+ }
+
+ waitpid (pid, &stat, 0);
+ }
+ fprintf (stderr, "test9 %s\n", (WEXITSTATUS (stat) == 0 ? "passed" : (WEXITSTATUS (stat) == 1 ? "skipped" : "failed")));
+ if (WEXITSTATUS (stat) == 1)
+ no_skipped++;
+
+ if (WEXITSTATUS (stat) > 1)
+ all_passed = 0;
+
+ if (all_passed)
+ fprintf (stderr, "All tests passed (%d skipped)\n", no_skipped);
+
+ return (all_passed ? 0 : 1);
+}
diff --git a/test/testvotequorum1.c b/test/testvotequorum1.c
new file mode 100644
index 0000000..70fea50
--- /dev/null
+++ b/test/testvotequorum1.c
@@ -0,0 +1,200 @@
+/*
+ * Copyright (c) 2009 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Author: Christine Caulfield (ccaulfie@redhat.com)
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of the MontaVista Software, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <corosync/corotypes.h>
+#include <corosync/votequorum.h>
+
+static votequorum_handle_t g_handle;
+
+static const char *node_state(int state)
+{
+ switch (state) {
+ case VOTEQUORUM_NODESTATE_MEMBER:
+ return "Member";
+ break;
+ case VOTEQUORUM_NODESTATE_DEAD:
+ return "Dead";
+ break;
+ case VOTEQUORUM_NODESTATE_LEAVING:
+ return "Leaving";
+ break;
+ default:
+ return "UNKNOWN";
+ break;
+ }
+}
+
+
+static void votequorum_expectedvotes_notification_fn(
+ votequorum_handle_t handle,
+ uint64_t context,
+ uint32_t expected_votes
+ )
+{
+ printf("votequorum expectedvotes notification called \n");
+ printf(" expected_votes = %d\n", expected_votes);
+}
+
+
+static void votequorum_quorum_notification_fn(
+ votequorum_handle_t handle,
+ uint64_t context,
+ uint32_t quorate,
+ uint32_t node_list_entries,
+ votequorum_node_t node_list[]
+ )
+{
+ int i;
+
+ printf("votequorum quorum notification called \n");
+ printf(" number of nodes = %d\n", node_list_entries);
+ printf(" quorate = %d\n", quorate);
+
+ for (i = 0; i< node_list_entries; i++) {
+ printf(" " CS_PRI_NODE_ID ": %s\n", node_list[i].nodeid, node_state(node_list[i].state));
+ }
+
+}
+
+static void votequorum_nodelist_notification_fn(
+ votequorum_handle_t handle,
+ uint64_t context,
+ votequorum_ring_id_t ring_id,
+ uint32_t node_list_entries,
+ uint32_t node_list[]
+ )
+{
+ int i;
+
+ printf("votequorum nodelist notification called \n");
+ printf(" number of nodes = %d\n", node_list_entries);
+ printf(" current ringid = (" CS_PRI_RING_ID ")\n", ring_id.nodeid, ring_id.seq);
+ printf(" nodes: ");
+
+ for (i = 0; i< node_list_entries; i++) {
+ printf(CS_PRI_NODE_ID " ", node_list[i]);
+ }
+ printf("\n\n");
+}
+
+
+int main(int argc, char *argv[])
+{
+ struct votequorum_info info;
+ votequorum_callbacks_t callbacks;
+ int err;
+
+ if (argc > 1 && strcmp(argv[1], "-h")==0) {
+ fprintf(stderr, "usage: %s [new-expected] [new-votes]\n", argv[0]);
+ return 0;
+ }
+
+ callbacks.votequorum_quorum_notify_fn = votequorum_quorum_notification_fn;
+ callbacks.votequorum_nodelist_notify_fn = votequorum_nodelist_notification_fn;
+ callbacks.votequorum_expectedvotes_notify_fn = votequorum_expectedvotes_notification_fn;
+
+ if ( (err=votequorum_initialize(&g_handle, &callbacks)) != CS_OK)
+ fprintf(stderr, "votequorum_initialize FAILED: %d\n", err);
+
+ if ( (err = votequorum_trackstart(g_handle, g_handle, CS_TRACK_CHANGES)) != CS_OK)
+ fprintf(stderr, "votequorum_trackstart FAILED: %d\n", err);
+
+ if ( (err=votequorum_getinfo(g_handle, 0, &info)) != CS_OK)
+ fprintf(stderr, "votequorum_getinfo FAILED: %d\n", err);
+ else {
+ printf("node votes %d\n", info.node_votes);
+ printf("expected votes %d\n", info.node_expected_votes);
+ printf("highest expected %d\n", info.highest_expected);
+ printf("total votes %d\n", info.total_votes);
+ printf("quorum %d\n", info.quorum);
+ printf("flags ");
+ if (info.flags & VOTEQUORUM_INFO_TWONODE) printf("2Node ");
+ if (info.flags & VOTEQUORUM_INFO_QUORATE) printf("Quorate ");
+ if (info.flags & VOTEQUORUM_INFO_WAIT_FOR_ALL) printf("WaitForAll ");
+ if (info.flags & VOTEQUORUM_INFO_LAST_MAN_STANDING) printf("LastManStanding ");
+ if (info.flags & VOTEQUORUM_INFO_AUTO_TIE_BREAKER) printf("AutoTieBreaker ");
+ if (info.flags & VOTEQUORUM_INFO_ALLOW_DOWNSCALE) printf("AllowDownscale ");
+
+ printf("\n");
+ }
+
+ if (argc >= 2 && atoi(argv[1])) {
+ if ( (err=votequorum_setexpected(g_handle, atoi(argv[1]))) != CS_OK)
+ fprintf(stderr, "set expected votes FAILED: %d\n", err);
+ }
+ if (argc >= 3 && atoi(argv[2])) {
+ if ( (err=votequorum_setvotes(g_handle, 0, atoi(argv[2]))) != CS_OK)
+ fprintf(stderr, "set votes FAILED: %d\n", err);
+ }
+
+ if (argc >= 2) {
+ if ( (err=votequorum_getinfo(g_handle, 0, &info)) != CS_OK)
+ fprintf(stderr, "votequorum_getinfo2 FAILED: %d\n", err);
+ else {
+ printf("-------------------\n");
+ printf("node votes %d\n", info.node_votes);
+ printf("expected votes %d\n", info.node_expected_votes);
+ printf("highest expected %d\n", info.highest_expected);
+ printf("total votes %d\n", info.total_votes);
+ printf("votequorum %d\n", info.quorum);
+ printf("flags ");
+ if (info.flags & VOTEQUORUM_INFO_TWONODE) printf("2Node ");
+ if (info.flags & VOTEQUORUM_INFO_QUORATE) printf("Quorate ");
+ if (info.flags & VOTEQUORUM_INFO_WAIT_FOR_ALL) printf("WaitForAll ");
+ if (info.flags & VOTEQUORUM_INFO_LAST_MAN_STANDING) printf("LastManStanding ");
+ if (info.flags & VOTEQUORUM_INFO_AUTO_TIE_BREAKER) printf("AutoTieBreaker ");
+ if (info.flags & VOTEQUORUM_INFO_ALLOW_DOWNSCALE) printf("AllowDownscale ");
+ printf("\n");
+ }
+ }
+
+ printf("Waiting for votequorum events, press ^C to finish\n");
+ printf("-------------------\n");
+
+ if (votequorum_dispatch(g_handle, CS_DISPATCH_BLOCKING) != CS_OK) {
+ fprintf(stderr, "votequorum_dispatch error\n");
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/test/testvotequorum2.c b/test/testvotequorum2.c
new file mode 100644
index 0000000..1e8c13f
--- /dev/null
+++ b/test/testvotequorum2.c
@@ -0,0 +1,236 @@
+/*
+ * Copyright (c) 2009-2014 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Author: Christine Caulfield (ccaulfie@redhat.com)
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of the MontaVista Software, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <corosync/corotypes.h>
+#include <corosync/votequorum.h>
+
+static votequorum_handle_t handle;
+
+static votequorum_ring_id_t last_received_ring_id;
+static votequorum_ring_id_t ring_id_to_send;
+static int no_sent_old_ringid = 0;
+
+static int print_info(int ok_to_fail)
+{
+ struct votequorum_info info;
+ int err;
+
+ if ( (err=votequorum_getinfo(handle, VOTEQUORUM_QDEVICE_NODEID, &info)) != CS_OK) {
+ fprintf(stderr, "votequorum_getinfo error %d: %s\n", err, ok_to_fail?"OK":"FAILED");
+ return -1;
+ }
+ else {
+ printf("name %s\n", info.qdevice_name);
+ printf("qdevice votes %d\n", info.qdevice_votes);
+ if (info.flags & VOTEQUORUM_INFO_QDEVICE_ALIVE) {
+ printf("alive ");
+ }
+ if (info.flags & VOTEQUORUM_INFO_QDEVICE_CAST_VOTE) {
+ printf("cast-vote ");
+ }
+ if (info.flags & VOTEQUORUM_INFO_QDEVICE_MASTER_WINS) {
+ printf("master-wins");
+ }
+ printf("\n\n");
+ }
+ return 0;
+}
+
+static void votequorum_nodelist_notification_fn(
+ votequorum_handle_t vq_handle,
+ uint64_t context,
+ votequorum_ring_id_t ring_id,
+ uint32_t node_list_entries,
+ uint32_t node_list[])
+{
+
+ printf("votequorum nodelist notification called \n");
+ printf(" current ringid = (" CS_PRI_RING_ID ")\n", ring_id.nodeid, ring_id.seq);
+ printf("\n");
+
+ memcpy(&last_received_ring_id, &ring_id, sizeof(ring_id));
+ no_sent_old_ringid = 0;
+}
+
+static void usage(const char *command)
+{
+ printf("%s [-F <num>] [-p <num>] [-t <time>] [-n <name>] [-c] [-m]\n", command);
+ printf(" -F <num> Number of times to send old ringid before actual ringid is sent (for testing, default = 0)\n");
+ printf(" -p <num> Number of times to poll qdevice (default 0=infinte)\n");
+ printf(" -t <secs> Time (in seconds) to wait between polls (default=1)\n");
+ printf(" -n <name> Name of quorum device (default QDEVICE)\n");
+ printf(" -c Don't cast vote (default is to cast vote)\n");
+ printf(" -q Don't print device status every poll time (default=will print)\n");
+ printf(" -m Master wins (default no)\n");
+ printf(" -1 Print status once and exit\n");
+}
+
+int main(int argc, char *argv[])
+{
+ int ret = 0;
+ int cast_vote = 1, master_wins = 0;
+ int pollcount=0, polltime=1, quiet=0, once=0;
+ int send_old_ringid = 0;
+ int err;
+ int opt;
+ votequorum_callbacks_t callbacks;
+ const char *devicename = "QDEVICE";
+ const char *options = "F:n:p:t:cmq1h";
+
+ memset(&callbacks, 0, sizeof(callbacks));
+ callbacks.votequorum_nodelist_notify_fn = votequorum_nodelist_notification_fn;
+
+ while ((opt = getopt(argc, argv, options)) != -1) {
+ switch (opt) {
+ case 'm':
+ master_wins = 1;
+ break;
+ case 'c':
+ cast_vote = 0;
+ break;
+ case '1':
+ once = 1;
+ break;
+ case 'q':
+ quiet = 1;
+ break;
+ case 'F':
+ send_old_ringid = atoi(optarg)+1;
+ break;
+ case 'p':
+ pollcount = atoi(optarg)+1;
+ break;
+ case 'n':
+ devicename = strdup(optarg);
+ break;
+ case 't':
+ polltime = atoi(optarg);
+ break;
+ case 'h':
+ usage(argv[0]);
+ exit(0);
+ }
+ }
+
+ if ( (err=votequorum_initialize(&handle, &callbacks)) != CS_OK) {
+ fprintf(stderr, "votequorum_initialize FAILED: %d\n", err);
+ return -1;
+ }
+
+ if (quiet && once) {
+ fprintf(stderr, "setting both -q (quet) and -1 (once) makes no sense\n");
+ usage(argv[0]);
+ exit(1);
+ }
+
+ if (!quiet) {
+ print_info(1);
+ }
+ if (once) {
+ exit(0);
+ }
+
+ if (argc >= 2) {
+ if ( (err = votequorum_trackstart(handle, handle, CS_TRACK_CHANGES)) != CS_OK) {
+ fprintf(stderr, "votequorum_trackstart FAILED: %d\n", err);
+ ret = -1;
+ goto out;
+ }
+
+ if ( (err=votequorum_qdevice_register(handle, devicename)) != CS_OK) {
+ fprintf(stderr, "qdevice_register FAILED: %d\n", err);
+ ret = -1;
+ goto out;
+ }
+
+ if ( (err=votequorum_qdevice_master_wins(handle, devicename, master_wins)) != CS_OK) {
+ fprintf(stderr, "qdevice_master_wins FAILED: %d\n", err);
+ ret = -1;
+ goto out;
+ }
+
+
+ while (--pollcount) {
+ if (votequorum_dispatch(handle, CS_DISPATCH_ALL) != CS_OK) {
+ fprintf(stderr, "votequorum_dispatch error\n");
+ ret = -1;
+ goto out;
+ }
+
+ if (!quiet) print_info(0);
+
+ if (no_sent_old_ringid + 1 >= send_old_ringid) {
+ /*
+ * Finally send correct ringid
+ */
+ memcpy(&ring_id_to_send, &last_received_ring_id, sizeof(ring_id_to_send));
+ } else {
+ no_sent_old_ringid++;
+ }
+
+ if ((err=votequorum_qdevice_poll(handle, devicename, cast_vote, ring_id_to_send)) != CS_OK &&
+ err != CS_ERR_MESSAGE_ERROR) {
+ fprintf(stderr, "qdevice poll FAILED: %d\n", err);
+ ret = -1;
+ goto out;
+ }
+ if (err == CS_ERR_MESSAGE_ERROR) {
+ fprintf(stderr, "qdevice poll passed OLD ring_id\n");
+ }
+
+ if (!quiet) print_info(0);
+ sleep(polltime);
+ }
+ if ((err= votequorum_qdevice_unregister(handle, devicename)) != CS_OK) {
+ fprintf(stderr, "qdevice unregister FAILED: %d\n", err);
+ ret = -1;
+ goto out;
+ }
+ }
+
+ if (!quiet) print_info(1);
+
+out:
+ votequorum_finalize(handle);
+ return ret;
+}
diff --git a/test/testzcgc.c b/test/testzcgc.c
new file mode 100644
index 0000000..ca177f4
--- /dev/null
+++ b/test/testzcgc.c
@@ -0,0 +1,175 @@
+/*
+ * Copyright (c) 2006-2009 Red Hat Inc
+ *
+ * All rights reserved.
+ *
+ * Author: Christine Caulfield <ccaulfie@redhat.com>
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of the MontaVista Software, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <unistd.h>
+#include <string.h>
+#include <inttypes.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/select.h>
+#include <sys/un.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include <corosync/corotypes.h>
+#include <corosync/cpg.h>
+
+static int quit = 0;
+static int show_ip = 0;
+
+static void print_cpgname (const struct cpg_name *name)
+{
+ int i;
+
+ for (i = 0; i < name->length; i++) {
+ printf ("%c", name->value[i]);
+ }
+}
+
+static void DeliverCallback (
+ cpg_handle_t handle,
+ const struct cpg_name *groupName,
+ uint32_t nodeid,
+ uint32_t pid,
+ void *msg,
+ size_t msg_len)
+{
+ if (show_ip) {
+ struct in_addr saddr;
+ saddr.s_addr = nodeid;
+ printf("DeliverCallback: message (len=%lu)from node/pid %s/%d: '%s'\n",
+ (unsigned long int) msg_len,
+ inet_ntoa(saddr), pid, (const char *)msg);
+ }
+ else {
+ printf("DeliverCallback: message (len=%lu)from node/pid " CS_PRI_NODE_ID "/%d: '%s'\n",
+ (unsigned long int) msg_len, nodeid, pid,
+ (const char *)msg);
+ }
+}
+
+static void ConfchgCallback (
+ cpg_handle_t handle,
+ const struct cpg_name *groupName,
+ const struct cpg_address *member_list, size_t member_list_entries,
+ const struct cpg_address *left_list, size_t left_list_entries,
+ const struct cpg_address *joined_list, size_t joined_list_entries)
+{
+ int i;
+ struct in_addr saddr;
+
+ printf("\nConfchgCallback: group '");
+ print_cpgname(groupName);
+ printf("'\n");
+ for (i=0; i<joined_list_entries; i++) {
+ if (show_ip) {
+ saddr.s_addr = joined_list[i].nodeid;
+ printf("joined node/pid: %s/%d reason: %d\n",
+ inet_ntoa (saddr), joined_list[i].pid,
+ joined_list[i].reason);
+ }
+ else {
+ printf("joined node/pid: " CS_PRI_NODE_ID "/%d reason: %d\n",
+ joined_list[i].nodeid, joined_list[i].pid,
+ joined_list[i].reason);
+ }
+ }
+
+ for (i=0; i<left_list_entries; i++) {
+ if (show_ip) {
+ saddr.s_addr = left_list[i].nodeid;
+ printf("left node/pid: %s/%d reason: %d\n",
+ inet_ntoa (saddr), left_list[i].pid,
+ left_list[i].reason);
+ }
+ else {
+ printf("left node/pid: " CS_PRI_NODE_ID "/%d reason: %d\n",
+ left_list[i].nodeid, left_list[i].pid,
+ left_list[i].reason);
+ }
+ }
+
+ printf("nodes in group now %lu\n",
+ (unsigned long int) member_list_entries);
+ for (i=0; i<member_list_entries; i++) {
+ if (show_ip) {
+ saddr.s_addr = member_list[i].nodeid;
+ printf("node/pid: %s/%d\n",
+ inet_ntoa (saddr), member_list[i].pid);
+ }
+ else {
+ printf("node/pid: " CS_PRI_NODE_ID "/%d\n",
+ member_list[i].nodeid, member_list[i].pid);
+ }
+ }
+
+ /* Is it us??
+ NOTE: in reality we should also check the nodeid */
+ if (left_list_entries && left_list[0].pid == getpid()) {
+ printf("We have left the building\n");
+ quit = 1;
+ }
+}
+
+static cpg_callbacks_t callbacks = {
+ .cpg_deliver_fn = DeliverCallback,
+ .cpg_confchg_fn = ConfchgCallback,
+};
+
+static struct cpg_name group_name;
+
+int main (int argc, char *argv[]) {
+ cpg_handle_t handle;
+ int result;
+ void *buffer;
+ unsigned int i;
+
+ strcpy(group_name.value, "GROUP");
+ group_name.length = 6;
+
+ result = cpg_initialize (&handle, &callbacks);
+ if (result != CS_OK) {
+ printf ("Could not initialize Cluster Process Group API instance error %d\n", result);
+ exit (1);
+ }
+ for (i = 0; i < 100; i++) {
+ cpg_zcb_alloc (handle, 1024*1024, &buffer);
+ }
+ return (0);
+}
diff --git a/tools/Makefile.am b/tools/Makefile.am
new file mode 100644
index 0000000..6279dd4
--- /dev/null
+++ b/tools/Makefile.am
@@ -0,0 +1,93 @@
+# Copyright (c) 2009 Red Hat, Inc.
+#
+# Authors: Andrew Beekhof
+# Steven Dake (sdake@redhat.com)
+#
+# This software licensed under BSD license, the text of which follows:
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# - Redistributions of source code must retain the above copyright notice,
+# this list of conditions and the following disclaimer.
+# - Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+# - Neither the name of the MontaVista Software, Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from this
+# software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+# THE POSSIBILITY OF SUCH DAMAGE.
+
+MAINTAINERCLEANFILES = Makefile.in
+
+sbin_PROGRAMS = corosync-cfgtool \
+ corosync-keygen \
+ corosync-cpgtool corosync-quorumtool \
+ corosync-notifyd corosync-cmapctl
+
+bin_SCRIPTS = corosync-blackbox
+
+if INSTALL_XMLCONF
+bin_SCRIPTS += corosync-xmlproc
+endif
+
+noinst_HEADERS = util.h
+
+AM_CFLAGS = $(knet_CFLAGS)
+
+EXTRA_DIST = corosync-xmlproc.sh \
+ corosync-notifyd.sysconfig.example \
+ corosync-blackbox.sh
+
+corosync_cfgtool_SOURCES = corosync-cfgtool.c util.c
+
+corosync_quorumtool_SOURCES = corosync-quorumtool.c util.c
+
+corosync-xmlproc: corosync-xmlproc.sh
+ $(SED) -e 's#@''DATADIR@#${datadir}#g' \
+ -e 's#@''BASHPATH@#${BASHPATH}#g' \
+ $< > $@
+
+corosync-blackbox: corosync-blackbox.sh
+ $(SED) -e 's#@''LOCALSTATEDIR@#${localstatedir}#g' $< > $@
+
+corosync_cmapctl_LDADD = $(LIBQB_LIBS) $(top_builddir)/common_lib/libcorosync_common.la $(top_builddir)/lib/libcmap.la
+
+corosync_cfgtool_LDADD = $(LIBQB_LIBS) $(top_builddir)/common_lib/libcorosync_common.la \
+ $(top_builddir)/lib/libcfg.la $(top_builddir)/lib/libcmap.la
+
+corosync_cpgtool_LDADD = $(LIBQB_LIBS) $(top_builddir)/lib/libcfg.la \
+ $(top_builddir)/lib/libcpg.la \
+ $(top_builddir)/common_lib/libcorosync_common.la
+
+corosync_quorumtool_LDADD = $(LIBQB_LIBS) \
+ $(top_builddir)/lib/libcmap.la \
+ $(top_builddir)/lib/libcfg.la \
+ $(top_builddir)/lib/libquorum.la \
+ $(top_builddir)/lib/libvotequorum.la \
+ $(top_builddir)/common_lib/libcorosync_common.la
+
+corosync_notifyd_CFLAGS = $(DBUS_CFLAGS) $(libsystemd_CFLAGS)
+corosync_notifyd_LDADD = $(LIBQB_LIBS) $(DBUS_LIBS) $(SNMP_LIBS) \
+ $(libsystemd_LIBS) \
+ $(top_builddir)/lib/libcmap.la \
+ $(top_builddir)/lib/libcfg.la \
+ $(top_builddir)/lib/libquorum.la \
+ $(top_builddir)/common_lib/libcorosync_common.la
+
+lint:
+ -splint $(LINT_FLAGS) $(DBUS_CFLAGS) $(CPPFLAGS) $(CFLAGS) *.c
+
+clean-local:
+ rm -f corosync-xmlproc corosync-blackbox
diff --git a/tools/Makefile.in b/tools/Makefile.in
new file mode 100644
index 0000000..2e9398c
--- /dev/null
+++ b/tools/Makefile.in
@@ -0,0 +1,899 @@
+# Makefile.in generated by automake 1.13.4 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+# Copyright (c) 2009 Red Hat, Inc.
+#
+# Authors: Andrew Beekhof
+# Steven Dake (sdake@redhat.com)
+#
+# This software licensed under BSD license, the text of which follows:
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# - Redistributions of source code must retain the above copyright notice,
+# this list of conditions and the following disclaimer.
+# - Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+# - Neither the name of the MontaVista Software, Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from this
+# software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+# THE POSSIBILITY OF SUCH DAMAGE.
+
+
+
+VPATH = @srcdir@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+sbin_PROGRAMS = corosync-cfgtool$(EXEEXT) corosync-keygen$(EXEEXT) \
+ corosync-cpgtool$(EXEEXT) corosync-quorumtool$(EXEEXT) \
+ corosync-notifyd$(EXEEXT) corosync-cmapctl$(EXEEXT)
+@INSTALL_XMLCONF_TRUE@am__append_1 = corosync-xmlproc
+subdir = tools
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+ $(top_srcdir)/depcomp $(noinst_HEADERS)
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/lib/libcfg.verso $(top_srcdir)/lib/libcpg.verso \
+ $(top_srcdir)/lib/libquorum.verso \
+ $(top_srcdir)/lib/libsam.verso \
+ $(top_srcdir)/lib/libvotequorum.verso \
+ $(top_srcdir)/lib/libcmap.verso $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/include/corosync/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__installdirs = "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(bindir)"
+PROGRAMS = $(sbin_PROGRAMS)
+am_corosync_cfgtool_OBJECTS = corosync-cfgtool.$(OBJEXT) \
+ util.$(OBJEXT)
+corosync_cfgtool_OBJECTS = $(am_corosync_cfgtool_OBJECTS)
+am__DEPENDENCIES_1 =
+corosync_cfgtool_DEPENDENCIES = $(am__DEPENDENCIES_1) \
+ $(top_builddir)/common_lib/libcorosync_common.la \
+ $(top_builddir)/lib/libcfg.la $(top_builddir)/lib/libcmap.la
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 =
+corosync_cmapctl_SOURCES = corosync-cmapctl.c
+corosync_cmapctl_OBJECTS = corosync-cmapctl.$(OBJEXT)
+corosync_cmapctl_DEPENDENCIES = $(am__DEPENDENCIES_1) \
+ $(top_builddir)/common_lib/libcorosync_common.la \
+ $(top_builddir)/lib/libcmap.la
+corosync_cpgtool_SOURCES = corosync-cpgtool.c
+corosync_cpgtool_OBJECTS = corosync-cpgtool.$(OBJEXT)
+corosync_cpgtool_DEPENDENCIES = $(am__DEPENDENCIES_1) \
+ $(top_builddir)/lib/libcfg.la $(top_builddir)/lib/libcpg.la \
+ $(top_builddir)/common_lib/libcorosync_common.la
+corosync_keygen_SOURCES = corosync-keygen.c
+corosync_keygen_OBJECTS = corosync-keygen.$(OBJEXT)
+corosync_keygen_LDADD = $(LDADD)
+corosync_notifyd_SOURCES = corosync-notifyd.c
+corosync_notifyd_OBJECTS = \
+ corosync_notifyd-corosync-notifyd.$(OBJEXT)
+corosync_notifyd_DEPENDENCIES = $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1) $(top_builddir)/lib/libcmap.la \
+ $(top_builddir)/lib/libcfg.la $(top_builddir)/lib/libquorum.la \
+ $(top_builddir)/common_lib/libcorosync_common.la
+corosync_notifyd_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(corosync_notifyd_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \
+ -o $@
+am_corosync_quorumtool_OBJECTS = corosync-quorumtool.$(OBJEXT) \
+ util.$(OBJEXT)
+corosync_quorumtool_OBJECTS = $(am_corosync_quorumtool_OBJECTS)
+corosync_quorumtool_DEPENDENCIES = $(am__DEPENDENCIES_1) \
+ $(top_builddir)/lib/libcmap.la $(top_builddir)/lib/libcfg.la \
+ $(top_builddir)/lib/libquorum.la \
+ $(top_builddir)/lib/libvotequorum.la \
+ $(top_builddir)/common_lib/libcorosync_common.la
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+SCRIPTS = $(bin_SCRIPTS)
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/corosync
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo " CC " $@;
+am__v_CC_1 =
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo " CCLD " $@;
+am__v_CCLD_1 =
+SOURCES = $(corosync_cfgtool_SOURCES) corosync-cmapctl.c \
+ corosync-cpgtool.c corosync-keygen.c corosync-notifyd.c \
+ $(corosync_quorumtool_SOURCES)
+DIST_SOURCES = $(corosync_cfgtool_SOURCES) corosync-cmapctl.c \
+ corosync-cpgtool.c corosync-keygen.c corosync-notifyd.c \
+ $(corosync_quorumtool_SOURCES)
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+HEADERS = $(noinst_HEADERS)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALLOCA = @ALLOCA@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUGTOOL = @AUGTOOL@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BASHPATH = @BASHPATH@
+BINDGEN = @BINDGEN@
+CARGO = @CARGO@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFG_SONAME = @CFG_SONAME@
+CFLAGS = @CFLAGS@
+CLIPPY = @CLIPPY@
+CMAP_SONAME = @CMAP_SONAME@
+COROSYSCONFDIR = @COROSYSCONFDIR@
+CPG_SONAME = @CPG_SONAME@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DBUS_CFLAGS = @DBUS_CFLAGS@
+DBUS_LIBS = @DBUS_LIBS@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DOT = @DOT@
+DOXYGEN = @DOXYGEN@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GREP = @GREP@
+GROFF = @GROFF@
+INITCONFIGDIR = @INITCONFIGDIR@
+INITDDIR = @INITDDIR@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBQB_CFLAGS = @LIBQB_CFLAGS@
+LIBQB_LIBS = @LIBQB_LIBS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LINT_FLAGS = @LINT_FLAGS@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LOGDIR = @LOGDIR@
+LOGROTATEDIR = @LOGROTATEDIR@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+QUORUM_SONAME = @QUORUM_SONAME@
+RANLIB = @RANLIB@
+RUSTC = @RUSTC@
+RUSTDOC = @RUSTDOC@
+RUSTFMT = @RUSTFMT@
+RUST_FLAGS = @RUST_FLAGS@
+RUST_TARGET_DIR = @RUST_TARGET_DIR@
+SAM_SONAME = @SAM_SONAME@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SNMPCONFIG = @SNMPCONFIG@
+SNMP_LIBS = @SNMP_LIBS@
+SOMAJOR = @SOMAJOR@
+SOMICRO = @SOMICRO@
+SOMINOR = @SOMINOR@
+SONAME = @SONAME@
+STRIP = @STRIP@
+SYSTEMDDIR = @SYSTEMDDIR@
+VERSCRIPT_LDFLAGS = @VERSCRIPT_LDFLAGS@
+VERSION = @VERSION@
+VOTEQUORUM_SONAME = @VOTEQUORUM_SONAME@
+WITH_LIST = @WITH_LIST@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+corosyncrustver = @corosyncrustver@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+knet_CFLAGS = @knet_CFLAGS@
+knet_LIBS = @knet_LIBS@
+libdir = @libdir@
+libexecdir = @libexecdir@
+libsystemd_CFLAGS = @libsystemd_CFLAGS@
+libsystemd_LIBS = @libsystemd_LIBS@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+nozzle_CFLAGS = @nozzle_CFLAGS@
+nozzle_LIBS = @nozzle_LIBS@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+statgrab_CFLAGS = @statgrab_CFLAGS@
+statgrab_LIBS = @statgrab_LIBS@
+statgrabge090_CFLAGS = @statgrabge090_CFLAGS@
+statgrabge090_LIBS = @statgrabge090_LIBS@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+MAINTAINERCLEANFILES = Makefile.in
+bin_SCRIPTS = corosync-blackbox $(am__append_1)
+noinst_HEADERS = util.h
+AM_CFLAGS = $(knet_CFLAGS)
+EXTRA_DIST = corosync-xmlproc.sh \
+ corosync-notifyd.sysconfig.example \
+ corosync-blackbox.sh
+
+corosync_cfgtool_SOURCES = corosync-cfgtool.c util.c
+corosync_quorumtool_SOURCES = corosync-quorumtool.c util.c
+corosync_cmapctl_LDADD = $(LIBQB_LIBS) $(top_builddir)/common_lib/libcorosync_common.la $(top_builddir)/lib/libcmap.la
+corosync_cfgtool_LDADD = $(LIBQB_LIBS) $(top_builddir)/common_lib/libcorosync_common.la \
+ $(top_builddir)/lib/libcfg.la $(top_builddir)/lib/libcmap.la
+
+corosync_cpgtool_LDADD = $(LIBQB_LIBS) $(top_builddir)/lib/libcfg.la \
+ $(top_builddir)/lib/libcpg.la \
+ $(top_builddir)/common_lib/libcorosync_common.la
+
+corosync_quorumtool_LDADD = $(LIBQB_LIBS) \
+ $(top_builddir)/lib/libcmap.la \
+ $(top_builddir)/lib/libcfg.la \
+ $(top_builddir)/lib/libquorum.la \
+ $(top_builddir)/lib/libvotequorum.la \
+ $(top_builddir)/common_lib/libcorosync_common.la
+
+corosync_notifyd_CFLAGS = $(DBUS_CFLAGS) $(libsystemd_CFLAGS)
+corosync_notifyd_LDADD = $(LIBQB_LIBS) $(DBUS_LIBS) $(SNMP_LIBS) \
+ $(libsystemd_LIBS) \
+ $(top_builddir)/lib/libcmap.la \
+ $(top_builddir)/lib/libcfg.la \
+ $(top_builddir)/lib/libquorum.la \
+ $(top_builddir)/common_lib/libcorosync_common.la
+
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign tools/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign tools/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+install-sbinPROGRAMS: $(sbin_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ @list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(sbindir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(sbindir)" || exit 1; \
+ fi; \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed 's/$(EXEEXT)$$//' | \
+ while read p p1; do if test -f $$p \
+ || test -f $$p1 \
+ ; then echo "$$p"; echo "$$p"; else :; fi; \
+ done | \
+ sed -e 'p;s,.*/,,;n;h' \
+ -e 's|.*|.|' \
+ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \
+ sed 'N;N;N;s,\n, ,g' | \
+ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \
+ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
+ if ($$2 == $$4) files[d] = files[d] " " $$1; \
+ else { print "f", $$3 "/" $$4, $$1; } } \
+ END { for (d in files) print "f", d, files[d] }' | \
+ while read type dir files; do \
+ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
+ test -z "$$files" || { \
+ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(sbindir)$$dir'"; \
+ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(sbindir)$$dir" || exit $$?; \
+ } \
+ ; done
+
+uninstall-sbinPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \
+ files=`for p in $$list; do echo "$$p"; done | \
+ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \
+ -e 's/$$/$(EXEEXT)/' \
+ `; \
+ test -n "$$list" || exit 0; \
+ echo " ( cd '$(DESTDIR)$(sbindir)' && rm -f" $$files ")"; \
+ cd "$(DESTDIR)$(sbindir)" && rm -f $$files
+
+clean-sbinPROGRAMS:
+ @list='$(sbin_PROGRAMS)'; test -n "$$list" || exit 0; \
+ echo " rm -f" $$list; \
+ rm -f $$list || exit $$?; \
+ test -n "$(EXEEXT)" || exit 0; \
+ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f" $$list; \
+ rm -f $$list
+
+corosync-cfgtool$(EXEEXT): $(corosync_cfgtool_OBJECTS) $(corosync_cfgtool_DEPENDENCIES) $(EXTRA_corosync_cfgtool_DEPENDENCIES)
+ @rm -f corosync-cfgtool$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(corosync_cfgtool_OBJECTS) $(corosync_cfgtool_LDADD) $(LIBS)
+
+corosync-cmapctl$(EXEEXT): $(corosync_cmapctl_OBJECTS) $(corosync_cmapctl_DEPENDENCIES) $(EXTRA_corosync_cmapctl_DEPENDENCIES)
+ @rm -f corosync-cmapctl$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(corosync_cmapctl_OBJECTS) $(corosync_cmapctl_LDADD) $(LIBS)
+
+corosync-cpgtool$(EXEEXT): $(corosync_cpgtool_OBJECTS) $(corosync_cpgtool_DEPENDENCIES) $(EXTRA_corosync_cpgtool_DEPENDENCIES)
+ @rm -f corosync-cpgtool$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(corosync_cpgtool_OBJECTS) $(corosync_cpgtool_LDADD) $(LIBS)
+
+corosync-keygen$(EXEEXT): $(corosync_keygen_OBJECTS) $(corosync_keygen_DEPENDENCIES) $(EXTRA_corosync_keygen_DEPENDENCIES)
+ @rm -f corosync-keygen$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(corosync_keygen_OBJECTS) $(corosync_keygen_LDADD) $(LIBS)
+
+corosync-notifyd$(EXEEXT): $(corosync_notifyd_OBJECTS) $(corosync_notifyd_DEPENDENCIES) $(EXTRA_corosync_notifyd_DEPENDENCIES)
+ @rm -f corosync-notifyd$(EXEEXT)
+ $(AM_V_CCLD)$(corosync_notifyd_LINK) $(corosync_notifyd_OBJECTS) $(corosync_notifyd_LDADD) $(LIBS)
+
+corosync-quorumtool$(EXEEXT): $(corosync_quorumtool_OBJECTS) $(corosync_quorumtool_DEPENDENCIES) $(EXTRA_corosync_quorumtool_DEPENDENCIES)
+ @rm -f corosync-quorumtool$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(corosync_quorumtool_OBJECTS) $(corosync_quorumtool_LDADD) $(LIBS)
+install-binSCRIPTS: $(bin_SCRIPTS)
+ @$(NORMAL_INSTALL)
+ @list='$(bin_SCRIPTS)'; test -n "$(bindir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \
+ fi; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ if test -f "$$d$$p"; then echo "$$d$$p"; echo "$$p"; else :; fi; \
+ done | \
+ sed -e 'p;s,.*/,,;n' \
+ -e 'h;s|.*|.|' \
+ -e 'p;x;s,.*/,,;$(transform)' | sed 'N;N;N;s,\n, ,g' | \
+ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1; } \
+ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
+ if ($$2 == $$4) { files[d] = files[d] " " $$1; \
+ if (++n[d] == $(am__install_max)) { \
+ print "f", d, files[d]; n[d] = 0; files[d] = "" } } \
+ else { print "f", d "/" $$4, $$1 } } \
+ END { for (d in files) print "f", d, files[d] }' | \
+ while read type dir files; do \
+ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
+ test -z "$$files" || { \
+ echo " $(INSTALL_SCRIPT) $$files '$(DESTDIR)$(bindir)$$dir'"; \
+ $(INSTALL_SCRIPT) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \
+ } \
+ ; done
+
+uninstall-binSCRIPTS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(bin_SCRIPTS)'; test -n "$(bindir)" || exit 0; \
+ files=`for p in $$list; do echo "$$p"; done | \
+ sed -e 's,.*/,,;$(transform)'`; \
+ dir='$(DESTDIR)$(bindir)'; $(am__uninstall_files_from_dir)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/corosync-cfgtool.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/corosync-cmapctl.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/corosync-cpgtool.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/corosync-keygen.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/corosync-quorumtool.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/corosync_notifyd-corosync-notifyd.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/util.Po@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+corosync_notifyd-corosync-notifyd.o: corosync-notifyd.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(corosync_notifyd_CFLAGS) $(CFLAGS) -MT corosync_notifyd-corosync-notifyd.o -MD -MP -MF $(DEPDIR)/corosync_notifyd-corosync-notifyd.Tpo -c -o corosync_notifyd-corosync-notifyd.o `test -f 'corosync-notifyd.c' || echo '$(srcdir)/'`corosync-notifyd.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/corosync_notifyd-corosync-notifyd.Tpo $(DEPDIR)/corosync_notifyd-corosync-notifyd.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='corosync-notifyd.c' object='corosync_notifyd-corosync-notifyd.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(corosync_notifyd_CFLAGS) $(CFLAGS) -c -o corosync_notifyd-corosync-notifyd.o `test -f 'corosync-notifyd.c' || echo '$(srcdir)/'`corosync-notifyd.c
+
+corosync_notifyd-corosync-notifyd.obj: corosync-notifyd.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(corosync_notifyd_CFLAGS) $(CFLAGS) -MT corosync_notifyd-corosync-notifyd.obj -MD -MP -MF $(DEPDIR)/corosync_notifyd-corosync-notifyd.Tpo -c -o corosync_notifyd-corosync-notifyd.obj `if test -f 'corosync-notifyd.c'; then $(CYGPATH_W) 'corosync-notifyd.c'; else $(CYGPATH_W) '$(srcdir)/corosync-notifyd.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/corosync_notifyd-corosync-notifyd.Tpo $(DEPDIR)/corosync_notifyd-corosync-notifyd.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='corosync-notifyd.c' object='corosync_notifyd-corosync-notifyd.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(corosync_notifyd_CFLAGS) $(CFLAGS) -c -o corosync_notifyd-corosync-notifyd.obj `if test -f 'corosync-notifyd.c'; then $(CYGPATH_W) 'corosync-notifyd.c'; else $(CYGPATH_W) '$(srcdir)/corosync-notifyd.c'; fi`
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(PROGRAMS) $(SCRIPTS) $(HEADERS)
+installdirs:
+ for dir in "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(bindir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+ -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-local clean-sbinPROGRAMS \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am: install-binSCRIPTS install-sbinPROGRAMS
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-binSCRIPTS uninstall-sbinPROGRAMS
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
+ clean-libtool clean-local clean-sbinPROGRAMS cscopelist-am \
+ ctags ctags-am distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-binSCRIPTS \
+ install-data install-data-am install-dvi install-dvi-am \
+ install-exec install-exec-am install-html install-html-am \
+ install-info install-info-am install-man install-pdf \
+ install-pdf-am install-ps install-ps-am install-sbinPROGRAMS \
+ install-strip installcheck installcheck-am installdirs \
+ maintainer-clean maintainer-clean-generic mostlyclean \
+ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
+ pdf pdf-am ps ps-am tags tags-am uninstall uninstall-am \
+ uninstall-binSCRIPTS uninstall-sbinPROGRAMS
+
+
+corosync-xmlproc: corosync-xmlproc.sh
+ $(SED) -e 's#@''DATADIR@#${datadir}#g' \
+ -e 's#@''BASHPATH@#${BASHPATH}#g' \
+ $< > $@
+
+corosync-blackbox: corosync-blackbox.sh
+ $(SED) -e 's#@''LOCALSTATEDIR@#${localstatedir}#g' $< > $@
+
+lint:
+ -splint $(LINT_FLAGS) $(DBUS_CFLAGS) $(CPPFLAGS) $(CFLAGS) *.c
+
+clean-local:
+ rm -f corosync-xmlproc corosync-blackbox
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/tools/corosync-blackbox.sh b/tools/corosync-blackbox.sh
new file mode 100644
index 0000000..1ca831f
--- /dev/null
+++ b/tools/corosync-blackbox.sh
@@ -0,0 +1,34 @@
+#!/bin/sh
+# Copyright (c) 2010 Red Hat, Inc.
+#
+# Authors: Angus Salkeld <asalkeld@redhat.com
+#
+# This software licensed under BSD license, the text of which follows:
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# - Redistributions of source code must retain the above copyright notice,
+# this list of conditions and the following disclaimer.
+# - Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+# - Neither the name of the MontaVista Software, Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from this
+# software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+# THE POSSIBILITY OF SUCH DAMAGE.
+
+corosync-cmapctl -s runtime.blackbox.dump_state str "$(date +%s)"
+corosync-cmapctl -s runtime.blackbox.dump_flight_data str "$(date +%s)"
+qb-blackbox "@LOCALSTATEDIR@/lib/corosync/fdata"
diff --git a/tools/corosync-cfgtool.c b/tools/corosync-cfgtool.c
new file mode 100644
index 0000000..d04d5be
--- /dev/null
+++ b/tools/corosync-cfgtool.c
@@ -0,0 +1,614 @@
+/*
+ * Copyright (c) 2006-2020 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Author: Steven Dake <sdake@redhat.com>
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of the MontaVista Software, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <unistd.h>
+#include <string.h>
+#include <pthread.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/select.h>
+#include <sys/un.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <limits.h>
+#include <getopt.h>
+
+#include <corosync/corotypes.h>
+#include <corosync/totem/totem.h>
+#include <corosync/cfg.h>
+#include <corosync/cmap.h>
+#include "util.h"
+
+#define cs_repeat(result, max, code) \
+ do { \
+ int counter = 0; \
+ do { \
+ result = code; \
+ if (result == CS_ERR_TRY_AGAIN) { \
+ sleep(1); \
+ counter++; \
+ } else { \
+ break; \
+ } \
+ } while (counter < max); \
+ } while (0)
+
+enum user_action {
+ ACTION_NOOP=0,
+ ACTION_LINKSTATUS_GET,
+ ACTION_NODESTATUS_GET,
+ ACTION_RELOAD_CONFIG,
+ ACTION_REOPEN_LOG_FILES,
+ ACTION_SHUTDOW,
+ ACTION_SHOWADDR,
+ ACTION_KILL_NODE,
+};
+
+static int node_compare(const void *aptr, const void *bptr)
+{
+ uint32_t a,b;
+
+ a = *(uint32_t *)aptr;
+ b = *(uint32_t *)bptr;
+
+ return a > b;
+}
+
+static int
+nodestatusget_do (enum user_action action, int brief)
+{
+ cs_error_t result;
+ corosync_cfg_handle_t handle;
+ cmap_handle_t cmap_handle;
+ char iter_key[CMAP_KEYNAME_MAXLEN];
+ cmap_iter_handle_t iter;
+ unsigned int local_nodeid;
+ unsigned int local_nodeid_index=0;
+ unsigned int other_nodeid_index=0;
+ unsigned int nodeid;
+ int nodeid_match_guard;
+ cmap_value_types_t type;
+ size_t value_len;
+ char *str;
+ char *transport_str = NULL;
+ uint32_t nodeid_list[KNET_MAX_HOST];
+ const char *link_transport[KNET_MAX_LINK];
+ int s = 0;
+ int rc = EXIT_SUCCESS;
+ int transport_number = TOTEM_TRANSPORT_KNET;
+ int i,j;
+ struct corosync_cfg_node_status_v1 node_status;
+
+ result = corosync_cfg_initialize (&handle, NULL);
+ if (result != CS_OK) {
+ fprintf (stderr, "Could not initialize corosync configuration API error %d\n", result);
+ exit (EXIT_FAILURE);
+ }
+
+ result = cmap_initialize (&cmap_handle);
+ if (result != CS_OK) {
+ fprintf (stderr, "Could not initialize corosync cmap API error %d\n", result);
+ exit (EXIT_FAILURE);
+ }
+
+ result = cmap_get_string(cmap_handle, "totem.transport", &str);
+ if (result == CS_OK) {
+ if (strcmp (str, "udpu") == 0) {
+ transport_number = TOTEM_TRANSPORT_UDPU;
+ }
+ if (strcmp (str, "udp") == 0) {
+ transport_number = TOTEM_TRANSPORT_UDP;
+ }
+ transport_str = str;
+ }
+ if (!transport_str) {
+ transport_str = strdup("knet"); /* It's the default */
+ }
+
+ result = corosync_cfg_local_get(handle, &local_nodeid);
+ if (result != CS_OK) {
+ fprintf (stderr, "Could not get the local node id, the error is: %d\n", result);
+ free(transport_str);
+ cmap_finalize(cmap_handle);
+ corosync_cfg_finalize(handle);
+ return EXIT_FAILURE;
+ }
+
+ /* Get a list of nodes. We do it this way rather than using votequorum as cfgtool
+ * needs to be independent of quorum type
+ */
+ result = cmap_iter_init(cmap_handle, "nodelist.node.", &iter);
+ if (result != CS_OK) {
+ fprintf (stderr, "Could not get nodelist from cmap. error %d\n", result);
+ free(transport_str);
+ cmap_finalize(cmap_handle);
+ corosync_cfg_finalize(handle);
+ exit (EXIT_FAILURE);
+ }
+
+ while ((cmap_iter_next(cmap_handle, iter, iter_key, &value_len, &type)) == CS_OK) {
+ nodeid_match_guard = 0;
+ if (sscanf(iter_key, "nodelist.node.%*u.nodeid%n", &nodeid_match_guard) != 0) {
+ continue;
+ }
+ /* check for exact match */
+ if (nodeid_match_guard != strlen(iter_key)) {
+ continue;
+ }
+ if (cmap_get_uint32(cmap_handle, iter_key, &nodeid) == CS_OK) {
+ nodeid_list[s++] = nodeid;
+ }
+ }
+
+ if (s == 0) {
+ fprintf(stderr, "No nodes found in nodelist\n");
+ exit (EXIT_FAILURE);
+ }
+
+ /* It's nice to have these in nodeid order */
+ qsort(nodeid_list, s, sizeof(uint32_t), node_compare);
+
+ /*
+ * Find local and other nodeid index in nodeid_list
+ */
+ for (i = 0; i < s; i++) {
+ if (nodeid_list[i] == local_nodeid) {
+ local_nodeid_index = i;
+ } else {
+ /* Bit of an odd one this. but local node only uses one link (of course, to itself)
+ so if we want to know which links are active across the cluster we need to look
+ at another node (any other) node's link list */
+ other_nodeid_index = i;
+ }
+ }
+
+ /* Get the transport of each link - but set reasonable defaults */
+ if (transport_number == TOTEM_TRANSPORT_KNET) {
+ for (i = 0; i<KNET_MAX_LINK; i++) {
+ link_transport[i] = "udp";
+ }
+ } else {
+ for (i = 0; i<KNET_MAX_LINK; i++) {
+ link_transport[i] = ""; /* No point in displaying "udp" again */
+ }
+ }
+ result = cmap_iter_init(cmap_handle, "totem.interface.", &iter);
+ if (result == CS_OK) { /* it's fine for this to fail, we just use the defaults */
+ while ((cmap_iter_next(cmap_handle, iter, iter_key, &value_len, &type)) == CS_OK) {
+ unsigned int link_number;
+ char *knet_transport;
+ char knet_transport_str[CMAP_KEYNAME_MAXLEN];
+
+ /* transport is (sensibly) indexed by link number */
+ if (sscanf(iter_key, "totem.interface.%u.knet_transport", &link_number) != 1) {
+ continue;
+ }
+ snprintf(knet_transport_str, sizeof(knet_transport_str),
+ "totem.interface.%u.knet_transport", link_number);
+ if (cmap_get_string(cmap_handle, knet_transport_str, &knet_transport) == CS_OK) {
+ link_transport[link_number] = knet_transport;
+ }
+ }
+
+ cmap_iter_finalize(cmap_handle, iter);
+ }
+
+ cmap_finalize(cmap_handle);
+
+ printf ("Local node ID " CS_PRI_NODE_ID ", transport %s\n", local_nodeid, transport_str);
+
+ /* If node status requested then do print node-based info */
+ if (action == ACTION_NODESTATUS_GET) {
+ for (i=0; i<s; i++) {
+ result = corosync_cfg_node_status_get(handle, nodeid_list[i], CFG_NODE_STATUS_V1, &node_status);
+ if (result == CS_OK) {
+ /* Only display node info if it is reachable (and not us) */
+ if (node_status.reachable && node_status.nodeid != local_nodeid) {
+ printf("nodeid: " CS_PRI_NODE_ID "", node_status.nodeid);
+ printf(" reachable");
+ if (node_status.remote) {
+ printf(" remote");
+ }
+ if (node_status.external) {
+ printf(" external");
+ }
+#ifdef HAVE_KNET_ONWIRE_VER
+ if (transport_number == TOTEM_TRANSPORT_KNET) {
+ printf(" onwire (min/max/cur): %d, %d, %d",
+ node_status.onwire_min,
+ node_status.onwire_max,
+ node_status.onwire_ver);
+ }
+#endif
+ printf("\n");
+ for (j=0; j<CFG_MAX_LINKS; j++) {
+ if (node_status.link_status[j].enabled) {
+ printf(" LINK: %d %s", j, link_transport[j]);
+ printf(" (%s%s%s)",
+ node_status.link_status[j].src_ipaddr,
+ transport_number==TOTEM_TRANSPORT_KNET?"->":"",
+ node_status.link_status[j].dst_ipaddr);
+ if (node_status.link_status[j].enabled) {
+ printf(" enabled");
+ }
+ if (node_status.link_status[j].connected) {
+ printf(" connected");
+ }
+ if (node_status.link_status[j].dynconnected) {
+ printf(" dynconnected");
+ }
+ printf(" mtu: %d\n", node_status.link_status[j].mtu);
+ }
+ }
+ printf("\n");
+ }
+ }
+ }
+ }
+ /* Print in link order */
+ else {
+ struct corosync_cfg_node_status_v1 node_info[s];
+ memset(node_info, 0, sizeof(node_info));
+
+ for (i=0; i<s; i++) {
+ result = corosync_cfg_node_status_get(handle, nodeid_list[i], CFG_NODE_STATUS_V1, &node_info[i]);
+ if (result != CS_OK) {
+ fprintf (stderr, "Could not get the node status for nodeid %d, the error is: %d\n", nodeid_list[i], result);
+ }
+ }
+
+ for (i=0; i<CFG_MAX_LINKS; i++) {
+ if (node_info[other_nodeid_index].link_status[i].enabled) {
+ printf("LINK ID %d %s\n", i, link_transport[i]);
+ printf("\taddr\t= %s\n", node_info[other_nodeid_index].link_status[i].src_ipaddr);
+ if (brief) {
+ printf("\tstatus\t= ");
+ for (j=0; j<s; j++) {
+ char status = (node_info[j].link_status[i].enabled |
+ (node_info[j].link_status[i].connected << 1)) + '0';
+ if (j == local_nodeid_index) {
+ status = 'n';
+ }
+ printf("%c", status);
+ }
+ printf("\n");
+ } else {
+ printf("\tstatus:\n");
+ for (j=0; j<s; j++) {
+ printf("\t\tnodeid: " CS_PRI_NODE_ID_PADDED ":\t", node_info[j].nodeid);
+ if (j == local_nodeid_index) {
+ printf("localhost");
+ } else {
+ if (node_info[j].link_status[i].connected) {
+ printf("connected");
+ } else {
+ printf("disconnected");
+ }
+ }
+ printf("\n");
+ }
+ }
+ }
+ }
+ }
+ free(transport_str);
+ corosync_cfg_finalize(handle);
+ return rc;
+}
+
+static int reload_config_do (void)
+{
+ cs_error_t result;
+ corosync_cfg_handle_t handle;
+ int rc;
+
+ rc = EXIT_SUCCESS;
+
+ printf ("Reloading corosync.conf...\n");
+ result = corosync_cfg_initialize (&handle, NULL);
+ if (result != CS_OK) {
+ fprintf (stderr, "Could not initialize corosync configuration API error %s\n", cs_strerror(result));
+ exit (EXIT_FAILURE);
+ }
+
+ result = corosync_cfg_reload_config (handle);
+ if (result != CS_OK) {
+ fprintf (stderr, "Could not reload configuration. Error %s\n", cs_strerror(result));
+ rc = (int)result;
+ }
+ else {
+ printf ("Done\n");
+ }
+
+ (void)corosync_cfg_finalize (handle);
+
+ return (rc);
+}
+
+static int reopen_log_files_do (void)
+{
+ cs_error_t result;
+ corosync_cfg_handle_t handle;
+ int rc;
+
+ rc = EXIT_SUCCESS;
+
+ result = corosync_cfg_initialize (&handle, NULL);
+ if (result != CS_OK) {
+ fprintf (stderr, "Could not initialize corosync configuration API error %s\n", cs_strerror(result));
+ exit (EXIT_FAILURE);
+ }
+
+ result = corosync_cfg_reopen_log_files (handle);
+ if (result != CS_OK) {
+ fprintf (stderr, "Could not reopen corosync logging files. Error %s\n", cs_strerror(result));
+ rc = (int)result;
+ }
+
+ (void)corosync_cfg_finalize (handle);
+
+ return (rc);
+}
+
+static void shutdown_do(int force)
+{
+ cs_error_t result;
+ corosync_cfg_handle_t handle;
+ corosync_cfg_callbacks_t callbacks;
+ int flag;
+
+ callbacks.corosync_cfg_shutdown_callback = NULL;
+ if (force) {
+ flag = COROSYNC_CFG_SHUTDOWN_FLAG_REGARDLESS;
+ } else {
+ flag = COROSYNC_CFG_SHUTDOWN_FLAG_REQUEST;
+ }
+
+ result = corosync_cfg_initialize (&handle, &callbacks);
+ if (result != CS_OK) {
+ fprintf (stderr, "Could not initialize corosync configuration API error %d\n", result);
+ exit (EXIT_FAILURE);
+ }
+
+ printf ("Shutting down corosync\n");
+ cs_repeat(result, 30, corosync_cfg_try_shutdown (handle, flag));
+ if (result != CS_OK) {
+ fprintf (stderr, "Could not shutdown (error = %d)\n", result);
+ }
+
+ (void)corosync_cfg_finalize (handle);
+}
+
+static int showaddrs_do(unsigned int nodeid)
+{
+ cs_error_t result;
+ corosync_cfg_handle_t handle;
+ int numaddrs;
+ int i;
+ int rc = EXIT_SUCCESS;
+ corosync_cfg_node_address_t addrs[INTERFACE_MAX];
+
+
+ result = corosync_cfg_initialize (&handle, NULL);
+ if (result != CS_OK) {
+ fprintf (stderr, "Could not initialize corosync configuration API error %d\n", result);
+ exit (EXIT_FAILURE);
+ }
+
+ if (corosync_cfg_get_node_addrs(handle, nodeid, INTERFACE_MAX, &numaddrs, addrs) == CS_OK) {
+ for (i=0; i<numaddrs; i++) {
+ char buf[INET6_ADDRSTRLEN];
+ struct sockaddr_storage *ss = (struct sockaddr_storage *)addrs[i].address;
+ struct sockaddr_in *sin = (struct sockaddr_in *)addrs[i].address;
+ struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)addrs[i].address;
+ void *saddr;
+
+ if (!ss->ss_family) {
+ continue;
+ }
+ if (ss->ss_family == AF_INET6) {
+ saddr = &sin6->sin6_addr;
+ } else {
+ saddr = &sin->sin_addr;
+ }
+
+ inet_ntop(ss->ss_family, saddr, buf, sizeof(buf));
+ if (i != 0) {
+ printf(" ");
+ }
+ printf("%s", buf);
+ }
+ printf("\n");
+ } else {
+ fprintf (stderr, "Could not get node address for nodeid %d\n", nodeid);
+ rc = EXIT_FAILURE;
+ }
+
+
+ (void)corosync_cfg_finalize (handle);
+ return rc;
+}
+
+
+static void killnode_do(unsigned int nodeid)
+{
+ cs_error_t result;
+ corosync_cfg_handle_t handle;
+
+ printf ("Killing node " CS_PRI_NODE_ID "\n", nodeid);
+ result = corosync_cfg_initialize (&handle, NULL);
+ if (result != CS_OK) {
+ fprintf (stderr, "Could not initialize corosync configuration API error %d\n", result);
+ exit (EXIT_FAILURE);
+ }
+ result = corosync_cfg_kill_node (handle, nodeid, "Killed by corosync-cfgtool");
+ if (result != CS_OK) {
+ fprintf (stderr, "Could not kill node (error = %s)\n", cs_strerror(result));
+ exit(EXIT_FAILURE);
+ }
+ (void)corosync_cfg_finalize (handle);
+}
+
+
+static void usage_do (void)
+{
+ printf ("corosync-cfgtool [[-i <interface ip>] [-b] -s] [-R] [-L] [-k nodeid] [-a nodeid] [-h] [-H]\n\n");
+ printf ("A tool for displaying and configuring active parameters within corosync.\n");
+ printf ("options:\n");
+ printf ("\t-i\tFinds only information about the specified interface IP address or link id when used with -s..\n");
+ printf ("\t-s\tDisplays the status of the current links on this node.\n");
+ printf ("\t-n\tDisplays the status of the connected nodes and their links.\n");
+ printf ("\t-b\tDisplays the brief status of the current links on this node when used with -s.\n");
+ printf ("\t-R\tTell all instances of corosync in this cluster to reload corosync.conf.\n");
+ printf ("\t-L\tTell corosync to reopen all logging files.\n");
+ printf ("\t-k\tKill a node identified by node id.\n");
+ printf ("\t-a\tDisplay the IP address(es) of a node\n");
+ printf ("\t-h\tPrint basic usage.\n");
+ printf ("\t-H\tShutdown corosync cleanly on this node.\n");
+ printf ("\t\t--force will shut down corosync regardless of daemon vetos\n");
+}
+
+int main (int argc, char *argv[]) {
+ int opt;
+ unsigned int nodeid = 0;
+ char interface_name[128] = "";
+ int rc = EXIT_SUCCESS;
+ enum user_action action = ACTION_NOOP;
+ int brief = 0;
+ long long int l;
+ int option_index = 0;
+ int force_shutdown = 0;
+ const char *options = "i:snbrRLk:a:hH";
+ struct option long_options[] = {
+ {"if", required_argument, 0, 'i'},
+ {"status", no_argument, 0, 's'},
+ {"nodes", no_argument, 0, 'n'},
+ {"brief", no_argument, 0, 'b'},
+ {"reload", no_argument, 0, 'R'},
+ {"reopen", no_argument, 0, 'L'},
+ {"kill", required_argument, 0, 'k'},
+ {"address", required_argument, 0, 'a'},
+ {"shutdown", no_argument, 0, 'H'},
+ {"force", no_argument, 0, 0},
+ {0, 0, 0, 0}
+ };
+
+ while ( (opt = getopt_long(argc, argv, options, long_options, &option_index)) != -1 ) {
+ switch (opt) {
+ case 0: // options with no short equivalent - just --force ATM
+ if (strcmp(long_options[option_index].name, "force") == 0) {
+ force_shutdown = 1;
+ }
+ break;
+ case 'i':
+ strncpy(interface_name, optarg, sizeof(interface_name));
+ interface_name[sizeof(interface_name) - 1] = '\0';
+ break;
+ case 's':
+ action = ACTION_LINKSTATUS_GET;
+ break;
+ case 'n':
+ action = ACTION_NODESTATUS_GET;
+ break;
+ case 'b':
+ brief = 1;
+ break;
+ case 'R':
+ action = ACTION_RELOAD_CONFIG;
+ break;
+ case 'L':
+ action = ACTION_REOPEN_LOG_FILES;
+ break;
+ case 'k':
+ if (util_strtonum(optarg, 1, UINT_MAX, &l) == -1) {
+ fprintf(stderr, "The nodeid was not valid, try a positive number\n");
+ exit(EXIT_FAILURE);
+ }
+ nodeid = l;
+ action = ACTION_KILL_NODE;
+ break;
+ case 'H':
+ action = ACTION_SHUTDOW;
+ break;
+ case 'a':
+ if (util_strtonum(optarg, 1, UINT_MAX, &l) == -1) {
+ fprintf(stderr, "The nodeid was not valid, try a positive number\n");
+ exit(EXIT_FAILURE);
+ }
+ nodeid = l;
+ action = ACTION_SHOWADDR;
+ break;
+ case '?':
+ return (EXIT_FAILURE);
+ break;
+ case 'h':
+ default:
+ break;
+ }
+ }
+ switch(action) {
+ case ACTION_LINKSTATUS_GET:
+ rc = nodestatusget_do(action, brief);
+ break;
+ case ACTION_NODESTATUS_GET:
+ rc = nodestatusget_do(action, brief);
+ break;
+ case ACTION_RELOAD_CONFIG:
+ rc = reload_config_do();
+ break;
+ case ACTION_REOPEN_LOG_FILES:
+ rc = reopen_log_files_do();
+ break;
+ case ACTION_KILL_NODE:
+ killnode_do(nodeid);
+ break;
+ case ACTION_SHUTDOW:
+ shutdown_do(force_shutdown);
+ break;
+ case ACTION_SHOWADDR:
+ rc = showaddrs_do(nodeid);
+ break;
+ case ACTION_NOOP:
+ default:
+ usage_do();
+ break;
+ }
+
+ return (rc);
+}
diff --git a/tools/corosync-cmapctl.c b/tools/corosync-cmapctl.c
new file mode 100644
index 0000000..6c79c9a
--- /dev/null
+++ b/tools/corosync-cmapctl.c
@@ -0,0 +1,996 @@
+/*
+ * Copyright (c) 2011-2012 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Author: Jan Friesse (jfriesse@redhat.com)
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of the Red Hat, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include <ctype.h>
+#include <stdio.h>
+#include <poll.h>
+
+#include <corosync/corotypes.h>
+#include <corosync/cmap.h>
+#include "../lib/util.h"
+
+#ifndef INFTIM
+#define INFTIM -1
+#endif
+
+#define MAX_TRY_AGAIN 10
+
+enum user_action {
+ ACTION_GET,
+ ACTION_SET,
+ ACTION_DELETE,
+ ACTION_DELETE_PREFIX,
+ ACTION_PRINT_PREFIX,
+ ACTION_TRACK,
+ ACTION_LOAD,
+ ACTION_CLEARSTATS,
+};
+
+struct name_to_type_item {
+ const char *name;
+ cmap_value_types_t type;
+};
+
+struct name_to_type_item name_to_type[] = {
+ {"i8", CMAP_VALUETYPE_INT8},
+ {"u8", CMAP_VALUETYPE_UINT8},
+ {"i16", CMAP_VALUETYPE_INT16},
+ {"u16", CMAP_VALUETYPE_UINT16},
+ {"i32", CMAP_VALUETYPE_INT32},
+ {"u32", CMAP_VALUETYPE_UINT32},
+ {"i64", CMAP_VALUETYPE_INT64},
+ {"u64", CMAP_VALUETYPE_UINT64},
+ {"flt", CMAP_VALUETYPE_FLOAT},
+ {"dbl", CMAP_VALUETYPE_DOUBLE},
+ {"str", CMAP_VALUETYPE_STRING},
+ {"bin", CMAP_VALUETYPE_BINARY}};
+
+int show_binary = 0;
+int quiet = 0;
+
+static int convert_name_to_type(const char *name)
+{
+ int i;
+
+ for (i = 0; i < sizeof(name_to_type) / sizeof(*name_to_type); i++) {
+ if (strcmp(name, name_to_type[i].name) == 0) {
+ return (name_to_type[i].type);
+ }
+ }
+
+ return (-1);
+}
+
+static int print_help(void)
+{
+ printf("\n");
+ printf("usage: corosync-cmapctl [-b] [-DdghsqTCt] [-p filename] [-m map] [params...]\n");
+ printf("\n");
+ printf(" -b show binary values\n");
+ printf("\n");
+ printf(" -m select map to use\n");
+ printf(" The default map is 'icmap' which contains configuration information and some runtime variables used by corosync. \n");
+ printf(" A 'stats' map is also available which displays network statistics - in great detail when knet is used as the transport.\n");
+ printf("Set key:\n");
+ printf(" corosync-cmapctl -s key_name type value\n");
+ printf("\n");
+ printf(" where type is one of ([i|u][8|16|32|64] | flt | dbl | str | bin)\n");
+ printf(" for bin, value is file name (or - for stdin)\n");
+ printf("\n");
+ printf(" map can be either 'icmap' (the default) which contains corosync\n");
+ printf(" configuration information, or 'stats' which contains statistics\n");
+ printf(" about the networking and IPC traffic in some detail.\n");
+ printf("\n");
+ printf("Clear stats:\n");
+ printf(" corosync-cmapctl -C [knet|ipc|totem|schedmiss|all]\n");
+ printf(" The 'stats' map is implied\n");
+ printf("\n");
+ printf("Load settings from a file:\n");
+ printf(" corosync-cmapctl -p filename\n");
+ printf("\n");
+ printf(" the format of the file is:\n");
+ printf(" [^[^]]<key_name>[ <type> <value>]\n");
+ printf(" Keys prefixed with single caret ('^') are deleted (see -d).\n");
+ printf(" Keys (actually prefixes) prefixed with double caret ('^^') are deleted by prefix (see -D).\n");
+ printf(" <type> and <value> are optional (not checked) in above cases.\n");
+ printf(" Other keys are set (see -s) so both <type> and <value> are required.\n");
+ printf("\n");
+ printf("Delete key:\n");
+ printf(" corosync-cmapctl -d key_name...\n");
+ printf("\n");
+ printf("Delete multiple keys with prefix:\n");
+ printf(" corosync-cmapctl -D key_prefix...\n");
+ printf("\n");
+ printf("Get key:\n");
+ printf(" corosync-cmapctl [-b] -g key_name...\n");
+ printf("\n");
+ printf("Quiet mode:\n");
+ printf(" corosync-cmapctl [-b] -q -g key_name...\n");
+ printf("\n");
+ printf("Display all keys:\n");
+ printf(" corosync-cmapctl [-b]\n");
+ printf("\n");
+ printf("Display keys with prefix key_name:\n");
+ printf(" corosync-cmapctl [-b] key_name...\n");
+ printf("\n");
+ printf("Track changes on keys with key_name:\n");
+ printf(" corosync-cmapctl [-b] -t key_name\n");
+ printf("\n");
+ printf("Track changes on keys with key prefix:\n");
+ printf(" corosync-cmapctl [-b] -T key_prefix\n");
+ printf("\n");
+
+ return (0);
+}
+
+static void print_binary_key (char *value, size_t value_len)
+{
+ size_t i;
+ char c;
+
+ for (i = 0; i < value_len; i++) {
+ c = value[i];
+ if (c >= ' ' && c < 0x7f && c != '\\') {
+ fputc (c, stdout);
+ } else {
+ if (c == '\\') {
+ printf ("\\\\");
+ } else {
+ printf ("\\x%02X", c);
+ }
+ }
+ }
+}
+
+static void print_key(cmap_handle_t handle,
+ const char *key_name,
+ size_t value_len,
+ const void *value,
+ cmap_value_types_t type)
+{
+ char *str;
+ char *bin_value = NULL;
+ cs_error_t err;
+ int8_t i8;
+ uint8_t u8;
+ int16_t i16;
+ uint16_t u16;
+ int32_t i32;
+ uint32_t u32;
+ int64_t i64;
+ uint64_t u64;
+ float flt;
+ double dbl;
+ int end_loop;
+ int no_retries;
+ size_t bin_value_len;
+
+ end_loop = 0;
+ no_retries = 0;
+
+ err = CS_OK;
+
+ while (!end_loop) {
+ switch (type) {
+ case CMAP_VALUETYPE_INT8:
+ if (value == NULL) {
+ err = cmap_get_int8(handle, key_name, &i8);
+ } else {
+ i8 = *((int8_t *)value);
+ }
+ break;
+ case CMAP_VALUETYPE_INT16:
+ if (value == NULL) {
+ err = cmap_get_int16(handle, key_name, &i16);
+ } else {
+ i16 = *((int16_t *)value);
+ }
+ break;
+ case CMAP_VALUETYPE_INT32:
+ if (value == NULL) {
+ err = cmap_get_int32(handle, key_name, &i32);
+ } else {
+ i32 = *((int32_t *)value);
+ }
+ break;
+ case CMAP_VALUETYPE_INT64:
+ if (value == NULL) {
+ err = cmap_get_int64(handle, key_name, &i64);
+ } else {
+ i64 = *((int64_t *)value);
+ }
+ break;
+ case CMAP_VALUETYPE_UINT8:
+ if (value == NULL) {
+ err = cmap_get_uint8(handle, key_name, &u8);
+ } else {
+ u8 = *((uint8_t *)value);
+ }
+ break;
+ case CMAP_VALUETYPE_UINT16:
+ if (value == NULL) {
+ err = cmap_get_uint16(handle, key_name, &u16);
+ } else {
+ u16 = *((uint16_t *)value);
+ }
+ break;
+ case CMAP_VALUETYPE_UINT32:
+ if (value == NULL) {
+ err = cmap_get_uint32(handle, key_name, &u32);
+ } else {
+ u32 = *((uint32_t *)value);
+ }
+ break;
+ case CMAP_VALUETYPE_UINT64:
+ if (value == NULL) {
+ err = cmap_get_uint64(handle, key_name, &u64);
+ } else {
+ u64 = *((uint64_t *)value);
+ }
+ break;
+ case CMAP_VALUETYPE_FLOAT:
+ if (value == NULL) {
+ err = cmap_get_float(handle, key_name, &flt);
+ } else {
+ flt = *((float *)value);
+ }
+ break;
+ case CMAP_VALUETYPE_DOUBLE:
+ if (value == NULL) {
+ err = cmap_get_double(handle, key_name, &dbl);
+ } else {
+ dbl = *((double *)value);
+ }
+ break;
+ case CMAP_VALUETYPE_STRING:
+ if (value == NULL) {
+ err = cmap_get_string(handle, key_name, &str);
+ } else {
+ str = (char *)value;
+ }
+ break;
+ case CMAP_VALUETYPE_BINARY:
+ if (show_binary) {
+ if (value == NULL) {
+ bin_value = malloc(value_len);
+ if (bin_value == NULL) {
+ fprintf(stderr, "Can't alloc memory\n");
+ exit(EXIT_FAILURE);
+ }
+ bin_value_len = value_len;
+ err = cmap_get(handle, key_name, bin_value, &bin_value_len, NULL);
+ } else {
+ bin_value = (char *)value;
+ }
+ }
+ break;
+ }
+
+ if (err == CS_OK) {
+ end_loop = 1;
+ } else if (err == CS_ERR_TRY_AGAIN) {
+ sleep(1);
+ no_retries++;
+
+ if (no_retries > MAX_TRY_AGAIN) {
+ end_loop = 1;
+ }
+ } else {
+ end_loop = 1;
+ }
+ };
+
+ if (err != CS_OK) {
+ fprintf(stderr, "Can't get value of %s. Error %s\n", key_name, cs_strerror(err));
+
+ /*
+ * bin_value was newly allocated
+ */
+ if (bin_value != NULL && value == NULL) {
+ free(bin_value);
+ }
+ return ;
+ }
+
+ if (!quiet)
+ printf("%s (", key_name);
+
+ switch (type) {
+ case CMAP_VALUETYPE_INT8:
+ if (!quiet)
+ printf("%s) = %"PRId8, "i8", i8);
+ else
+ printf("%"PRId8, i8);
+ break;
+ case CMAP_VALUETYPE_UINT8:
+ if (!quiet)
+ printf("%s) = %"PRIu8, "u8", u8);
+ else
+ printf("%"PRIu8, u8);
+ break;
+ case CMAP_VALUETYPE_INT16:
+ if (!quiet)
+ printf("%s) = %"PRId16, "i16", i16);
+ else
+ printf("%"PRId16, i16);
+ break;
+ case CMAP_VALUETYPE_UINT16:
+ if (!quiet)
+ printf("%s) = %"PRIu16, "u16", u16);
+ else
+ printf("%"PRIu16, u16);
+ break;
+ case CMAP_VALUETYPE_INT32:
+ if (!quiet)
+ printf("%s) = %"PRId32, "i32", i32);
+ else
+ printf("%"PRId32, i32);
+ break;
+ case CMAP_VALUETYPE_UINT32:
+ if (!quiet)
+ printf("%s) = %"PRIu32, "u32", u32);
+ else
+ printf("%"PRIu32, u32);
+ break;
+ case CMAP_VALUETYPE_INT64:
+ if (!quiet)
+ printf("%s) = %"PRId64, "i64", i64);
+ else
+ printf("%"PRId64, i64);
+ break;
+ case CMAP_VALUETYPE_UINT64:
+ if (!quiet)
+ printf("%s) = %"PRIu64, "u64", u64);
+ else
+ printf("%"PRIu64, u64);
+ break;
+ case CMAP_VALUETYPE_FLOAT:
+ if (!quiet)
+ printf("%s) = %f", "flt", flt);
+ else
+ printf("%f", flt);
+ break;
+ case CMAP_VALUETYPE_DOUBLE:
+ if (!quiet)
+ printf("%s) = %lf", "dbl", dbl);
+ else
+ printf("%lf", dbl);
+ break;
+ case CMAP_VALUETYPE_STRING:
+ if (!quiet)
+ printf("%s) = %s", "str", str);
+ else
+ printf("%s", str);
+ if (value == NULL) {
+ free(str);
+ }
+ break;
+ case CMAP_VALUETYPE_BINARY:
+ printf("%s)", "bin");
+ if (show_binary) {
+ printf(" = ");
+ if (bin_value) {
+ print_binary_key(bin_value, value_len);
+ if (value == NULL) {
+ free(bin_value);
+ }
+ } else {
+ printf("*empty*");
+ }
+ }
+ break;
+ }
+
+ printf("\n");
+}
+
+static int print_iter(cmap_handle_t handle, const char *prefix)
+{
+ cmap_iter_handle_t iter_handle;
+ char key_name[CMAP_KEYNAME_MAXLEN + 1];
+ size_t value_len;
+ cmap_value_types_t type;
+ cs_error_t err;
+ int no_result = 1;
+
+ err = cmap_iter_init(handle, prefix, &iter_handle);
+ if (err != CS_OK) {
+ fprintf (stderr, "Failed to initialize iteration. Error %s\n", cs_strerror(err));
+ exit (EXIT_FAILURE);
+ }
+
+ while ((err = cmap_iter_next(handle, iter_handle, key_name, &value_len, &type)) == CS_OK) {
+ no_result = 0;
+ print_key(handle, key_name, value_len, NULL, type);
+ }
+
+ cmap_iter_finalize(handle, iter_handle);
+ return no_result;
+}
+
+static void delete_with_prefix(cmap_handle_t handle, const char *prefix)
+{
+ cmap_iter_handle_t iter_handle;
+ char key_name[CMAP_KEYNAME_MAXLEN + 1];
+ size_t value_len;
+ cmap_value_types_t type;
+ cs_error_t err;
+ cs_error_t err2;
+
+ err = cmap_iter_init(handle, prefix, &iter_handle);
+ if (err != CS_OK) {
+ fprintf (stderr, "Failed to initialize iteration. Error %s\n", cs_strerror(err));
+ exit (EXIT_FAILURE);
+ }
+
+ while ((err = cmap_iter_next(handle, iter_handle, key_name, &value_len, &type)) == CS_OK) {
+ err2 = cmap_delete(handle, key_name);
+ if (err2 != CS_OK) {
+ fprintf(stderr, "Can't delete key %s. Error %s\n", key_name, cs_strerror(err2));
+ }
+ }
+ cmap_iter_finalize(handle, iter_handle);
+}
+
+static void cmap_notify_fn(
+ cmap_handle_t cmap_handle,
+ cmap_track_handle_t cmap_track_handle,
+ int32_t event,
+ const char *key_name,
+ struct cmap_notify_value new_val,
+ struct cmap_notify_value old_val,
+ void *user_data)
+{
+ switch (event) {
+ case CMAP_TRACK_ADD:
+ printf("create> ");
+ print_key(cmap_handle, key_name, new_val.len, new_val.data, new_val.type);
+ break;
+ case CMAP_TRACK_DELETE:
+ printf("delete> ");
+ print_key(cmap_handle, key_name, old_val.len, old_val.data, old_val.type);
+ break;
+ case CMAP_TRACK_MODIFY:
+ printf("modify> ");
+ print_key(cmap_handle, key_name, new_val.len, new_val.data, new_val.type);
+ break;
+ default:
+ printf("unknown change> ");
+ break;
+ }
+
+}
+
+static void add_track(cmap_handle_t handle, const char *key_name, int prefix)
+{
+ cmap_track_handle_t track_handle;
+ int32_t track_type;
+ cs_error_t err;
+
+ track_type = CMAP_TRACK_ADD | CMAP_TRACK_DELETE | CMAP_TRACK_MODIFY;
+ if (prefix) {
+ track_type |= CMAP_TRACK_PREFIX;
+ }
+
+ err = cmap_track_add(handle, key_name, track_type, cmap_notify_fn, NULL, &track_handle);
+ if (err != CS_OK) {
+ fprintf(stderr, "Failed to add tracking function. Error %s\n", cs_strerror(err));
+ exit (EXIT_FAILURE);
+ }
+}
+
+static void track_changes(cmap_handle_t handle)
+{
+ struct pollfd pfd[2];
+ int cmap_fd;
+ cs_error_t err;
+ int poll_res;
+ char inbuf[3];
+ int quit = CS_FALSE;
+
+ err = cmap_fd_get(handle, &cmap_fd);
+ if (err != CS_OK) {
+ fprintf(stderr, "Failed to get file handle. Error %s\n", cs_strerror(err));
+ exit (EXIT_FAILURE);
+ }
+
+ pfd[0].fd = cmap_fd;
+ pfd[1].fd = STDIN_FILENO;
+ pfd[0].events = pfd[1].events = POLLIN;
+
+ printf("Type \"q\" to finish\n");
+ do {
+ pfd[0].revents = pfd[1].revents = 0;
+ poll_res = poll(pfd, 2, INFTIM);
+ if (poll_res == -1) {
+ perror("poll");
+ }
+
+ if (pfd[1].revents & POLLIN) {
+ if (fgets(inbuf, sizeof(inbuf), stdin) == NULL) {
+ quit = CS_TRUE;
+ } else if (strncmp(inbuf, "q", 1) == 0) {
+ quit = CS_TRUE;
+ }
+ }
+
+ if (pfd[0].revents & POLLIN) {
+ err = cmap_dispatch(handle, CS_DISPATCH_ALL);
+ if (err != CS_OK) {
+ fprintf(stderr, "Dispatch error %s\n", cs_strerror(err));
+ quit = CS_TRUE;
+ }
+ }
+ } while (poll_res > 0 && !quit);
+}
+
+static cs_error_t set_key_bin(cmap_handle_t handle, const char *key_name, const char *fname)
+{
+ FILE *f;
+ char *val;
+ char buf[4096];
+ size_t size;
+ size_t readed;
+ size_t pos;
+ cs_error_t err;
+
+ if (strcmp(fname, "-") == 0) {
+ f = stdin;
+ } else {
+ f = fopen(fname, "rb");
+ if (f == NULL) {
+ perror("Can't open input file");
+ exit(EXIT_FAILURE);
+ }
+ }
+
+ val = NULL;
+ size = 0;
+ pos = 0;
+
+ while ((readed = fread(buf, 1, sizeof(buf), f)) != 0) {
+ size += readed;
+ if ((val = realloc(val, size)) == NULL) {
+ fprintf(stderr, "Can't alloc memory\n");
+ exit (EXIT_FAILURE);
+ }
+ memcpy(val + pos, buf, readed);
+ pos += readed;
+ }
+
+ if (f != stdin) {
+ fclose(f);
+ }
+
+ err = cmap_set(handle, key_name, val, size, CMAP_VALUETYPE_BINARY);
+ free(val);
+
+ return (err);
+}
+
+static void set_key(cmap_handle_t handle, const char *key_name, const char *key_type_s, const char *key_value_s)
+{
+ int64_t i64;
+ uint64_t u64;
+ double dbl;
+ float flt;
+ cs_error_t err = CS_OK;
+ int scanf_res = 0;
+
+ cmap_value_types_t type;
+
+ if (convert_name_to_type(key_type_s) == -1) {
+ fprintf(stderr, "Unknown type %s\n", key_type_s);
+ exit (EXIT_FAILURE);
+ }
+
+ type = convert_name_to_type(key_type_s);
+
+ switch (type) {
+ case CMAP_VALUETYPE_INT8:
+ case CMAP_VALUETYPE_INT16:
+ case CMAP_VALUETYPE_INT32:
+ case CMAP_VALUETYPE_INT64:
+ scanf_res = sscanf(key_value_s, "%"PRId64, &i64);
+ break;
+ case CMAP_VALUETYPE_UINT8:
+ case CMAP_VALUETYPE_UINT16:
+ case CMAP_VALUETYPE_UINT32:
+ case CMAP_VALUETYPE_UINT64:
+ scanf_res = sscanf(key_value_s, "%"PRIu64, &u64);
+ break;
+ case CMAP_VALUETYPE_FLOAT:
+ scanf_res = sscanf(key_value_s, "%f", &flt);
+ break;
+ case CMAP_VALUETYPE_DOUBLE:
+ scanf_res = sscanf(key_value_s, "%lf", &dbl);
+ break;
+ case CMAP_VALUETYPE_STRING:
+ case CMAP_VALUETYPE_BINARY:
+ /*
+ * Do nothing
+ */
+ scanf_res = 1;
+ break;
+ }
+
+ if (scanf_res != 1) {
+ fprintf(stderr, "%s is not valid %s type value\n", key_value_s, key_type_s);
+ exit(EXIT_FAILURE);
+ }
+ /*
+ * We have parsed value, so insert value
+ */
+
+ switch (type) {
+ case CMAP_VALUETYPE_INT8:
+ if (i64 > INT8_MAX || i64 < INT8_MIN) {
+ fprintf(stderr, "%s is not valid i8 integer\n", key_value_s);
+ exit(EXIT_FAILURE);
+ }
+ err = cmap_set_int8(handle, key_name, i64);
+ break;
+ case CMAP_VALUETYPE_INT16:
+ if (i64 > INT16_MAX || i64 < INT16_MIN) {
+ fprintf(stderr, "%s is not valid i16 integer\n", key_value_s);
+ exit(EXIT_FAILURE);
+ }
+ err = cmap_set_int16(handle, key_name, i64);
+ break;
+ case CMAP_VALUETYPE_INT32:
+ if (i64 > INT32_MAX || i64 < INT32_MIN) {
+ fprintf(stderr, "%s is not valid i32 integer\n", key_value_s);
+ exit(EXIT_FAILURE);
+ }
+ err = cmap_set_int32(handle, key_name, i64);
+ break;
+ case CMAP_VALUETYPE_INT64:
+ err = cmap_set_int64(handle, key_name, i64);
+ break;
+
+ case CMAP_VALUETYPE_UINT8:
+ if (u64 > UINT8_MAX) {
+ fprintf(stderr, "%s is not valid u8 integer\n", key_value_s);
+ exit(EXIT_FAILURE);
+ }
+ err = cmap_set_uint8(handle, key_name, u64);
+ break;
+ case CMAP_VALUETYPE_UINT16:
+ if (u64 > UINT16_MAX) {
+ fprintf(stderr, "%s is not valid u16 integer\n", key_value_s);
+ exit(EXIT_FAILURE);
+ }
+ err = cmap_set_uint16(handle, key_name, u64);
+ break;
+ case CMAP_VALUETYPE_UINT32:
+ if (u64 > UINT32_MAX) {
+ fprintf(stderr, "%s is not valid u32 integer\n", key_value_s);
+ exit(EXIT_FAILURE);
+ }
+ err = cmap_set_uint32(handle, key_name, u64);
+ break;
+ case CMAP_VALUETYPE_UINT64:
+ err = cmap_set_uint64(handle, key_name, u64);
+ break;
+ case CMAP_VALUETYPE_FLOAT:
+ err = cmap_set_float(handle, key_name, flt);
+ break;
+ case CMAP_VALUETYPE_DOUBLE:
+ err = cmap_set_double(handle, key_name, dbl);
+ break;
+ case CMAP_VALUETYPE_STRING:
+ err = cmap_set_string(handle, key_name, key_value_s);
+ break;
+ case CMAP_VALUETYPE_BINARY:
+ err = set_key_bin(handle, key_name, key_value_s);
+ break;
+ }
+
+ if (err != CS_OK) {
+ fprintf (stderr, "Failed to set key %s. Error %s\n", key_name, cs_strerror(err));
+ exit (EXIT_FAILURE);
+ }
+}
+
+
+static void read_in_config_file(cmap_handle_t handle, char * filename)
+{
+ int ignore;
+ int c;
+ FILE* fh;
+ char buf[1024];
+ char * line;
+ char *key_name;
+ char *key_type_s;
+ char *key_value_s;
+
+ fh = fopen(filename, "r");
+ if (fh == NULL) {
+ perror ("Couldn't open file.");
+ return;
+ }
+
+ while (fgets (buf, 1024, fh) != NULL) {
+ /* find the first real character, if it is
+ * a '#' then ignore this line.
+ * else process.
+ * if no real characters then also ignore.
+ */
+ ignore = 1;
+ for (c = 0; c < 1024; c++) {
+ if (isblank (buf[c])) {
+ continue;
+ }
+
+ if (buf[c] == '#' || buf[c] == '\n') {
+ ignore = 1;
+ break;
+ }
+ ignore = 0;
+ line = &buf[c];
+ break;
+ }
+ if (ignore == 1) {
+ continue;
+ }
+
+ /*
+ * should be:
+ * [^[^]]<key>[ <type> <value>]
+ */
+ key_name = strtok(line, " \n");
+ if (key_name && *key_name == '^') {
+ key_name++;
+ if (*key_name == '^') {
+ key_name++;
+ delete_with_prefix(handle, key_name);
+ } else {
+ cs_error_t err;
+
+ err = cmap_delete(handle, key_name);
+ if (err != CS_OK) {
+ fprintf(stderr, "Can't delete key %s. Error %s\n", key_name, cs_strerror(err));
+ }
+ }
+ } else {
+ key_type_s = strtok(NULL, " \n");
+ key_value_s = strtok(NULL, " \n");
+ if (key_type_s == NULL || key_value_s == NULL) {
+ fprintf(stderr, "Both type and value for key %s are required\n", key_name);
+ exit (EXIT_FAILURE);
+ }
+ set_key(handle, key_name, key_type_s, key_value_s);
+ }
+ }
+
+ fclose (fh);
+}
+
+static void clear_stats(cmap_handle_t handle, char *clear_opt)
+{
+ char key_name[CMAP_KEYNAME_MAXLEN + 1];
+
+ sprintf(key_name, "stats.clear.%s", clear_opt);
+ cmap_set_uint32(handle, key_name, 1);
+}
+
+int main(int argc, char *argv[])
+{
+ enum user_action action;
+ int c;
+ cs_error_t err;
+ cmap_handle_t handle;
+ int i;
+ size_t value_len;
+ cmap_value_types_t type;
+ cmap_map_t map = CMAP_MAP_DEFAULT;
+ int track_prefix;
+ int map_set = 0;
+ int no_retries;
+ char * clear_opt = NULL;
+ char * settings_file = NULL;
+ int count_of_no_result = 0;
+
+ action = ACTION_PRINT_PREFIX;
+ track_prefix = 1;
+
+ while ((c = getopt(argc, argv, "m:hqgsdDtTbp:C:")) != -1) {
+ switch (c) {
+ case 'h':
+ return print_help();
+ break;
+ case 'b':
+ show_binary++;
+ break;
+ case 'q':
+ quiet = 1;
+ break;
+ case 'g':
+ action = ACTION_GET;
+ break;
+ case 's':
+ action = ACTION_SET;
+ break;
+ case 'd':
+ action = ACTION_DELETE;
+ break;
+ case 'D':
+ action = ACTION_DELETE_PREFIX;
+ break;
+ case 'p':
+ settings_file = optarg;
+ action = ACTION_LOAD;
+ break;
+ case 'C':
+ if (strcmp(optarg, "knet") == 0 ||
+ strcmp(optarg, "totem") == 0 ||
+ strcmp(optarg, "ipc") == 0 ||
+ strcmp(optarg, "schedmiss") == 0 ||
+ strcmp(optarg, "all") == 0) {
+ action = ACTION_CLEARSTATS;
+ clear_opt = optarg;
+
+ /* Force the map to be STATS */
+ map = CMAP_MAP_STATS;
+ }
+ else {
+ fprintf(stderr, "argument to -C should be 'knet', 'totem', 'ipc', 'schedmiss' or 'all'\n");
+ return (EXIT_FAILURE);
+ }
+ break;
+ case 't':
+ action = ACTION_TRACK;
+ track_prefix = 0;
+ break;
+ case 'T':
+ action = ACTION_TRACK;
+ break;
+ case 'm':
+ if (strcmp(optarg, "icmap") == 0 ||
+ strcmp(optarg, "default") == 0) {
+ map = CMAP_MAP_ICMAP;
+ map_set = 1;
+ }
+ if (strcmp(optarg, "stats") == 0) {
+ map = CMAP_MAP_STATS;
+ map_set = 1;
+ }
+ if (!map_set) {
+ fprintf(stderr, "invalid map name, must be 'default', 'icmap' or 'stats'\n");
+ return (EXIT_FAILURE);
+ }
+ break;
+ case '?':
+ return (EXIT_FAILURE);
+ break;
+ default:
+ action = ACTION_PRINT_PREFIX;
+ break;
+ }
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ if (argc == 0 &&
+ action != ACTION_LOAD &&
+ action != ACTION_CLEARSTATS &&
+ action != ACTION_PRINT_PREFIX) {
+ fprintf(stderr, "Expected key after options\n");
+ return (EXIT_FAILURE);
+ }
+
+ no_retries = 0;
+
+ while ((err = cmap_initialize_map(&handle, map)) == CS_ERR_TRY_AGAIN && no_retries++ < MAX_TRY_AGAIN) {
+ sleep(1);
+ }
+
+ if (err != CS_OK) {
+ fprintf (stderr, "Failed to initialize the cmap API. Error %s\n", cs_strerror(err));
+ exit (EXIT_FAILURE);
+ }
+
+ switch (action) {
+ case ACTION_PRINT_PREFIX:
+ if (argc == 0) {
+ count_of_no_result = print_iter(handle, NULL);
+ } else {
+ for (i = 0; i < argc; i++) {
+ count_of_no_result += print_iter(handle, argv[i]);
+ }
+ }
+
+ if (count_of_no_result > 0 && count_of_no_result >= argc) {
+ return (EXIT_FAILURE);
+ }
+ break;
+ case ACTION_GET:
+ for (i = 0; i < argc; i++) {
+ err = cmap_get(handle, argv[i], NULL, &value_len, &type);
+ if (err == CS_OK) {
+ print_key(handle, argv[i], value_len, NULL, type);
+ } else {
+ fprintf(stderr, "Can't get key %s. Error %s\n", argv[i], cs_strerror(err));
+ return (EXIT_FAILURE);
+ }
+ }
+ break;
+ case ACTION_DELETE:
+ for (i = 0; i < argc; i++) {
+ err = cmap_delete(handle, argv[i]);
+ if (err != CS_OK) {
+ fprintf(stderr, "Can't delete key %s. Error %s\n", argv[i], cs_strerror(err));
+ return (EXIT_FAILURE);
+ }
+ }
+ break;
+ case ACTION_DELETE_PREFIX:
+ for (i = 0; i < argc; i++) {
+ delete_with_prefix(handle, argv[i]);
+ }
+ break;
+ case ACTION_LOAD:
+ read_in_config_file(handle, settings_file);
+ break;
+ case ACTION_TRACK:
+ for (i = 0; i < argc; i++) {
+ add_track(handle, argv[i], track_prefix);
+ }
+ track_changes(handle);
+ break;
+ case ACTION_SET:
+ if (argc < 3) {
+ fprintf(stderr, "At least 3 parameters are expected for set\n");
+ return (EXIT_FAILURE);
+ }
+
+ set_key(handle, argv[0], argv[1], argv[2]);
+ break;
+ case ACTION_CLEARSTATS:
+ clear_stats(handle, clear_opt);
+ break;
+
+ }
+
+ err = cmap_finalize(handle);
+ if (err != CS_OK) {
+ fprintf (stderr, "Failed to finalize the cmap API. Error %s\n", cs_strerror(err));
+ exit (EXIT_FAILURE);
+ }
+
+ return (0);
+}
diff --git a/tools/corosync-cpgtool.c b/tools/corosync-cpgtool.c
new file mode 100644
index 0000000..b52a35b
--- /dev/null
+++ b/tools/corosync-cpgtool.c
@@ -0,0 +1,276 @@
+/*
+ * Copyright (c) 2009-2011 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Author: Jan Friesse <jfriesse@redhat.com>
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of the MontaVista Software, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <unistd.h>
+#include <string.h>
+#include <pthread.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/select.h>
+#include <sys/un.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <libgen.h>
+
+#include <corosync/corotypes.h>
+#include <corosync/totem/totem.h>
+#include <corosync/cfg.h>
+#include <corosync/cpg.h>
+
+static corosync_cfg_handle_t cfg_handle;
+static cpg_handle_t cpg_handle;
+
+typedef enum {
+ OPER_NAMES_ONLY = 1,
+ OPER_FULL_OUTPUT = 2,
+} operation_t;
+
+static void fprint_addrs(FILE *f, unsigned int nodeid)
+{
+ int numaddrs;
+ int i;
+ corosync_cfg_node_address_t addrs[INTERFACE_MAX];
+
+ if (corosync_cfg_get_node_addrs(cfg_handle, nodeid, INTERFACE_MAX, &numaddrs, addrs) == CS_OK) {
+ for (i=0; i<numaddrs; i++) {
+ char buf[INET6_ADDRSTRLEN];
+ struct sockaddr_storage *ss = (struct sockaddr_storage *)addrs[i].address;
+ struct sockaddr_in *sin = (struct sockaddr_in *)addrs[i].address;
+ struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)addrs[i].address;
+ void *saddr;
+
+ if (!ss->ss_family) {
+ continue;
+ }
+
+ if (ss->ss_family == AF_INET6) {
+ saddr = &sin6->sin6_addr;
+ } else {
+ saddr = &sin->sin_addr;
+ }
+
+ inet_ntop(ss->ss_family, saddr, buf, sizeof(buf));
+ if (i != 0) {
+ fprintf(f, " ");
+ }
+ fprintf(f, "%s", buf);
+ }
+ }
+}
+
+static void fprint_group (FILE *f, int escape, const struct cpg_name *group) {
+ int i;
+ char c;
+
+ for (i = 0; i < group->length; i++) {
+ c = group->value[i];
+
+ if (!escape || (c >= ' ' && c < 0x7f && c != '\\')) {
+ fputc (c, f);
+ } else {
+ if (c == '\\')
+ fprintf (f, "\\\\");
+ else
+ fprintf (f, "\\x%02X", c);
+ }
+ }
+}
+
+static int display_groups (char delimiter, int escape)
+{
+ cs_error_t res;
+ cpg_iteration_handle_t iter_handle;
+ struct cpg_iteration_description_t description;
+
+ res = cpg_iteration_initialize (cpg_handle, CPG_ITERATION_NAME_ONLY, NULL, &iter_handle);
+ if (res != CS_OK) {
+ fprintf (stderr, "Cannot initialize cpg iterator error %d\n", res);
+
+ return 0;
+ }
+
+ while ((res = cpg_iteration_next (iter_handle, &description)) == CS_OK) {
+ fprint_group (stdout, escape, &description.group);
+ fputc ((delimiter ? delimiter : '\n'), stdout);
+ }
+
+ if (delimiter)
+ putc ('\n', stdout);
+
+ cpg_iteration_finalize (iter_handle);
+
+ return 1;
+}
+
+static inline int group_name_compare (
+ const struct cpg_name *g1,
+ const struct cpg_name *g2)
+{
+ return (g1->length == g2->length?
+ memcmp (g1->value, g2->value, g1->length):
+ g1->length - g2->length);
+}
+
+static int display_groups_with_members (char delimiter, int escape) {
+ cs_error_t res;
+ cpg_iteration_handle_t iter_handle;
+ struct cpg_iteration_description_t description;
+ struct cpg_name old_group;
+
+ res = cpg_iteration_initialize (cpg_handle, CPG_ITERATION_ALL, NULL, &iter_handle);
+ if (res != CS_OK) {
+ fprintf (stderr, "Cannot initialize cpg iterator error %d\n", res);
+
+ return 0;
+ }
+
+ memset (&old_group, 0, sizeof (struct cpg_name));
+
+ if (delimiter) {
+ fprintf (stdout, "GRP_NAME%cPID%cNODEID\n", delimiter, delimiter);
+ } else {
+ fprintf (stdout, "Group Name\t%10s\t%10s\n", "PID", "Node ID");
+ }
+
+ while ((res = cpg_iteration_next (iter_handle, &description)) == CS_OK) {
+ if (!delimiter && group_name_compare (&old_group, &description.group) != 0) {
+ fprint_group (stdout, escape, &description.group);
+ fprintf (stdout, "\n");
+
+ memcpy (&old_group, &description.group, sizeof (struct cpg_name));
+ }
+
+ if (!delimiter) {
+ fprintf (stdout, "\t\t%10u\t%10u (", description.pid, description.nodeid);
+ fprint_addrs (stdout, description.nodeid);
+ fprintf (stdout, ")\n");
+ } else {
+ fprint_group (stdout, escape, &description.group);
+ fprintf (stdout, "%c%u%c%u\n", delimiter, description.pid, delimiter, description.nodeid);
+ }
+ }
+
+ if (res != CS_ERR_NO_SECTIONS) {
+ fprintf (stderr, "cpg iteration error %d\n", res);
+
+ return 0;
+ }
+
+ cpg_iteration_finalize (iter_handle);
+
+ return 1;
+}
+
+static void usage_do (const char *prog_name)
+{
+ printf ("%s [-d delimiter] [-e] [-n] [-h]\n\n", prog_name);
+ printf ("A tool for displaying cpg groups and members.\n");
+ printf ("options:\n");
+ printf ("\t-d\tDelimiter between fields.\n");
+ printf ("\t-e\tDon't escape unprintable characters in group name.\n");
+ printf ("\t-n\tDisplay only all existing group names.\n");
+ printf ("\t-h\tDisplay this help.\n");
+}
+
+
+int main (int argc, char *argv[]) {
+ const char *options = "hd:ne";
+ int opt;
+ const char *prog_name = basename(argv[0]);
+ char delimiter = 0;
+ int escape = 1;
+ operation_t operation = OPER_FULL_OUTPUT;
+ int result;
+
+ while ( (opt = getopt(argc, argv, options)) != -1 ) {
+ switch (opt) {
+ case 'd':
+ if (strlen (optarg) > 0) {
+ delimiter = optarg[0];
+ }
+ break;
+
+ case 'n':
+ operation = OPER_NAMES_ONLY;
+ break;
+
+ case 'e':
+ escape = 0;
+ break;
+
+ case 'h':
+ usage_do (prog_name);
+ return (EXIT_SUCCESS);
+ break;
+
+ case '?':
+ case ':':
+ return (EXIT_FAILURE);
+ break;
+ }
+ }
+
+ result = cpg_initialize (&cpg_handle, NULL);
+
+ if (result != CS_OK) {
+ fprintf (stderr, "Could not initialize corosync cpg API error %d\n", result);
+ return (EXIT_FAILURE);
+ }
+
+ result = corosync_cfg_initialize (&cfg_handle, NULL);
+ if (result != CS_OK) {
+ fprintf (stderr, "Could not initialize corosync configuration API error %d\n", result);
+ return (EXIT_FAILURE);
+ }
+
+ switch (operation) {
+ case OPER_NAMES_ONLY:
+ result = display_groups (delimiter, escape);
+ break;
+
+ case OPER_FULL_OUTPUT:
+ result = display_groups_with_members (delimiter, escape);
+ break;
+ }
+
+ cpg_finalize (cpg_handle);
+ corosync_cfg_finalize (cfg_handle);
+
+ return (result ? EXIT_SUCCESS : EXIT_FAILURE);
+}
diff --git a/tools/corosync-keygen.c b/tools/corosync-keygen.c
new file mode 100644
index 0000000..243661a
--- /dev/null
+++ b/tools/corosync-keygen.c
@@ -0,0 +1,191 @@
+/*
+ * Copyright (c) 2004 MontaVista Software, Inc.
+ * Copyright (c) 2005-2019 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Author: Steven Dake (sdake@redhat.com)
+ * Jan Friesse (jfriesse@redhat.com)
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of the MontaVista Software, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include <err.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <string.h>
+#include <getopt.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <netinet/in.h>
+
+#include <corosync/totem/totem.h>
+
+#define DEFAULT_KEYFILE COROSYSCONFDIR "/authkey"
+
+#define DEFAULT_KEYFILE_LEN 256
+
+#define DEFAULT_RANDOM_DEV "/dev/urandom"
+
+static const char usage[] =
+ "Usage: corosync-keygen [-k <keyfile>] [-s size] [-m <randomfile>] [-l] [-h]\n"
+ " -k / --key-file=<filename> - Write to the specified keyfile\n"
+ " instead of the default " DEFAULT_KEYFILE ".\n"
+ " -r / --random-file - Random number source file. Default is \n"
+ " /dev/urandom. As an example /dev/random may be requested\n"
+ " (that may require user input for entropy).\n"
+ " -l / --less-secure - Not used, option is kept only\n"
+ " for compatibility.\n"
+ " -s / --size - Length of key.\n"
+ " -h / --help - Print basic usage.\n";
+
+
+int main (int argc, char *argv[])
+{
+ int authkey_fd;
+ int random_fd;
+ char *keyfile = NULL;
+ unsigned char key[TOTEM_PRIVATE_KEY_LEN_MAX];
+ ssize_t res;
+ ssize_t bytes_read;
+ size_t key_len = DEFAULT_KEYFILE_LEN;
+ const char *random_dev = DEFAULT_RANDOM_DEV;
+ long long int tmpll;
+ char *ep;
+ int c;
+ int option_index;
+ static struct option long_options[] = {
+ { "key-file", required_argument, NULL, 'k' },
+ { "less-secure", no_argument, NULL, 'l' },
+ { "random-file", required_argument, NULL, 'r' },
+ { "size", required_argument, NULL, 's' },
+ { "help", no_argument, NULL, 'h' },
+ { 0, 0, NULL, 0 },
+ };
+
+ while ((c = getopt_long (argc, argv, "k:r:s:lh",
+ long_options, &option_index)) != -1) {
+ switch (c) {
+ case 'k':
+ keyfile = optarg;
+ break;
+ case 'l':
+ /*
+ * Only kept for compatibility
+ */
+ break;
+ case 'r':
+ random_dev = optarg;
+ break;
+ case 's':
+ tmpll = strtoll(optarg, &ep, 10);
+ if (tmpll < TOTEM_PRIVATE_KEY_LEN_MIN ||
+ tmpll > TOTEM_PRIVATE_KEY_LEN_MAX ||
+ errno != 0 || *ep != '\0') {
+ errx (1, "Unsupported key size (supported <%u,%u>)\n",
+ TOTEM_PRIVATE_KEY_LEN_MIN,
+ TOTEM_PRIVATE_KEY_LEN_MAX);
+ }
+
+ key_len = (size_t)tmpll;
+ break;
+ case 'h':
+ printf ("%s\n", usage);
+ exit(0);
+ break;
+ default:
+ printf ("Error parsing command line options.\n");
+ exit (1);
+ }
+ }
+
+ printf ("Corosync Cluster Engine Authentication key generator.\n");
+
+ if (!keyfile) {
+ keyfile = (char *)DEFAULT_KEYFILE;
+ }
+
+ printf ("Gathering %lu bits for key from %s.\n", (unsigned long)(key_len * 8), random_dev);
+ random_fd = open (random_dev, O_RDONLY);
+
+ if (random_fd == -1) {
+ err (1, "Failed to open random source");
+ }
+
+ if (strcmp(random_dev, "/dev/random") == 0) {
+ printf ("Press keys on your keyboard to generate entropy.\n");
+ }
+ /*
+ * Read random data
+ */
+ bytes_read = 0;
+
+retry_read:
+ res = read (random_fd, &key[bytes_read], key_len - bytes_read);
+ if (res == -1) {
+ err (1, "Could not read /dev/random");
+ }
+ bytes_read += res;
+ if (bytes_read != key_len) {
+ printf ("Press keys on your keyboard to generate entropy (%d bits still needed).\n",
+ (int)((key_len - bytes_read) * 8));
+ goto retry_read;
+ }
+ close (random_fd);
+
+ /*
+ * Open key
+ */
+ authkey_fd = open (keyfile, O_CREAT|O_WRONLY|O_TRUNC, 0600);
+ if (authkey_fd == -1) {
+ err (2, "Could not create %s", keyfile);
+ }
+ if (fchmod (authkey_fd, 0400)) {
+ err (3, "Failed to set key file permissions to 0400");
+ }
+
+ printf ("Writing corosync key to %s.\n", keyfile);
+
+ /*
+ * Write key
+ */
+ res = write (authkey_fd, key, key_len);
+ if (res != key_len) {
+ err (4, "Could not write %s", keyfile);
+ }
+
+ if (close (authkey_fd)) {
+ err (5, "Could not close %s", keyfile);
+ }
+
+ return (0);
+}
diff --git a/tools/corosync-notifyd.c b/tools/corosync-notifyd.c
new file mode 100644
index 0000000..93414f6
--- /dev/null
+++ b/tools/corosync-notifyd.c
@@ -0,0 +1,1420 @@
+/*
+ * Copyright (c) 2011-2017 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Author: Angus Salkeld <asalkeld@redhat.com>
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of the MontaVista Software, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include <sys/select.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <sys/types.h>
+#include <netdb.h>
+#include <arpa/inet.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <unistd.h>
+#include <string.h>
+#include <ctype.h>
+#include <poll.h>
+#include <signal.h>
+
+#include <qb/qbdefs.h>
+#include <qb/qbloop.h>
+#include <qb/qbmap.h>
+#include <qb/qblog.h>
+
+#include <corosync/corotypes.h>
+#include <corosync/cfg.h>
+#include <corosync/quorum.h>
+#include <corosync/cmap.h>
+
+#ifdef HAVE_LIBSYSTEMD
+#include <systemd/sd-daemon.h>
+#endif
+
+/*
+ * generic declarations
+ */
+enum {
+ CS_NTF_LOG,
+ CS_NTF_STDOUT,
+ CS_NTF_SNMP,
+ CS_NTF_DBUS,
+ CS_NTF_FG,
+ CS_NTF_NODNS,
+ CS_NTF_MAX,
+};
+static int conf[CS_NTF_MAX];
+
+static int exit_code = 0;
+
+static int32_t _cs_is_quorate = 0;
+
+typedef void (*node_membership_fn_t)(char *nodename, uint32_t nodeid, char *state, char* ip);
+typedef void (*node_quorum_fn_t)(char *nodename, uint32_t nodeid, const char *state);
+typedef void (*application_connection_fn_t)(char *nodename, uint32_t nodeid, char *app_name, const char *state);
+typedef void (*link_faulty_fn_t)(char *nodename, uint32_t local_nodeid, uint32_t nodeid, uint32_t iface_no, const char *state);
+
+struct notify_callbacks {
+ node_membership_fn_t node_membership_fn;
+ node_quorum_fn_t node_quorum_fn;
+ application_connection_fn_t application_connection_fn;
+ link_faulty_fn_t link_faulty_fn;
+};
+
+struct track_item {
+ char key_name[CMAP_KEYNAME_MAXLEN + 1];
+ cmap_track_handle_t track_handle;
+};
+
+#define MAX_NOTIFIERS 5
+static int num_notifiers = 0;
+static struct notify_callbacks notifiers[MAX_NOTIFIERS];
+/*
+ * Global variable with local nodeid
+ */
+static uint32_t g_local_nodeid = 0;
+static char local_nodename[CS_MAX_NAME_LENGTH];
+static qb_loop_t *main_loop;
+static quorum_handle_t quorum_handle;
+static qb_map_t *tracker_map;
+
+static void _cs_node_membership_event(char *nodename, uint32_t nodeid, char *state, char* ip);
+static void _cs_node_quorum_event(const char *state);
+static void _cs_application_connection_event(char *app_name, const char *state);
+static void _cs_link_faulty_event(uint32_t nodeid, uint32_t iface_no, const char *state);
+
+#ifdef HAVE_DBUS
+#include <dbus/dbus.h>
+/*
+ * dbus
+ */
+#define DBUS_CS_NAME "org.corosync"
+#define DBUS_CS_IFACE "org.corosync"
+#define DBUS_CS_PATH "/org/corosync"
+
+static DBusConnection *db = NULL;
+static char _err[512];
+static int err_set = 0;
+static void _cs_dbus_init(void);
+#endif /* HAVE_DBUS */
+
+#ifdef ENABLE_SNMP
+#include <net-snmp/net-snmp-config.h>
+#include <net-snmp/snmpv3_api.h>
+#include <net-snmp/agent/agent_trap.h>
+#include <net-snmp/library/mib.h>
+#include <net-snmp/library/snmp_api.h>
+#include <net-snmp/library/snmp_client.h>
+#include <net-snmp/library/snmp_debug.h>
+
+enum snmp_node_status {
+ SNMP_NODE_STATUS_UNKNOWN = 0,
+ SNMP_NODE_STATUS_JOINED = 1,
+ SNMP_NODE_STATUS_LEFT = 2
+};
+
+#define SNMP_OID_COROSYNC "1.3.6.1.4.1.35488"
+#define SNMP_OID_OBJECT_ROOT SNMP_OID_COROSYNC ".1"
+#define SNMP_OID_OBJECT_NODE_NAME SNMP_OID_OBJECT_ROOT ".1"
+#define SNMP_OID_OBJECT_NODE_ID SNMP_OID_OBJECT_ROOT ".2"
+#define SNMP_OID_OBJECT_NODE_STATUS SNMP_OID_OBJECT_ROOT ".3"
+#define SNMP_OID_OBJECT_NODE_ADDR SNMP_OID_OBJECT_ROOT ".4"
+#define SNMP_OID_OBJECT_LOCAL_NODE_ID SNMP_OID_OBJECT_ROOT ".5"
+
+#define SNMP_OID_OBJECT_RINGSEQ SNMP_OID_OBJECT_ROOT ".20"
+#define SNMP_OID_OBJECT_QUORUM SNMP_OID_OBJECT_ROOT ".21"
+
+#define SNMP_OID_OBJECT_APP_NAME SNMP_OID_OBJECT_ROOT ".40"
+#define SNMP_OID_OBJECT_APP_STATUS SNMP_OID_OBJECT_ROOT ".41"
+
+#define SNMP_OID_OBJECT_LINK_IFACE_NO SNMP_OID_OBJECT_ROOT ".60"
+#define SNMP_OID_OBJECT_LINK_STATUS SNMP_OID_OBJECT_ROOT ".61"
+
+#define SNMP_OID_TRAPS_ROOT SNMP_OID_COROSYNC ".0"
+#define SNMP_OID_TRAPS_NODE SNMP_OID_TRAPS_ROOT ".1"
+#define SNMP_OID_TRAPS_QUORUM SNMP_OID_TRAPS_ROOT ".2"
+#define SNMP_OID_TRAPS_APP SNMP_OID_TRAPS_ROOT ".3"
+#define SNMP_OID_TRAPS_LINK SNMP_OID_TRAPS_ROOT ".4"
+
+#define CS_TIMESTAMP_STR_LEN 20
+static const char *local_host = "localhost";
+#endif /* ENABLE_SNMP */
+static char snmp_manager_buf[CS_MAX_NAME_LENGTH];
+static char *snmp_manager = NULL;
+static char snmp_community_buf[CS_MAX_NAME_LENGTH];
+static char *snmp_community = NULL;
+
+#define CMAP_MAX_RETRIES 10
+
+/*
+ * cmap
+ */
+static cmap_handle_t cmap_handle;
+static cmap_handle_t stats_handle;
+static cmap_track_handle_t cmap_track_handle_runtime_members_key_changed;
+static cmap_track_handle_t cmap_track_handle_stats_ipcs_key_changed;
+static cmap_track_handle_t cmap_track_handle_stats_knet_key_changed;
+
+static int32_t _cs_ip_to_hostname(char* ip, char* name_out)
+{
+ struct sockaddr_in sa;
+ int rc;
+
+ if (strchr(ip, ':') == NULL) {
+ sa.sin_family = AF_INET;
+ } else {
+ sa.sin_family = AF_INET6;
+ }
+
+ rc = inet_pton(sa.sin_family, ip, &sa.sin_addr);
+ if (rc == 0) {
+ return -EINVAL;
+ }
+
+ rc = getnameinfo((struct sockaddr*)&sa, sizeof(sa),
+ name_out, CS_MAX_NAME_LENGTH, NULL, 0, 0);
+ if (rc != 0) {
+ qb_log(LOG_ERR, "error looking up %s : %s", ip, gai_strerror(rc));
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static void _cs_cmap_members_key_changed (
+ cmap_handle_t cmap_handle_c,
+ cmap_track_handle_t cmap_track_handle,
+ int32_t event,
+ const char *key_name,
+ struct cmap_notify_value new_value,
+ struct cmap_notify_value old_value,
+ void *user_data)
+{
+ char nodename[CS_MAX_NAME_LENGTH];
+ char* open_bracket = NULL;
+ char* close_bracket = NULL;
+ int res;
+ uint32_t nodeid;
+ char *ip_str;
+ char tmp_key[CMAP_KEYNAME_MAXLEN];
+ cs_error_t err;
+ int no_retries;
+
+ if (event != CMAP_TRACK_ADD && event != CMAP_TRACK_MODIFY) {
+ return ;
+ }
+
+ if (NULL == key_name) {
+ qb_log(LOG_ERR, "key_name: nil");
+ return ;
+ }
+
+ res = sscanf(key_name, "runtime.members.%u.%s", &nodeid, tmp_key);
+ if (res != 2)
+ return ;
+
+ if (strcmp(tmp_key, "status") != 0) {
+ return ;
+ }
+
+ res = snprintf(tmp_key, CMAP_KEYNAME_MAXLEN, "runtime.members.%u.ip", nodeid);
+ if (res <= 0 || res >= CMAP_KEYNAME_MAXLEN) {
+ qb_log(LOG_ERR, "temp_key: failed, res: %d, nodeid: " CS_PRI_NODE_ID, res, nodeid);
+ return ;
+ }
+ no_retries = 0;
+ while ((err = cmap_get_string(cmap_handle, tmp_key, &ip_str)) == CS_ERR_TRY_AGAIN &&
+ no_retries++ < CMAP_MAX_RETRIES) {
+ sleep(1);
+ }
+
+ if (err != CS_OK) {
+ return ;
+ }
+ /*
+ * We want the ip out of: "r(0) ip(192.168.100.92)"
+ */
+ open_bracket = strrchr(ip_str, '(');
+ if (NULL == open_bracket) {
+ qb_log(LOG_ERR, "ip_str: %s", ip_str);
+ free(ip_str);
+ return ;
+ }
+ open_bracket++;
+ close_bracket = strchr(open_bracket, ')');
+ if (NULL == close_bracket) {
+ qb_log(LOG_ERR, "open_bracket: %s", open_bracket);
+ free(ip_str);
+ return ;
+ }
+ *close_bracket = '\0';
+ if(conf[CS_NTF_NODNS]) {
+ strncpy(nodename, open_bracket, CS_MAX_NAME_LENGTH-1);
+ } else {
+ res = _cs_ip_to_hostname(open_bracket, nodename);
+ if (res) {
+ strncpy(nodename, open_bracket, CS_MAX_NAME_LENGTH-1);
+ }
+ }
+ _cs_node_membership_event(nodename, nodeid, (char *)new_value.data, open_bracket);
+ free(ip_str);
+}
+
+static void _cs_cmap_connections_key_changed (
+ cmap_handle_t cmap_handle_c,
+ cmap_track_handle_t cmap_track_handle,
+ int32_t event,
+ const char *key_name,
+ struct cmap_notify_value new_value,
+ struct cmap_notify_value old_value,
+ void *user_data)
+{
+ char obj_name[CS_MAX_NAME_LENGTH];
+ char conn_str[CMAP_KEYNAME_MAXLEN];
+ char tmp_key[CMAP_KEYNAME_MAXLEN];
+ int service, pid;
+ int res;
+
+ res = sscanf(key_name, "stats.ipcs.service%d.%d.%[^.].%s", &service,&pid, conn_str, tmp_key);
+ if (res != 4) {
+ return ;
+ }
+
+ if (strcmp(tmp_key, "procname") != 0) {
+ return ;
+ }
+
+ if (snprintf(obj_name, CS_MAX_NAME_LENGTH, "%s.%d.%s", conn_str, pid,
+ (char*)new_value.data) >= CS_MAX_NAME_LENGTH) {
+ /*
+ * This should never happen
+ */
+ qb_log(LOG_ERR, "Can't snprintf obj_name");
+ return ;
+ }
+
+ if (event == CMAP_TRACK_ADD) {
+ _cs_application_connection_event(obj_name, "connected");
+ }
+
+ if (event == CMAP_TRACK_DELETE) {
+ _cs_application_connection_event(obj_name, "disconnected");
+ }
+}
+
+static void _cs_cmap_link_faulty_key_changed (
+ cmap_handle_t cmap_handle_c,
+ cmap_track_handle_t cmap_track_handle,
+ int32_t event,
+ const char *key_name,
+ struct cmap_notify_value new_value,
+ struct cmap_notify_value old_value,
+ void *user_data)
+{
+ uint32_t iface_no;
+ uint32_t nodeid;
+ int res;
+ int no_retries;
+ uint8_t connected;
+ cs_error_t err;
+
+ res = sscanf(key_name, "stats.knet.node%u.link%u.connected", &nodeid, &iface_no);
+ if (res != 2) {
+ return ;
+ }
+
+ no_retries = 0;
+ while ((err = cmap_get_uint8(stats_handle, key_name, &connected)) == CS_ERR_TRY_AGAIN &&
+ no_retries++ < CMAP_MAX_RETRIES) {
+ sleep(1);
+ }
+
+ if (err != CS_OK) {
+ return ;
+ }
+
+ if (connected) {
+ _cs_link_faulty_event(nodeid, iface_no, "operational");
+ } else {
+ _cs_link_faulty_event(nodeid, iface_no, "disconnected");
+ }
+}
+
+static void _cs_cmap_link_added_removed (
+ cmap_handle_t cmap_handle_c,
+ cmap_track_handle_t track_handle,
+ int32_t event,
+ const char *key_name,
+ struct cmap_notify_value new_value,
+ struct cmap_notify_value old_value,
+ void *user_data)
+{
+ struct track_item *track_item;
+ cs_error_t err;
+
+ /* Add/remove a tracker for a new/removed knet link */
+ if (strstr(key_name, ".connected")) {
+ if (event == CMAP_TRACK_ADD) {
+ assert(strlen(key_name) < sizeof(track_item->key_name));
+
+ track_item = malloc(sizeof(struct track_item));
+ if (!track_item) {
+ qb_log(LOG_WARNING, "Can't alloc track_item for new/removed knet link");
+ return;
+ }
+ err = cmap_track_add(stats_handle, key_name, CMAP_TRACK_MODIFY,
+ _cs_cmap_link_faulty_key_changed, NULL, &track_handle);
+ if (err != CS_OK) {
+ qb_log(LOG_WARNING, "Can't add tracker for new/removed knet link");
+
+ free(track_item);
+ return ;
+ }
+
+ strcpy(track_item->key_name, key_name);
+
+ track_item->track_handle = track_handle;
+ qb_map_put(tracker_map, track_item->key_name, track_item);
+ } else {
+ track_item = qb_map_get(tracker_map, key_name);
+ if (track_item) {
+ cmap_track_delete(stats_handle, track_item->track_handle);
+ qb_map_rm(tracker_map, track_item->key_name);
+ free(track_item);
+ }
+ }
+ }
+}
+
+
+static int
+_cs_cmap_dispatch(int fd, int revents, void *data)
+{
+ cs_error_t err;
+
+ err = cmap_dispatch(*(cmap_handle_t *)data, CS_DISPATCH_ONE);
+
+ if (err != CS_OK && err != CS_ERR_TRY_AGAIN && err != CS_ERR_TIMEOUT &&
+ err != CS_ERR_QUEUE_FULL) {
+ qb_log(LOG_ERR, "Could not dispatch cmap events. Error %u", err);
+ qb_loop_stop(main_loop);
+
+ exit_code = 1;
+
+ return -1;
+ }
+
+ return 0;
+}
+
+static void _cs_quorum_notification(quorum_handle_t handle,
+ uint32_t quorate, uint64_t ring_seq,
+ uint32_t view_list_entries, uint32_t *view_list)
+{
+ if (_cs_is_quorate == quorate) {
+ return;
+ }
+ _cs_is_quorate = quorate;
+
+ if (quorate) {
+ _cs_node_quorum_event("quorate");
+ } else {
+ _cs_node_quorum_event("not quorate");
+ }
+}
+
+static int
+_cs_quorum_dispatch(int fd, int revents, void *data)
+{
+ cs_error_t err;
+
+ err = quorum_dispatch(quorum_handle, CS_DISPATCH_ONE);
+ if (err != CS_OK && err != CS_ERR_TRY_AGAIN && err != CS_ERR_TIMEOUT &&
+ err != CS_ERR_QUEUE_FULL) {
+ qb_log(LOG_ERR, "Could not dispatch quorum events. Error %u", err);
+ qb_loop_stop(main_loop);
+
+ exit_code = 1;
+
+ return -1;
+ }
+ return 0;
+}
+
+static void
+_cs_quorum_init(void)
+{
+ cs_error_t rc;
+ uint32_t quorum_type;
+ int fd;
+
+ quorum_callbacks_t quorum_callbacks = {
+ .quorum_notify_fn = _cs_quorum_notification,
+ };
+
+ rc = quorum_initialize (&quorum_handle, &quorum_callbacks,
+ &quorum_type);
+ if (rc != CS_OK) {
+ qb_log(LOG_ERR, "Could not connect to corosync(quorum)");
+ return;
+ }
+ quorum_fd_get(quorum_handle, &fd);
+ qb_loop_poll_add(main_loop, QB_LOOP_MED, fd, POLLIN|POLLNVAL, NULL,
+ _cs_quorum_dispatch);
+ rc = quorum_trackstart(quorum_handle, CS_TRACK_CHANGES);
+ if (rc != CS_OK) {
+ qb_log(LOG_ERR, "Could not start tracking");
+ return;
+ }
+}
+
+static void
+_cs_quorum_finalize(void)
+{
+ quorum_finalize (quorum_handle);
+}
+
+
+#ifdef HAVE_DBUS
+/*
+ * dbus notifications
+ */
+static void
+_cs_dbus_auto_flush(void)
+{
+ dbus_connection_ref(db);
+ while (dbus_connection_get_dispatch_status(db) == DBUS_DISPATCH_DATA_REMAINS) {
+ dbus_connection_dispatch(db);
+ }
+
+ while (dbus_connection_has_messages_to_send(db)) {
+ dbus_connection_flush(db);
+ }
+
+ dbus_connection_unref(db);
+}
+
+static void
+_cs_dbus_release(void)
+{
+ DBusError err;
+
+ if (!db)
+ return;
+
+ dbus_error_init(&err);
+ dbus_bus_release_name(db, DBUS_CS_NAME, &err);
+ dbus_error_free(&err);
+ dbus_connection_unref(db);
+ db = NULL;
+}
+
+static void
+_cs_dbus_node_quorum_event(char *nodename, uint32_t nodeid, const char *state)
+{
+ DBusMessage *msg = NULL;
+
+ if (err_set) {
+ qb_log(LOG_ERR, "%s", _err);
+ err_set = 0;
+ }
+
+ if (!db) {
+ goto out_free;
+ }
+
+ if (dbus_connection_get_is_connected(db) != TRUE) {
+ err_set = 1;
+ snprintf(_err, sizeof(_err), "DBus connection lost");
+ _cs_dbus_release();
+ goto out_unlock;
+ }
+
+ _cs_dbus_auto_flush();
+
+ if (!(msg = dbus_message_new_signal(DBUS_CS_PATH,
+ DBUS_CS_IFACE,
+ "QuorumStateChange"))) {
+ qb_log(LOG_ERR, "error creating dbus signal");
+ goto out_unlock;
+ }
+
+ if (!dbus_message_append_args(msg,
+ DBUS_TYPE_STRING, &nodename,
+ DBUS_TYPE_UINT32, &nodeid,
+ DBUS_TYPE_STRING, &state,
+ DBUS_TYPE_INVALID)) {
+ qb_log(LOG_ERR, "error adding args to quorum signal");
+ goto out_unlock;
+ }
+
+ dbus_connection_send(db, msg, NULL);
+
+out_unlock:
+ if (msg) {
+ dbus_message_unref(msg);
+ }
+out_free:
+ return;
+}
+
+static void
+_cs_dbus_node_membership_event(char *nodename, uint32_t nodeid, char *state, char* ip)
+{
+ DBusMessage *msg = NULL;
+
+ if (err_set) {
+ qb_log(LOG_ERR, "%s", _err);
+ err_set = 0;
+ }
+
+ if (!db) {
+ goto out_free;
+ }
+
+ if (dbus_connection_get_is_connected(db) != TRUE) {
+ err_set = 1;
+ snprintf(_err, sizeof(_err), "DBus connection lost");
+ _cs_dbus_release();
+ goto out_unlock;
+ }
+
+ _cs_dbus_auto_flush();
+
+ if (!(msg = dbus_message_new_signal(DBUS_CS_PATH,
+ DBUS_CS_IFACE,
+ "NodeStateChange"))) {
+ qb_log(LOG_ERR, "error creating NodeStateChange signal");
+ goto out_unlock;
+ }
+
+ if (!dbus_message_append_args(msg,
+ DBUS_TYPE_STRING, &nodename,
+ DBUS_TYPE_UINT32, &nodeid,
+ DBUS_TYPE_STRING, &ip,
+ DBUS_TYPE_STRING, &state,
+ DBUS_TYPE_INVALID)) {
+ qb_log(LOG_ERR, "error adding args to NodeStateChange signal");
+ goto out_unlock;
+ }
+
+ dbus_connection_send(db, msg, NULL);
+
+out_unlock:
+ if (msg) {
+ dbus_message_unref(msg);
+ }
+out_free:
+ return;
+}
+
+static void
+_cs_dbus_application_connection_event(char *nodename, uint32_t nodeid, char *app_name, const char *state)
+{
+ DBusMessage *msg = NULL;
+
+ if (err_set) {
+ qb_log(LOG_ERR, "%s", _err);
+ err_set = 0;
+ }
+
+ if (!db) {
+ goto out_free;
+ }
+
+ if (dbus_connection_get_is_connected(db) != TRUE) {
+ err_set = 1;
+ snprintf(_err, sizeof(_err), "DBus connection lost");
+ _cs_dbus_release();
+ goto out_unlock;
+ }
+
+ _cs_dbus_auto_flush();
+
+ if (!(msg = dbus_message_new_signal(DBUS_CS_PATH,
+ DBUS_CS_IFACE,
+ "ConnectionStateChange"))) {
+ qb_log(LOG_ERR, "error creating ConnectionStateChange signal");
+ goto out_unlock;
+ }
+
+ if (!dbus_message_append_args(msg,
+ DBUS_TYPE_STRING, &nodename,
+ DBUS_TYPE_UINT32, &nodeid,
+ DBUS_TYPE_STRING, &app_name,
+ DBUS_TYPE_STRING, &state,
+ DBUS_TYPE_INVALID)) {
+ qb_log(LOG_ERR, "error adding args to ConnectionStateChange signal");
+ goto out_unlock;
+ }
+
+ dbus_connection_send(db, msg, NULL);
+
+out_unlock:
+ if (msg) {
+ dbus_message_unref(msg);
+ }
+out_free:
+ return;
+}
+
+static void
+_cs_dbus_link_faulty_event(char *nodename, uint32_t local_nodeid, uint32_t nodeid, uint32_t iface_no, const char *state)
+{
+ DBusMessage *msg = NULL;
+
+ if (err_set) {
+ qb_log(LOG_ERR, "%s", _err);
+ err_set = 0;
+ }
+
+ if (!db) {
+ goto out_free;
+ }
+
+ if (dbus_connection_get_is_connected(db) != TRUE) {
+ err_set = 1;
+ snprintf(_err, sizeof(_err), "DBus connection lost");
+ _cs_dbus_release();
+ goto out_unlock;
+ }
+
+ _cs_dbus_auto_flush();
+
+ if (!(msg = dbus_message_new_signal(DBUS_CS_PATH,
+ DBUS_CS_IFACE,
+ "QuorumStateChange"))) {
+ qb_log(LOG_ERR, "error creating dbus signal");
+ goto out_unlock;
+ }
+
+ if (!dbus_message_append_args(msg,
+ DBUS_TYPE_STRING, &nodename,
+ DBUS_TYPE_UINT32, &local_nodeid,
+ DBUS_TYPE_UINT32, &nodeid,
+ DBUS_TYPE_UINT32, &iface_no,
+ DBUS_TYPE_STRING, &state,
+ DBUS_TYPE_INVALID)) {
+ qb_log(LOG_ERR, "error adding args to link signal");
+ goto out_unlock;
+ }
+
+ dbus_connection_send(db, msg, NULL);
+
+out_unlock:
+ if (msg) {
+ dbus_message_unref(msg);
+ }
+out_free:
+ return;
+}
+
+static void
+_cs_dbus_init(void)
+{
+ DBusConnection *dbc = NULL;
+ DBusError err;
+
+ dbus_error_init(&err);
+
+ dbc = dbus_bus_get(DBUS_BUS_SYSTEM, &err);
+ if (!dbc) {
+ snprintf(_err, sizeof(_err),
+ "dbus_bus_get: %s", err.message);
+ err_set = 1;
+ dbus_error_free(&err);
+ return;
+ }
+
+ dbus_connection_set_exit_on_disconnect(dbc, FALSE);
+
+ db = dbc;
+
+ notifiers[num_notifiers].node_membership_fn =
+ _cs_dbus_node_membership_event;
+ notifiers[num_notifiers].node_quorum_fn =
+ _cs_dbus_node_quorum_event;
+ notifiers[num_notifiers].application_connection_fn =
+ _cs_dbus_application_connection_event;
+ notifiers[num_notifiers].link_faulty_fn =
+ _cs_dbus_link_faulty_event;
+
+ num_notifiers++;
+}
+
+#endif /* HAVE_DBUS */
+
+#ifdef ENABLE_SNMP
+static netsnmp_session *_cs_snmp_session_init (const char *target)
+{
+ static netsnmp_session *session = NULL;
+#ifndef NETSNMPV54
+ char default_port[128];
+ snprintf (default_port, sizeof (default_port), "%s:162", target);
+#endif
+ if (session) {
+ return (session);
+ }
+
+ if (target == NULL) {
+ return NULL;
+ }
+
+ session = malloc (sizeof (netsnmp_session));
+ snmp_sess_init (session);
+ session->version = SNMP_VERSION_2c;
+ session->callback = NULL;
+ session->callback_magic = NULL;
+
+ if (snmp_community) {
+ session->community = (u_char *)snmp_community;
+ session->community_len = strlen(snmp_community_buf);
+ }
+
+ session = snmp_add(session,
+#ifdef NETSNMPV54
+ netsnmp_transport_open_client ("snmptrap", target),
+#else
+ netsnmp_tdomain_transport (default_port, 0, "udp"),
+#endif
+ NULL, NULL);
+
+ if (session == NULL) {
+ qb_log(LOG_ERR, 0, "Could not create snmp transport");
+ }
+ return (session);
+}
+
+static void _cs_snmp_add_field (
+ netsnmp_pdu *trap_pdu,
+ u_char asn_type,
+ const char *prefix,
+ void *value,
+ size_t value_size)
+{
+ oid _oid[MAX_OID_LEN];
+ size_t _oid_len = MAX_OID_LEN;
+ if (snmp_parse_oid(prefix, _oid, &_oid_len)) {
+ snmp_pdu_add_variable (trap_pdu, _oid, _oid_len, asn_type, (u_char *) value, value_size);
+ }
+}
+
+static netsnmp_pdu *_cs_snmp_trap_pdu_init (const char *trap_oid)
+{
+ static oid snmptrap_oid[] = { 1,3,6,1,6,3,1,1,4,1,0 };
+ static oid sysuptime_oid[] = { 1,3,6,1,2,1,1,3,0 };
+ char csysuptime[CS_TIMESTAMP_STR_LEN];
+ time_t now;
+ struct tm *now_tm;
+ netsnmp_pdu *trap_pdu;
+
+ now = time (NULL);
+ if (now == ((time_t)-1)) {
+ qb_log(LOG_NOTICE, "Failed to get timestamp.");
+ return (NULL);
+ }
+
+ /* format uptime */
+ now_tm = localtime(&now);
+ if (now_tm == NULL || strftime (csysuptime, sizeof(csysuptime), "%s", now_tm) == 0) {
+ qb_log(LOG_NOTICE, "Failed to format timestamp.");
+ return (NULL);
+ }
+
+ trap_pdu = snmp_pdu_create (SNMP_MSG_TRAP2);
+ if (!trap_pdu) {
+ qb_log(LOG_NOTICE, "Failed to create SNMP notification.");
+ return (NULL);
+ }
+
+ /* send uptime */
+ snmp_add_var (trap_pdu, sysuptime_oid, sizeof (sysuptime_oid) / sizeof (oid), 't', csysuptime);
+ snmp_add_var (trap_pdu, snmptrap_oid, sizeof (snmptrap_oid) / sizeof (oid), 'o', trap_oid);
+
+ return (trap_pdu);
+}
+
+static void
+_cs_snmp_node_membership_event(char *nodename, uint32_t nodeid, char *state, char* ip)
+{
+ int ret;
+ netsnmp_pdu *trap_pdu;
+ netsnmp_session *session = _cs_snmp_session_init (snmp_manager);
+
+ if (session == NULL) {
+ qb_log(LOG_NOTICE, "Failed to init SNMP session.");
+ return ;
+ }
+
+ trap_pdu = _cs_snmp_trap_pdu_init(SNMP_OID_TRAPS_NODE);
+ if (trap_pdu == NULL) {
+ return ;
+ }
+
+ /* Add extries to the trap */
+ _cs_snmp_add_field (trap_pdu, ASN_OCTET_STR, SNMP_OID_OBJECT_NODE_NAME, (void*)nodename, strlen (nodename));
+ _cs_snmp_add_field (trap_pdu, ASN_UNSIGNED, SNMP_OID_OBJECT_NODE_ID, (void*)&nodeid, sizeof (nodeid));
+ _cs_snmp_add_field (trap_pdu, ASN_OCTET_STR, SNMP_OID_OBJECT_NODE_ADDR, (void*)ip, strlen (ip));
+ _cs_snmp_add_field (trap_pdu, ASN_OCTET_STR, SNMP_OID_OBJECT_NODE_STATUS, (void*)state, strlen (state));
+
+ /* Send and cleanup */
+ ret = snmp_send (session, trap_pdu);
+ if (ret == 0) {
+ /* error */
+ qb_log(LOG_ERR, "Could not send SNMP trap");
+ snmp_free_pdu (trap_pdu);
+ }
+}
+
+static void
+_cs_snmp_node_quorum_event(char *nodename, uint32_t nodeid,
+ const char *state)
+{
+ int ret;
+ netsnmp_pdu *trap_pdu;
+ netsnmp_session *session = _cs_snmp_session_init (snmp_manager);
+
+ if (session == NULL) {
+ qb_log(LOG_NOTICE, "Failed to init SNMP session.");
+ return ;
+ }
+
+ trap_pdu = _cs_snmp_trap_pdu_init(SNMP_OID_TRAPS_QUORUM);
+ if (trap_pdu == NULL) {
+ return ;
+ }
+
+ /* Add extries to the trap */
+ _cs_snmp_add_field (trap_pdu, ASN_OCTET_STR, SNMP_OID_OBJECT_NODE_NAME, (void*)nodename, strlen (nodename));
+ _cs_snmp_add_field (trap_pdu, ASN_UNSIGNED, SNMP_OID_OBJECT_NODE_ID, (void*)&nodeid, sizeof (nodeid));
+ _cs_snmp_add_field (trap_pdu, ASN_OCTET_STR, SNMP_OID_OBJECT_QUORUM, (void*)state, strlen (state));
+
+ /* Send and cleanup */
+ ret = snmp_send (session, trap_pdu);
+ if (ret == 0) {
+ /* error */
+ qb_log(LOG_ERR, "Could not send SNMP trap");
+ snmp_free_pdu (trap_pdu);
+ }
+}
+
+static void
+_cs_snmp_link_faulty_event(char *nodename, uint32_t local_nodeid, uint32_t nodeid,
+ uint32_t iface_no, const char *state)
+{
+ int ret;
+ netsnmp_pdu *trap_pdu;
+ netsnmp_session *session = _cs_snmp_session_init (snmp_manager);
+
+ if (session == NULL) {
+ qb_log(LOG_NOTICE, "Failed to init SNMP session.");
+ return ;
+ }
+
+ trap_pdu = _cs_snmp_trap_pdu_init(SNMP_OID_TRAPS_LINK);
+ if (trap_pdu == NULL) {
+ return ;
+ }
+
+ /* Add extries to the trap */
+ _cs_snmp_add_field (trap_pdu, ASN_OCTET_STR, SNMP_OID_OBJECT_NODE_NAME, (void*)nodename, strlen (nodename));
+ _cs_snmp_add_field (trap_pdu, ASN_UNSIGNED, SNMP_OID_OBJECT_LOCAL_NODE_ID, (void*)&local_nodeid, sizeof (local_nodeid));
+ _cs_snmp_add_field (trap_pdu, ASN_UNSIGNED, SNMP_OID_OBJECT_NODE_ID, (void*)&nodeid, sizeof (nodeid));
+ _cs_snmp_add_field (trap_pdu, ASN_INTEGER, SNMP_OID_OBJECT_LINK_IFACE_NO, (void*)&iface_no, sizeof (iface_no));
+ _cs_snmp_add_field (trap_pdu, ASN_OCTET_STR, SNMP_OID_OBJECT_LINK_STATUS, (void*)state, strlen (state));
+
+ /* Send and cleanup */
+ ret = snmp_send (session, trap_pdu);
+ if (ret == 0) {
+ /* error */
+ qb_log(LOG_ERR, "Could not send SNMP trap");
+ snmp_free_pdu (trap_pdu);
+ }
+}
+
+static void
+_cs_snmp_init(void)
+{
+ if (snmp_manager == NULL) {
+ snmp_manager = (char*)local_host;
+ }
+
+ notifiers[num_notifiers].node_membership_fn =
+ _cs_snmp_node_membership_event;
+ notifiers[num_notifiers].node_quorum_fn =
+ _cs_snmp_node_quorum_event;
+ notifiers[num_notifiers].application_connection_fn = NULL;
+ notifiers[num_notifiers].link_faulty_fn =
+ _cs_snmp_link_faulty_event;
+ num_notifiers++;
+}
+
+#endif /* ENABLE_SNMP */
+
+static void
+_cs_syslog_node_membership_event(char *nodename, uint32_t nodeid, char *state, char* ip)
+{
+ qb_log(LOG_NOTICE, "%s[" CS_PRI_NODE_ID "] ip:%s %s", nodename, nodeid, ip, state);
+}
+
+static void
+_cs_syslog_node_quorum_event(char *nodename, uint32_t nodeid, const char *state)
+{
+ if (strcmp(state, "quorate") == 0) {
+ qb_log(LOG_NOTICE, "%s[" CS_PRI_NODE_ID "] is now %s", nodename, nodeid, state);
+ } else {
+ qb_log(LOG_NOTICE, "%s[" CS_PRI_NODE_ID "] has lost quorum", nodename, nodeid);
+ }
+}
+
+static void
+_cs_syslog_application_connection_event(char *nodename, uint32_t nodeid, char* app_name, const char *state)
+{
+ if (strcmp(state, "connected") == 0) {
+ qb_log(LOG_NOTICE, "%s[" CS_PRI_NODE_ID "] %s is now %s to corosync", nodename, nodeid, app_name, state);
+ } else {
+ qb_log(LOG_NOTICE, "%s[" CS_PRI_NODE_ID "] %s is now %s from corosync", nodename, nodeid, app_name, state);
+ }
+}
+
+static void
+_cs_syslog_link_faulty_event(char *nodename, uint32_t our_nodeid, uint32_t nodeid, uint32_t iface_no, const char *state)
+{
+ qb_log(LOG_NOTICE, "%s[" CS_PRI_NODE_ID "] link %u to node " CS_PRI_NODE_ID " is now %s", nodename, our_nodeid, iface_no, nodeid, state);
+}
+
+static void
+_cs_node_membership_event(char *nodename, uint32_t nodeid, char *state, char* ip)
+{
+ int i;
+
+ for (i = 0; i < num_notifiers; i++) {
+ if (notifiers[i].node_membership_fn) {
+ notifiers[i].node_membership_fn(nodename, nodeid, state, ip);
+ }
+ }
+}
+
+static void
+_cs_local_node_info_get(char **nodename, uint32_t *nodeid)
+{
+ cs_error_t rc;
+ corosync_cfg_handle_t cfg_handle;
+
+ if (g_local_nodeid == 0) {
+ rc = corosync_cfg_initialize(&cfg_handle, NULL);
+ if (rc != CS_OK) {
+ syslog (LOG_ERR, "Failed to initialize the cfg API. Error %d\n", rc);
+ exit (EXIT_FAILURE);
+ }
+
+ rc = corosync_cfg_local_get (cfg_handle, &g_local_nodeid);
+ corosync_cfg_finalize(cfg_handle);
+ if (rc != CS_OK) {
+ g_local_nodeid = 0;
+ strncpy(local_nodename, "localhost", sizeof (local_nodename));
+ local_nodename[sizeof (local_nodename) - 1] = '\0';
+ } else {
+ gethostname(local_nodename, CS_MAX_NAME_LENGTH);
+ }
+ }
+ *nodeid = g_local_nodeid;
+ *nodename = local_nodename;
+}
+
+static void
+_cs_node_quorum_event(const char *state)
+{
+ int i;
+ char *nodename;
+ uint32_t nodeid;
+
+ _cs_local_node_info_get(&nodename, &nodeid);
+
+ for (i = 0; i < num_notifiers; i++) {
+ if (notifiers[i].node_quorum_fn) {
+ notifiers[i].node_quorum_fn(nodename, nodeid, state);
+ }
+ }
+}
+
+static void
+_cs_application_connection_event(char *app_name, const char *state)
+{
+ int i;
+ char *nodename;
+ uint32_t nodeid;
+
+ _cs_local_node_info_get(&nodename, &nodeid);
+
+ for (i = 0; i < num_notifiers; i++) {
+ if (notifiers[i].application_connection_fn) {
+ notifiers[i].application_connection_fn(nodename, nodeid, app_name, state);
+ }
+ }
+}
+
+static void
+_cs_link_faulty_event(uint32_t nodeid, uint32_t iface_no, const char *state)
+{
+ int i;
+ char *nodename;
+ uint32_t our_nodeid;
+
+ _cs_local_node_info_get(&nodename, &our_nodeid);
+
+ for (i = 0; i < num_notifiers; i++) {
+ if (notifiers[i].link_faulty_fn) {
+ notifiers[i].link_faulty_fn(nodename, our_nodeid, nodeid, iface_no, state);
+ }
+ }
+}
+
+static int32_t
+sig_exit_handler(int32_t num, void *data)
+{
+ qb_loop_stop(main_loop);
+ return 0;
+}
+
+static void track_link_updown_events(void)
+{
+ cmap_iter_handle_t iter_handle;
+ cmap_track_handle_t track_handle;
+
+ char key_name[CMAP_KEYNAME_MAXLEN + 1];
+ size_t value_len;
+ cmap_value_types_t type;
+ cs_error_t err;
+ struct track_item *track_item;
+
+ err = cmap_iter_init(stats_handle, "stats.knet.", &iter_handle);
+ if (err != CS_OK) {
+ fprintf (stderr, "Failed to initialize knet stats iterator. Error %s\n", cs_strerror(err));
+ exit (EXIT_FAILURE);
+ }
+
+ while ((err = cmap_iter_next(stats_handle, iter_handle, key_name, &value_len, &type)) == CS_OK) {
+ if (strstr(key_name, ".connected")) {
+
+ track_item = malloc(sizeof(struct track_item));
+ if (!track_item) {
+ return;
+ }
+
+ if ((err = cmap_track_add(stats_handle, key_name, CMAP_TRACK_MODIFY, _cs_cmap_link_faulty_key_changed, NULL, &track_handle)) != CS_OK) {
+ fprintf (stderr, "Failed to add tracker for %s. Error %s\n", key_name, cs_strerror(err));
+ exit (EXIT_FAILURE);
+ }
+ strcpy(track_item->key_name, key_name);
+ track_item->track_handle = track_handle;
+ qb_map_put(tracker_map, track_item->key_name, track_item);
+ }
+ }
+ cmap_iter_finalize(stats_handle, iter_handle);
+}
+
+static void
+_cs_cmap_init(void)
+{
+ cs_error_t rc = CS_OK;
+ int cmap_fd = 0;
+ int stats_fd = 0;
+
+ tracker_map = qb_trie_create();
+ if (!tracker_map) {
+ qb_log(LOG_ERR, "Failed to initialize the track map. Error %d", rc);
+ exit (EXIT_FAILURE);
+ }
+
+ rc = cmap_initialize_map (&cmap_handle, CMAP_MAP_ICMAP);
+ if (rc != CS_OK) {
+ qb_log(LOG_ERR, "Failed to initialize the cmap API. Error %d", rc);
+ exit (EXIT_FAILURE);
+ }
+ cmap_fd_get(cmap_handle, &cmap_fd);
+
+ qb_loop_poll_add(main_loop, QB_LOOP_MED, cmap_fd, POLLIN|POLLNVAL, (void*)&cmap_handle,
+ _cs_cmap_dispatch);
+
+
+ rc = cmap_initialize_map (&stats_handle, CMAP_MAP_STATS);
+ if (rc != CS_OK) {
+ qb_log(LOG_ERR, "Failed to initialize the cmap stats API. Error %d", rc);
+ exit (EXIT_FAILURE);
+ }
+ cmap_fd_get(stats_handle, &stats_fd);
+
+ qb_loop_poll_add(main_loop, QB_LOOP_MED, stats_fd, POLLIN|POLLNVAL, (void*)&stats_handle,
+ _cs_cmap_dispatch);
+
+
+ rc = cmap_track_add(cmap_handle, "runtime.members.",
+ CMAP_TRACK_ADD | CMAP_TRACK_MODIFY | CMAP_TRACK_PREFIX,
+ _cs_cmap_members_key_changed,
+ NULL,
+ &cmap_track_handle_runtime_members_key_changed);
+ if (rc != CS_OK) {
+ qb_log(LOG_ERR,
+ "Failed to track the members key. Error %d", rc);
+ exit (EXIT_FAILURE);
+ }
+
+ rc = cmap_track_add(stats_handle, "stats.ipcs.",
+ CMAP_TRACK_ADD | CMAP_TRACK_DELETE | CMAP_TRACK_PREFIX,
+ _cs_cmap_connections_key_changed,
+ NULL,
+ &cmap_track_handle_stats_ipcs_key_changed);
+ if (rc != CS_OK) {
+ qb_log(LOG_ERR,
+ "Failed to track the connections key. Error %d", rc);
+ exit (EXIT_FAILURE);
+ }
+
+ rc = cmap_track_add(stats_handle, "stats.knet.",
+ CMAP_TRACK_ADD | CMAP_TRACK_DELETE | CMAP_TRACK_PREFIX,
+ _cs_cmap_link_added_removed,
+ NULL,
+ &cmap_track_handle_stats_knet_key_changed);
+ if (rc != CS_OK) {
+ qb_log(LOG_ERR,
+ "Failed to track the knet link status key. Error %d", rc);
+ exit (EXIT_FAILURE);
+ }
+ track_link_updown_events();
+}
+
+static void
+_cs_cmap_finalize(void)
+{
+ struct qb_map_iter *map_iter;
+ struct track_item *track_item;
+
+ map_iter = qb_map_iter_create(tracker_map);
+ while (qb_map_iter_next(map_iter, (void **)&track_item) != NULL) {
+ cmap_track_delete(stats_handle, track_item->track_handle);
+ free(track_item);
+ }
+ qb_map_iter_free(map_iter);
+
+ cmap_track_delete(cmap_handle, cmap_track_handle_runtime_members_key_changed);
+ cmap_track_delete(stats_handle, cmap_track_handle_stats_ipcs_key_changed);
+ cmap_track_delete(stats_handle, cmap_track_handle_stats_knet_key_changed);
+ cmap_finalize (cmap_handle);
+ cmap_finalize (stats_handle);
+}
+
+static void
+_cs_check_config(void)
+{
+ if (conf[CS_NTF_LOG] == QB_FALSE &&
+ conf[CS_NTF_STDOUT] == QB_FALSE &&
+ conf[CS_NTF_SNMP] == QB_FALSE &&
+ conf[CS_NTF_DBUS] == QB_FALSE) {
+ qb_log(LOG_ERR, "no event type enabled, see corosync-notifyd -h, exiting.");
+ exit(EXIT_FAILURE);
+ }
+
+#ifndef ENABLE_SNMP
+ if (conf[CS_NTF_SNMP]) {
+ qb_log(LOG_ERR, "Not compiled with SNMP support enabled, exiting.");
+ exit(EXIT_FAILURE);
+ }
+#endif
+#ifndef HAVE_DBUS
+ if (conf[CS_NTF_DBUS]) {
+ qb_log(LOG_ERR, "Not compiled with DBus support enabled, exiting.");
+ exit(EXIT_FAILURE);
+ }
+#endif
+
+ if (conf[CS_NTF_STDOUT] && !conf[CS_NTF_FG]) {
+ qb_log(LOG_ERR, "configured to print to stdout and run in the background, exiting");
+ exit(EXIT_FAILURE);
+ }
+ if (conf[CS_NTF_SNMP] && conf[CS_NTF_DBUS]) {
+ qb_log(LOG_ERR, "configured to send snmp traps and dbus signals - are you sure?.");
+ }
+}
+
+static void
+_cs_usage(void)
+{
+ fprintf(stderr, "usage:\n"\
+ " -c : SNMP Community name.\n"\
+ " -f : Start application in foreground.\n"\
+ " -l : Log all events.\n"\
+ " -o : Print events to stdout (turns on -l).\n"\
+ " -s : Send SNMP traps on all events.\n"\
+ " -m : Set the SNMP Manager IP address (defaults to localhost).\n"\
+ " -n : No reverse DNS lookup on cmap member change events.\n"\
+ " -d : Send DBUS signals on all events.\n"\
+ " -h : Print this help.\n\n");
+}
+
+int
+main(int argc, char *argv[])
+{
+ int ch;
+
+ conf[CS_NTF_FG] = QB_FALSE;
+ conf[CS_NTF_LOG] = QB_FALSE;
+ conf[CS_NTF_STDOUT] = QB_FALSE;
+ conf[CS_NTF_SNMP] = QB_FALSE;
+ conf[CS_NTF_DBUS] = QB_FALSE;
+
+ while ((ch = getopt (argc, argv, "c:floshdnm:")) != EOF) {
+ switch (ch) {
+ case 'c':
+ strncpy(snmp_community_buf, optarg, sizeof (snmp_community_buf));
+ snmp_community_buf[sizeof (snmp_community_buf) - 1] = '\0';
+ snmp_community = snmp_community_buf;
+ break;
+ case 'f':
+ conf[CS_NTF_FG] = QB_TRUE;
+ break;
+ case 'l':
+ conf[CS_NTF_LOG] = QB_TRUE;
+ break;
+ case 'm':
+ conf[CS_NTF_SNMP] = QB_TRUE;
+ strncpy(snmp_manager_buf, optarg, sizeof (snmp_manager_buf));
+ snmp_manager_buf[sizeof (snmp_manager_buf) - 1] = '\0';
+ snmp_manager = snmp_manager_buf;
+ break;
+ case 'n':
+ conf[CS_NTF_NODNS] = QB_TRUE;
+ break;
+ case 'o':
+ conf[CS_NTF_LOG] = QB_TRUE;
+ conf[CS_NTF_STDOUT] = QB_TRUE;
+ break;
+ case 's':
+ conf[CS_NTF_SNMP] = QB_TRUE;
+ break;
+ case 'd':
+ conf[CS_NTF_DBUS] = QB_TRUE;
+ break;
+ case 'h':
+ default:
+ _cs_usage();
+ return EXIT_FAILURE;
+ }
+ }
+
+ qb_log_init("notifyd", LOG_DAEMON, LOG_INFO);
+
+ if (conf[CS_NTF_STDOUT]) {
+ qb_log_filter_ctl(QB_LOG_STDERR, QB_LOG_FILTER_ADD,
+ QB_LOG_FILTER_FILE, "*", LOG_DEBUG);
+ qb_log_ctl(QB_LOG_STDERR, QB_LOG_CONF_ENABLED, conf[CS_NTF_STDOUT]);
+ }
+ _cs_check_config();
+
+ if (!conf[CS_NTF_FG]) {
+ if (daemon(0, 0) < 0)
+ {
+ perror("daemon() failed");
+ return EXIT_FAILURE;
+ }
+ }
+
+ num_notifiers = 0;
+ if (conf[CS_NTF_LOG]) {
+ notifiers[num_notifiers].node_membership_fn =
+ _cs_syslog_node_membership_event;
+ notifiers[num_notifiers].node_quorum_fn =
+ _cs_syslog_node_quorum_event;
+ notifiers[num_notifiers].application_connection_fn =
+ _cs_syslog_application_connection_event;
+ notifiers[num_notifiers].link_faulty_fn =
+ _cs_syslog_link_faulty_event;
+ num_notifiers++;
+ }
+
+ main_loop = qb_loop_create();
+
+ _cs_cmap_init();
+ _cs_quorum_init();
+
+#ifdef HAVE_DBUS
+ if (conf[CS_NTF_DBUS]) {
+ _cs_dbus_init();
+ }
+#endif /* HAVE_DBUS */
+
+#ifdef ENABLE_SNMP
+ if (conf[CS_NTF_SNMP]) {
+ _cs_snmp_init();
+ }
+#endif /* ENABLE_SNMP */
+
+ qb_loop_signal_add(main_loop,
+ QB_LOOP_HIGH,
+ SIGINT,
+ NULL,
+ sig_exit_handler,
+ NULL);
+ qb_loop_signal_add(main_loop,
+ QB_LOOP_HIGH,
+ SIGQUIT,
+ NULL,
+ sig_exit_handler,
+ NULL);
+ qb_loop_signal_add(main_loop,
+ QB_LOOP_HIGH,
+ SIGTERM,
+ NULL,
+ sig_exit_handler,
+ NULL);
+
+#ifdef HAVE_LIBSYSTEMD
+ sd_notify (0, "READY=1");
+#endif
+
+ qb_loop_run(main_loop);
+
+#ifdef HAVE_DBUS
+ if (conf[CS_NTF_DBUS]) {
+ _cs_dbus_release();
+ }
+#endif /* HAVE_DBUS */
+
+ _cs_quorum_finalize();
+ _cs_cmap_finalize();
+
+ return (exit_code);
+}
+
diff --git a/tools/corosync-notifyd.sysconfig.example b/tools/corosync-notifyd.sysconfig.example
new file mode 100644
index 0000000..908bc8c
--- /dev/null
+++ b/tools/corosync-notifyd.sysconfig.example
@@ -0,0 +1,10 @@
+#
+# See "man corosync-notifyd" for detailed descriptions of
+# the options below.
+#
+# OPTIONS="-d -s -l -m <snmp manager address>"
+#
+
+# Send DBUS signals on all events (for SNMP traps, use -s)
+OPTIONS="-d"
+
diff --git a/tools/corosync-quorumtool.c b/tools/corosync-quorumtool.c
new file mode 100644
index 0000000..199bd20
--- /dev/null
+++ b/tools/corosync-quorumtool.c
@@ -0,0 +1,1023 @@
+/*
+ * Copyright (c) 2009-2020 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Authors: Christine Caulfield <ccaulfie@redhat.com>
+ * Fabio M. Di Nitto (fdinitto@redhat.com)
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of the Red Hat Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <limits.h>
+
+#include <corosync/totem/totem.h>
+#include <corosync/cfg.h>
+#include <corosync/cmap.h>
+#include <corosync/quorum.h>
+#include <corosync/votequorum.h>
+#include "util.h"
+
+typedef enum {
+ NODEID_FORMAT_DECIMAL,
+ NODEID_FORMAT_HEX
+} nodeid_format_t;
+
+typedef enum {
+ ADDRESS_FORMAT_NAME,
+ ADDRESS_FORMAT_IP
+} name_format_t;
+
+typedef enum {
+ CMD_SHOWNODES,
+ CMD_SHOWSTATUS,
+ CMD_SETVOTES,
+ CMD_SETEXPECTED,
+ CMD_MONITOR,
+ CMD_UNREGISTER_QDEVICE
+} command_t;
+
+typedef enum {
+ SORT_ADDR,
+ SORT_NODEID,
+ SORT_NODENAME
+} sorttype_t;
+
+#define EXIT_NOT_QUORATE 2
+
+/*
+ * global vars
+ */
+
+/*
+ * cmap bits
+ */
+static cmap_handle_t cmap_handle;
+
+/*
+ * quorum bits
+ */
+static void quorum_notification_fn(
+ quorum_handle_t handle,
+ uint32_t quorate,
+ uint64_t ring_id,
+ uint32_t view_list_entries,
+ uint32_t *view_list);
+
+static quorum_handle_t q_handle;
+static uint32_t q_type;
+static quorum_callbacks_t q_callbacks = {
+ .quorum_notify_fn = quorum_notification_fn
+};
+
+/*
+ * quorum call back vars
+ */
+
+/* Containing struct to keep votequorum & normal quorum bits together */
+typedef struct {
+ struct votequorum_info *vq_info; /* Might be NULL if votequorum not present */
+ char *name; /* Might be IP address or NULL */
+ int node_id; /* Always present */
+} view_list_entry_t;
+
+static view_list_entry_t *g_view_list;
+static uint32_t g_quorate;
+static uint64_t g_ring_id;
+static uint32_t g_ring_id_rep_node;
+static uint32_t g_view_list_entries;
+static uint32_t g_called;
+static uint32_t g_vq_called;
+static uint32_t g_show_all_addrs = 0;
+
+/*
+ * votequorum bits
+ */
+static void votequorum_notification_fn(
+ votequorum_handle_t handle,
+ uint64_t context,
+ votequorum_ring_id_t ring_id,
+ uint32_t node_list_entries,
+ uint32_t node_list[]);
+static votequorum_handle_t v_handle;
+static votequorum_callbacks_t v_callbacks = {
+ .votequorum_quorum_notify_fn = NULL,
+ .votequorum_expectedvotes_notify_fn = NULL,
+ .votequorum_nodelist_notify_fn = votequorum_notification_fn,
+};
+static uint32_t our_nodeid = 0;
+
+/*
+ * cfg bits
+ */
+static corosync_cfg_handle_t c_handle;
+static corosync_cfg_callbacks_t c_callbacks = {
+ .corosync_cfg_shutdown_callback = NULL
+};
+
+/*
+ * global
+ */
+static int machine_parsable = 0;
+
+static void show_usage(const char *name)
+{
+ printf("usage: \n");
+ printf("%s <options>\n", name);
+ printf("\n");
+ printf(" options:\n");
+ printf("\n");
+ printf(" -s show quorum status\n");
+ printf(" -m constantly monitor quorum status\n");
+ printf(" -l list nodes\n");
+ printf(" -a show all names or addresses for each node\n");
+ printf(" -p when used with -s or -l, generates machine parsable output\n");
+ printf(" -v <votes> change the number of votes for a node (*)\n");
+ printf(" -n <nodeid> optional nodeid of node for -v\n");
+ printf(" -e <expected> change expected votes for the cluster (*)\n");
+ printf(" -H show nodeids in hexadecimal rather than decimal\n");
+ printf(" -i show node IP addresses instead of the resolved name\n");
+ printf(" -o <a|n|i> order by [a] IP address (default), [n] name, [i] nodeid\n");
+ printf(" -f forcefully unregister a quorum device *DANGEROUS* (*)\n");
+ printf(" -h show this help text\n");
+ printf(" -V show version and exit\n");
+ printf("\n");
+ printf(" (*) Starred items only work if votequorum is the quorum provider for corosync\n");
+ printf("\n");
+}
+
+static int get_quorum_type(char *quorum_type, size_t quorum_type_len)
+{
+ int err;
+ char *str = NULL;
+
+ if ((!quorum_type) || (quorum_type_len <= 0)) {
+ return -1;
+ }
+
+ if (q_type == QUORUM_FREE) {
+ return -1;
+ }
+
+ if ((err = cmap_get_string(cmap_handle, "quorum.provider", &str)) != CS_OK) {
+ goto out;
+ }
+
+ if (!str) {
+ return -1;
+ }
+
+ strncpy(quorum_type, str, quorum_type_len - 1);
+ free(str);
+
+ return 0;
+out:
+ return err;
+}
+
+/*
+ * Returns 1 if 'votequorum' is active. The called then knows that
+ * votequorum calls should work and can provide extra information
+ */
+static int using_votequorum(void)
+{
+ char quorumtype[256];
+ int using_voteq;
+
+ memset(quorumtype, 0, sizeof(quorumtype));
+
+ if (get_quorum_type(quorumtype, sizeof(quorumtype))) {
+ return -1;
+ }
+
+ if (strcmp(quorumtype, "corosync_votequorum") == 0) {
+ using_voteq = 1;
+ } else {
+ using_voteq = 0;
+ }
+
+ return using_voteq;
+}
+
+static int set_votes(uint32_t nodeid, int votes)
+{
+ int err;
+
+ if ((err=votequorum_setvotes(v_handle, nodeid, votes)) != CS_OK) {
+ fprintf(stderr, "Unable to set votes %d for nodeid: " CS_PRI_NODE_ID ": %s\n",
+ votes, nodeid, cs_strerror(err));
+ }
+
+ return (err == CS_OK ? EXIT_SUCCESS : EXIT_FAILURE);
+}
+
+static int set_expected(int expected_votes)
+{
+ int err;
+
+ if ((err=votequorum_setexpected(v_handle, expected_votes)) != CS_OK) {
+ fprintf(stderr, "Unable to set expected votes: %s\n", cs_strerror(err));
+ }
+
+ return (err == CS_OK ? EXIT_SUCCESS : EXIT_FAILURE);
+}
+
+/*
+ * node name by nodelist
+ */
+
+static const char *node_name_by_nodelist(uint32_t nodeid)
+{
+ cmap_iter_handle_t iter;
+ char key_name[CMAP_KEYNAME_MAXLEN + 1];
+ char tmp_key[CMAP_KEYNAME_MAXLEN + 1];
+ static char ret_buf[_POSIX_HOST_NAME_MAX];
+ char *str = NULL;
+ uint32_t node_pos, cur_nodeid;
+ int res = 0;
+
+ if (cmap_iter_init(cmap_handle, "nodelist.node.", &iter) != CS_OK) {
+ return "";
+ }
+
+ memset(ret_buf, 0, sizeof(ret_buf));
+
+ while ((cmap_iter_next(cmap_handle, iter, key_name, NULL, NULL)) == CS_OK) {
+
+ res = sscanf(key_name, "nodelist.node.%u.%s", &node_pos, tmp_key);
+ if (res != 2) {
+ continue;
+ }
+
+ if (strcmp(tmp_key, "nodeid") != 0) {
+ continue;
+ }
+
+ snprintf(tmp_key, CMAP_KEYNAME_MAXLEN, "nodelist.node.%u.nodeid", node_pos);
+ if (cmap_get_uint32(cmap_handle, tmp_key, &cur_nodeid) != CS_OK) {
+ continue;
+ }
+ if (cur_nodeid != nodeid) {
+ continue;
+ }
+ snprintf(tmp_key, CMAP_KEYNAME_MAXLEN, "nodelist.node.%u.name", node_pos);
+ if (cmap_get_string(cmap_handle, tmp_key, &str) != CS_OK) {
+ continue;
+ }
+ if (!str) {
+ continue;
+ }
+ strncpy(ret_buf, str, sizeof(ret_buf) - 1);
+ free(str);
+ break;
+ }
+ cmap_iter_finalize(cmap_handle, iter);
+
+ return ret_buf;
+}
+
+/*
+ * This resolves the first address assigned to a node
+ * and returns the name or IP address. Use cfgtool if you need more information.
+ */
+static const char *node_name(uint32_t nodeid, name_format_t name_format)
+{
+ int err;
+ int numaddrs;
+ corosync_cfg_node_address_t addrs[INTERFACE_MAX];
+ static char buf[(INET6_ADDRSTRLEN + 1) * KNET_MAX_LINK];
+ const char *nodelist_name = NULL;
+ socklen_t addrlen;
+ struct sockaddr_storage *ss;
+ int start_addr = 0;
+ int i;
+ int bufptr = 0;
+
+ buf[0] = '\0';
+
+ /* If a name is required, always look for the nodelist node0_addr name first */
+ if (name_format == ADDRESS_FORMAT_NAME) {
+ nodelist_name = node_name_by_nodelist(nodeid);
+ }
+ if ((nodelist_name) &&
+ (strlen(nodelist_name) > 0)) {
+ start_addr = 1;
+ assert(strlen(nodelist_name) < sizeof(buf));
+ strcpy(buf, nodelist_name);
+ bufptr = strlen(buf);
+ }
+
+ err = corosync_cfg_get_node_addrs(c_handle, nodeid, INTERFACE_MAX, &numaddrs, addrs);
+ if (err != CS_OK) {
+ fprintf(stderr, "Unable to get node address for nodeid " CS_PRI_NODE_ID ": %s\n", nodeid, cs_strerror(err));
+ return "";
+ }
+
+ /* Don't show all addressess */
+ if (!g_show_all_addrs) {
+ numaddrs = 1;
+ }
+
+ for (i=start_addr; i<numaddrs; i++) {
+
+ ss = (struct sockaddr_storage *)addrs[i].address;
+
+ if (!ss->ss_family) {
+ continue;
+ }
+
+ if (ss->ss_family == AF_INET6) {
+ addrlen = sizeof(struct sockaddr_in6);
+ } else {
+ addrlen = sizeof(struct sockaddr_in);
+ }
+
+ if (i) {
+ buf[bufptr++] = ',';
+ buf[bufptr++] = ' ';
+ }
+
+ if (!getnameinfo(
+ (struct sockaddr *)addrs[i].address, addrlen,
+ buf+bufptr, sizeof(buf)-bufptr,
+ NULL, 0,
+ (name_format == ADDRESS_FORMAT_IP)?NI_NUMERICHOST:0)) {
+ bufptr += strlen(buf+bufptr);
+ }
+ }
+
+ return buf;
+}
+
+
+static void votequorum_notification_fn(
+ votequorum_handle_t handle,
+ uint64_t context,
+ votequorum_ring_id_t ring_id,
+ uint32_t node_list_entries,
+ uint32_t node_list[])
+{
+ g_ring_id_rep_node = ring_id.nodeid;
+ g_vq_called = 1;
+}
+
+static void quorum_notification_fn(
+ quorum_handle_t handle,
+ uint32_t quorate,
+ uint64_t ring_id,
+ uint32_t view_list_entries,
+ uint32_t *view_list)
+{
+ int i;
+
+ g_called = 1;
+ g_quorate = quorate;
+ g_ring_id = ring_id;
+ g_view_list_entries = view_list_entries;
+ if (g_view_list) {
+ free(g_view_list);
+ }
+ g_view_list = malloc(sizeof(view_list_entry_t) * view_list_entries);
+ if (g_view_list) {
+ for (i=0; i< view_list_entries; i++) {
+ g_view_list[i].node_id = view_list[i];
+ g_view_list[i].name = NULL;
+ g_view_list[i].vq_info = NULL;
+ }
+ }
+}
+
+static void print_string_padded(const char *buf)
+{
+ int len, delta;
+
+ len = strlen(buf);
+ delta = 10 - len;
+ while (delta > 0) {
+ printf(" ");
+ delta--;
+ }
+ printf("%s ", buf);
+}
+
+static void print_uint32_padded(uint32_t value)
+{
+ char buf[12];
+
+ snprintf(buf, sizeof(buf) - 1, "%u", value);
+ print_string_padded(buf);
+}
+
+/* for qsort */
+static int compare_nodeids(const void *one, const void *two)
+{
+ const view_list_entry_t *info1 = one;
+ const view_list_entry_t *info2 = two;
+
+ if (info1->node_id == info2->node_id) {
+ return 0;
+ }
+ if (info1->node_id > info2->node_id) {
+ return 1;
+ }
+ return -1;
+}
+
+static int compare_nodenames(const void *one, const void *two)
+{
+ const view_list_entry_t *info1 = one;
+ const view_list_entry_t *info2 = two;
+
+ return strcmp(info1->name, info2->name);
+}
+
+static void display_nodes_data(nodeid_format_t nodeid_format, name_format_t name_format, sorttype_t sort_type)
+{
+ int i, display_qdevice = 0;
+ unsigned int our_flags = 0;
+ struct votequorum_info info[g_view_list_entries];
+ /*
+ * cache node info because we need to parse them twice
+ */
+ if (v_handle) {
+ for (i=0; i < g_view_list_entries; i++) {
+ if (votequorum_getinfo(v_handle, g_view_list[i].node_id, &info[i]) != CS_OK) {
+ printf("Unable to get node " CS_PRI_NODE_ID " info\n", g_view_list[i].node_id);
+ }
+ g_view_list[i].vq_info = &info[i];
+ if (info[i].flags & VOTEQUORUM_INFO_QDEVICE_REGISTERED) {
+ display_qdevice = 1;
+ }
+ }
+ }
+
+ /*
+ * Get node names
+ */
+ for (i=0; i < g_view_list_entries; i++) {
+ g_view_list[i].name = strdup(node_name(g_view_list[i].node_id, name_format));
+ }
+
+ printf("\nMembership information\n");
+ printf("----------------------\n");
+
+ print_string_padded("Nodeid");
+ if (v_handle) {
+ print_string_padded("Votes");
+ if ((display_qdevice) || (machine_parsable)) {
+ print_string_padded("Qdevice");
+ }
+ }
+ printf("Name\n");
+
+ /* corosync sends them already sorted by address */
+ if (sort_type == SORT_NODEID) {
+ qsort(g_view_list, g_view_list_entries, sizeof(view_list_entry_t), compare_nodeids);
+ }
+ if (sort_type == SORT_NODENAME) {
+ qsort(g_view_list, g_view_list_entries, sizeof(view_list_entry_t), compare_nodenames);
+ }
+ for (i=0; i < g_view_list_entries; i++) {
+ if (nodeid_format == NODEID_FORMAT_DECIMAL) {
+ print_uint32_padded(g_view_list[i].node_id);
+ } else {
+ printf("0x%08x ", g_view_list[i].node_id);
+ }
+ if (v_handle) {
+ int votes = -1;
+
+ votes = info[i].node_votes;
+ print_uint32_padded(votes);
+
+ if ((display_qdevice) || (machine_parsable)) {
+ if (info[i].flags & VOTEQUORUM_INFO_QDEVICE_REGISTERED) {
+ char buf[10];
+
+ snprintf(buf, sizeof(buf),
+ "%s,%s,%s",
+ info[i].flags & VOTEQUORUM_INFO_QDEVICE_ALIVE?"A":"NA",
+ info[i].flags & VOTEQUORUM_INFO_QDEVICE_CAST_VOTE?"V":"NV",
+ info[i].flags & VOTEQUORUM_INFO_QDEVICE_MASTER_WINS?"MW":"NMW");
+ print_string_padded(buf);
+ } else {
+ print_string_padded("NR");
+ }
+ }
+ }
+ printf("%s", g_view_list[i].name);
+ if (g_view_list[i].node_id == our_nodeid) {
+ printf(" (local)");
+ if (v_handle) {
+ our_flags = info[i].flags;
+ }
+ }
+ printf("\n");
+ }
+
+ if (g_view_list_entries) {
+ for (i=0; i < g_view_list_entries; i++) {
+ free(g_view_list[i].name);
+ }
+ free(g_view_list);
+ g_view_list = NULL;
+ }
+
+ if (display_qdevice) {
+ if (nodeid_format == NODEID_FORMAT_DECIMAL) {
+ print_uint32_padded(VOTEQUORUM_QDEVICE_NODEID);
+ } else {
+ printf("0x%08x ", VOTEQUORUM_QDEVICE_NODEID);
+ }
+ /* If the quorum device is inactive on this node then show votes as 0
+ so that the display is not confusing */
+ if (our_flags & VOTEQUORUM_INFO_QDEVICE_CAST_VOTE) {
+ print_uint32_padded(info[0].qdevice_votes);
+ }
+ else {
+ print_uint32_padded(0);
+ }
+ printf(" %s", info[0].qdevice_name);
+ if (our_flags & VOTEQUORUM_INFO_QDEVICE_CAST_VOTE) {
+ printf("\n");
+ }
+ else {
+ printf(" (votes %d)\n", info[0].qdevice_votes);
+ }
+ }
+
+}
+
+static int display_quorum_data(int is_quorate,
+ nodeid_format_t nodeid_format, name_format_t name_format, sorttype_t sort_type,
+ int loop)
+{
+ struct votequorum_info info;
+ int err;
+ char quorumtype[256];
+ time_t t;
+
+ memset(quorumtype, 0, sizeof(quorumtype));
+
+ printf("Quorum information\n");
+ printf("------------------\n");
+ time(&t);
+ printf("Date: %s", ctime((const time_t *)&t));
+
+ if (get_quorum_type(quorumtype, sizeof(quorumtype))) {
+ strncpy(quorumtype, "Not configured", sizeof(quorumtype) - 1);
+ }
+ printf("Quorum provider: %s\n", quorumtype);
+ printf("Nodes: %d\n", g_view_list_entries);
+ if (nodeid_format == NODEID_FORMAT_DECIMAL) {
+ printf("Node ID: " CS_PRI_NODE_ID "\n", our_nodeid);
+ } else {
+ printf("Node ID: 0x%08x\n", our_nodeid);
+ }
+
+ if (v_handle) {
+ printf("Ring ID: " CS_PRI_RING_ID "\n", g_ring_id_rep_node, g_ring_id);
+ }
+ else {
+ printf("Ring ID: " CS_PRI_RING_ID_SEQ "\n", g_ring_id);
+ }
+ printf("Quorate: %s\n", is_quorate?"Yes":"No");
+
+ if (!v_handle) {
+ return CS_OK;
+ }
+
+ err=votequorum_getinfo(v_handle, our_nodeid, &info);
+ if ((err == CS_OK) || (err == CS_ERR_NOT_EXIST)) {
+ printf("\nVotequorum information\n");
+ printf("----------------------\n");
+ printf("Expected votes: %d\n", info.node_expected_votes);
+ printf("Highest expected: %d\n", info.highest_expected);
+ printf("Total votes: %d\n", info.total_votes);
+ printf("Quorum: %d %s\n", info.quorum, info.flags & VOTEQUORUM_INFO_QUORATE?" ":"Activity blocked");
+ printf("Flags: ");
+ if (info.flags & VOTEQUORUM_INFO_TWONODE) printf("2Node ");
+ if (info.flags & VOTEQUORUM_INFO_QUORATE) printf("Quorate ");
+ if (info.flags & VOTEQUORUM_INFO_WAIT_FOR_ALL) printf("WaitForAll ");
+ if (info.flags & VOTEQUORUM_INFO_LAST_MAN_STANDING) printf("LastManStanding ");
+ if (info.flags & VOTEQUORUM_INFO_AUTO_TIE_BREAKER) printf("AutoTieBreaker ");
+ if (info.flags & VOTEQUORUM_INFO_ALLOW_DOWNSCALE) printf("AllowDownscale ");
+ if (info.flags & VOTEQUORUM_INFO_QDEVICE_REGISTERED) printf("Qdevice ");
+ printf("\n");
+ } else {
+ fprintf(stderr, "Unable to get node info: %s\n", cs_strerror(err));
+ }
+
+ display_nodes_data(nodeid_format, name_format, sort_type);
+
+ return err;
+}
+
+/*
+ * return EXIT_SUCCESS if quorate
+ * EXIT_NOT_QUORATE if not quorate
+ * EXIT_FAILURE on error
+ */
+static int show_status(nodeid_format_t nodeid_format, name_format_t name_format, sorttype_t sort_type)
+{
+ int is_quorate;
+ int err;
+
+ err=quorum_getquorate(q_handle, &is_quorate);
+ if (err != CS_OK) {
+ fprintf(stderr, "Unable to get cluster quorate status: %s\n", cs_strerror(err));
+ goto quorum_err;
+ }
+
+ err=quorum_trackstart(q_handle, CS_TRACK_CURRENT);
+ if (err != CS_OK) {
+ fprintf(stderr, "Unable to start quorum status tracking: %s\n", cs_strerror(err));
+ goto quorum_err;
+ }
+
+ g_called = 0;
+ while (g_called == 0 && err == CS_OK) {
+ err = quorum_dispatch(q_handle, CS_DISPATCH_ONE);
+ if (err != CS_OK) {
+ fprintf(stderr, "Unable to dispatch quorum status: %s\n", cs_strerror(err));
+ }
+ }
+
+ if (quorum_trackstop(q_handle) != CS_OK) {
+ fprintf(stderr, "Unable to stop quorum status tracking: %s\n", cs_strerror(err));
+ }
+
+ if (using_votequorum()) {
+
+ if ( (err=votequorum_trackstart(v_handle, 0LL, CS_TRACK_CURRENT)) != CS_OK) {
+ fprintf(stderr, "Unable to start votequorum status tracking: %s\n", cs_strerror(err));
+ goto quorum_err;
+ }
+
+ g_vq_called = 0;
+ while (g_vq_called == 0 && err == CS_OK) {
+ err = votequorum_dispatch(v_handle, CS_DISPATCH_ONE);
+ if (err != CS_OK) {
+ fprintf(stderr, "Unable to dispatch votequorum status: %s\n", cs_strerror(err));
+ }
+ }
+ }
+
+quorum_err:
+ if (err != CS_OK) {
+ return EXIT_FAILURE;
+ }
+
+ err = display_quorum_data(is_quorate, nodeid_format, name_format, sort_type, 0);
+ if (err != CS_OK) {
+ return EXIT_FAILURE;
+ }
+
+ return (is_quorate ? EXIT_SUCCESS : EXIT_NOT_QUORATE);
+}
+
+static int monitor_status(nodeid_format_t nodeid_format, name_format_t name_format, sorttype_t sort_type) {
+ int err;
+ int loop = 0;
+
+ if (q_type == QUORUM_FREE) {
+ printf("\nQuorum is not configured - cannot monitor\n");
+ return show_status(nodeid_format, name_format, sort_type);
+ }
+
+ err=quorum_trackstart(q_handle, CS_TRACK_CHANGES);
+ if (err != CS_OK) {
+ fprintf(stderr, "Unable to start quorum status tracking: %s\n", cs_strerror(err));
+ goto quorum_err;
+ }
+
+ if (using_votequorum()) {
+ if ( (err=votequorum_trackstart(v_handle, 0LL, CS_TRACK_CHANGES)) != CS_OK) {
+ fprintf(stderr, "Unable to start votequorum status tracking: %s\n", cs_strerror(err));
+ goto quorum_err;
+ }
+ }
+
+
+ while (1) {
+ err = quorum_dispatch(q_handle, CS_DISPATCH_ONE);
+ if (err != CS_OK) {
+ fprintf(stderr, "Unable to dispatch quorum status: %s\n", cs_strerror(err));
+ goto quorum_err;
+ }
+ if (using_votequorum()) {
+ g_vq_called = 0;
+ while (!g_vq_called) {
+ err = votequorum_dispatch(v_handle, CS_DISPATCH_ONE);
+ if (err != CS_OK) {
+ fprintf(stderr, "Unable to dispatch votequorum status: %s\n", cs_strerror(err));
+ goto quorum_err;
+ }
+ }
+ }
+
+ err = display_quorum_data(g_quorate, nodeid_format, name_format, sort_type, loop);
+ printf("\n");
+ loop = 1;
+ if (err != CS_OK) {
+ fprintf(stderr, "Unable to display quorum data: %s\n", cs_strerror(err));
+ goto quorum_err;
+ }
+ }
+
+quorum_err:
+ return EXIT_FAILURE;
+}
+
+static int show_nodes(nodeid_format_t nodeid_format, name_format_t name_format, sorttype_t sort_type)
+{
+ int err;
+ int result = EXIT_FAILURE;
+
+ err = quorum_trackstart(q_handle, CS_TRACK_CURRENT);
+ if (err != CS_OK) {
+ fprintf(stderr, "Unable to start quorum status tracking: %s\n", cs_strerror(err));
+ goto err_exit;
+ }
+
+ g_called = 0;
+ while (g_called == 0) {
+ err = quorum_dispatch(q_handle, CS_DISPATCH_ONE);
+ if (err != CS_OK) {
+ fprintf(stderr, "Unable to dispatch quorum status: %s\n", cs_strerror(err));
+ goto err_exit;
+ }
+ }
+
+ display_nodes_data(nodeid_format, name_format, sort_type);
+
+ result = EXIT_SUCCESS;
+err_exit:
+ return result;
+}
+
+static int unregister_qdevice(void)
+{
+ int err;
+ struct votequorum_info info;
+ int result;
+
+ result = EXIT_FAILURE;
+
+ err = votequorum_getinfo(v_handle, our_nodeid, &info);
+ if (err != CS_OK) {
+ fprintf(stderr, "Unable to get quorum device info: %s\n", cs_strerror(err));
+ goto err_exit;
+ }
+
+ if (!(info.flags & VOTEQUORUM_INFO_QDEVICE_REGISTERED)) {
+ result = EXIT_SUCCESS;
+ goto err_exit;
+ }
+
+ err = votequorum_qdevice_unregister(v_handle, info.qdevice_name);
+ if (err != CS_OK) {
+ fprintf(stderr, "Unable to unregister quorum device: %s\n", cs_strerror(err));
+ goto err_exit;
+ }
+
+ result = EXIT_SUCCESS;
+err_exit:
+ return result;
+}
+
+/*
+ * return -1 on error
+ * 0 if OK
+ */
+
+static int init_all(void) {
+ cmap_handle = 0;
+ q_handle = 0;
+ v_handle = 0;
+ c_handle = 0;
+
+ if (cmap_initialize(&cmap_handle) != CS_OK) {
+ fprintf(stderr, "Cannot initialize CMAP service\n");
+ cmap_handle = 0;
+ goto out;
+ }
+
+ if (quorum_initialize(&q_handle, &q_callbacks, &q_type) != CS_OK) {
+ fprintf(stderr, "Cannot initialize QUORUM service\n");
+ q_handle = 0;
+ goto out;
+ }
+
+ if (corosync_cfg_initialize(&c_handle, &c_callbacks) != CS_OK) {
+ fprintf(stderr, "Cannot initialise CFG service\n");
+ c_handle = 0;
+ goto out;
+ }
+
+ if (using_votequorum() <= 0) {
+ return 0;
+ }
+
+ if (votequorum_initialize(&v_handle, &v_callbacks) != CS_OK) {
+ fprintf(stderr, "Cannot initialise VOTEQUORUM service\n");
+ v_handle = 0;
+ goto out;
+ }
+
+ if (cmap_get_uint32(cmap_handle, "runtime.votequorum.this_node_id", &our_nodeid) != CS_OK) {
+ fprintf(stderr, "Unable to retrieve this_node_id\n");
+ goto out;
+ }
+
+ return 0;
+out:
+ return -1;
+}
+
+static void close_all(void) {
+ if (cmap_handle) {
+ cmap_finalize(cmap_handle);
+ }
+ if (q_handle) {
+ quorum_finalize(q_handle);
+ }
+ if (c_handle) {
+ corosync_cfg_finalize(c_handle);
+ }
+ if (v_handle) {
+ votequorum_finalize(v_handle);
+ }
+}
+
+int main (int argc, char *argv[]) {
+ const char *options = "VHaslpmfe:v:hin:o:";
+ int opt;
+ int votes = 0;
+ int ret = 0;
+ uint32_t nodeid = 0;
+ uint32_t nodeid_set = 0;
+ nodeid_format_t nodeid_format = NODEID_FORMAT_DECIMAL;
+ name_format_t address_format = ADDRESS_FORMAT_NAME;
+ command_t command_opt = CMD_SHOWSTATUS;
+ sorttype_t sort_opt = SORT_ADDR;
+ long long int l;
+
+ while ( (opt = getopt(argc, argv, options)) != -1 ) {
+ switch (opt) {
+ case 'f':
+ command_opt = CMD_UNREGISTER_QDEVICE;
+ break;
+ case 's':
+ command_opt = CMD_SHOWSTATUS;
+ break;
+ case 'a':
+ g_show_all_addrs = 1;
+ break;
+ case 'm':
+ command_opt = CMD_MONITOR;
+ break;
+ case 'i':
+ address_format = ADDRESS_FORMAT_IP;
+ break;
+ case 'H':
+ nodeid_format = NODEID_FORMAT_HEX;
+ break;
+ case 'l':
+ command_opt = CMD_SHOWNODES;
+ break;
+ case 'p':
+ machine_parsable = 1;
+ break;
+ case 'e':
+ if (util_strtonum(optarg, 1, INT_MAX, &l) == -1) {
+ fprintf(stderr, "New expected votes value was not valid, try a positive number\n");
+ exit(EXIT_FAILURE);
+ }
+ votes = l;
+ command_opt = CMD_SETEXPECTED;
+ break;
+ case 'n':
+ if (util_strtonum(optarg, 1, UINT_MAX, &l) == -1) {
+ fprintf(stderr, "The nodeid was not valid, try a positive number\n");
+ exit(EXIT_FAILURE);
+ }
+ nodeid = l;
+ nodeid_set = 1;
+ break;
+ case 'v':
+ if (util_strtonum(optarg, 0, INT_MAX, &l) == -1) {
+ fprintf(stderr, "New votes value was not valid, try a positive number or zero\n");
+ exit(EXIT_FAILURE);
+ }
+ votes = l;
+ command_opt = CMD_SETVOTES;
+ break;
+ case 'o':
+ if (strcmp(optarg, "a") == 0) {
+ sort_opt = SORT_ADDR;
+ } else if (strcmp(optarg, "i") == 0) {
+ sort_opt = SORT_NODEID;
+ } else if (strcmp(optarg, "n") == 0) {
+ sort_opt = SORT_NODENAME;
+ } else {
+ fprintf(stderr, "Invalid ordering option. valid orders are a(address), i(node ID) or n(name)\n");
+ exit(EXIT_FAILURE);
+ }
+ break;
+ case 'V':
+ printf("corosync-quorumtool version: %s\n", VERSION);
+ exit(EXIT_SUCCESS);
+ break;
+ case 'h':
+ show_usage(argv[0]);
+ exit(EXIT_SUCCESS);
+ break;
+ case ':':
+ case '?':
+ default:
+ show_usage(argv[0]);
+ exit(EXIT_FAILURE);
+ break;
+ }
+ }
+
+ if (init_all()) {
+ close_all();
+ exit(EXIT_FAILURE);
+ }
+
+ switch (command_opt) {
+ case CMD_SHOWNODES:
+ ret = show_nodes(nodeid_format, address_format, sort_opt);
+ break;
+ case CMD_SHOWSTATUS:
+ ret = show_status(nodeid_format, address_format, sort_opt);
+ break;
+ case CMD_SETVOTES:
+ if (using_votequorum() > 0) {
+ if (!nodeid_set) {
+ nodeid = our_nodeid;
+ }
+ ret = set_votes(nodeid, votes);
+ } else {
+ fprintf(stderr, "You cannot change node votes, corosync is not using votequorum\n");
+ ret = EXIT_FAILURE;
+ }
+ break;
+ case CMD_SETEXPECTED:
+ if (using_votequorum() > 0) {
+ ret = set_expected(votes);
+ } else {
+ fprintf(stderr, "You cannot change expected votes, corosync is not using votequorum\n");
+ ret = EXIT_FAILURE;
+ }
+ break;
+ case CMD_MONITOR:
+ ret = monitor_status(nodeid_format, address_format, sort_opt);
+ break;
+ case CMD_UNREGISTER_QDEVICE:
+ if (using_votequorum() > 0) {
+ ret = unregister_qdevice();
+ } else {
+ fprintf(stderr, "You cannot unregister quorum device, corosync is not using votequorum\n");
+ ret = EXIT_FAILURE;
+ }
+ break;
+ }
+
+ close_all();
+
+ return (ret);
+}
diff --git a/tools/corosync-xmlproc.sh b/tools/corosync-xmlproc.sh
new file mode 100644
index 0000000..c098958
--- /dev/null
+++ b/tools/corosync-xmlproc.sh
@@ -0,0 +1,57 @@
+#!@BASHPATH@
+
+# Copyright (c) 2011 Red Hat, Inc.
+#
+# All rights reserved.
+#
+# Author: Jan Friesse (jfriesse@redhat.com)
+#
+# This software licensed under BSD license, the text of which follows:
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# - Redistributions of source code must retain the above copyright notice,
+# this list of conditions and the following disclaimer.
+# - Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+# - Neither the name of the Red Hat, Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from this
+# software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+# THE POSSIBILITY OF SUCH DAMAGE.
+
+XSLT_PROC=xsltproc
+
+usage() {
+ echo "$0 input_config [output]"
+ echo " where input_config is valid XML configuration file"
+
+ exit 1
+}
+
+[ "$1" == "" ] && usage
+
+$XSLT_PROC -V >/dev/null 2>&1
+if [ "$?" != 0 ];then
+ echo "Can't find xslt processor $XSLT_PROC"
+ exit 2
+fi
+
+# TODO:
+# Validation should occur before actual processing
+
+[ "$2" != "" ] && out_param="-o $2"
+
+$XSLT_PROC --stringparam inputfile "$1" $out_param @DATADIR@/corosync/xml2conf.xsl "$1"
diff --git a/tools/util.c b/tools/util.c
new file mode 100644
index 0000000..f2ef5fd
--- /dev/null
+++ b/tools/util.c
@@ -0,0 +1,35 @@
+#include <stdlib.h>
+#include <errno.h>
+
+#include "util.h"
+
+/*
+ * Safer wrapper of strtoll. Return 0 on success, otherwise -1.
+ * Idea from corosync-qdevice project
+ */
+int
+util_strtonum(const char *str, long long int min_val, long long int max_val,
+ long long int *res)
+{
+ long long int tmp_ll;
+ char *ep;
+
+ if (min_val > max_val) {
+ return (-1);
+ }
+
+ errno = 0;
+
+ tmp_ll = strtoll(str, &ep, 10);
+ if (ep == str || *ep != '\0' || errno != 0) {
+ return (-1);
+ }
+
+ if (tmp_ll < min_val || tmp_ll > max_val) {
+ return (-1);
+ }
+
+ *res = tmp_ll;
+
+ return (0);
+}
diff --git a/tools/util.h b/tools/util.h
new file mode 100644
index 0000000..619cf67
--- /dev/null
+++ b/tools/util.h
@@ -0,0 +1,15 @@
+#ifndef COROSYNC_TOOLS_UTIL_H_DEFINED
+#define COROSYNC_TOOLS_UTIL_H_DEFINED
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern int util_strtonum(const char *str, long long int min_val,
+ long long int max_val, long long int *res);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* COROSYNC_TOOLS_UTIL_H_DEFINED */
diff --git a/vqsim/Makefile.am b/vqsim/Makefile.am
new file mode 100644
index 0000000..7639fcf
--- /dev/null
+++ b/vqsim/Makefile.am
@@ -0,0 +1,57 @@
+#
+# Copyright (c) 2009 Red Hat, Inc.
+#
+# Authors: Andrew Beekhof
+# Steven Dake (sdake@redhat.com)
+#
+# This software licensed under BSD license, the text of which follows:
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# - Redistributions of source code must retain the above copyright notice,
+# this list of conditions and the following disclaimer.
+# - Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+# - Neither the name of the MontaVista Software, Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from this
+# software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+# THE POSSIBILITY OF SUCH DAMAGE.
+
+MAINTAINERCLEANFILES = Makefile.in
+
+if BUILD_VQSIM
+
+noinst_HEADERS = vqsim.h
+
+bin_PROGRAMS = corosync-vqsim
+
+corosync_vqsim_CFLAGS = $(knet_CFLAGS)
+
+corosync_vqsim_LDADD = $(top_builddir)/common_lib/libcorosync_common.la \
+ ../exec/corosync-votequorum.o ../exec/corosync-icmap.o \
+ ../exec/corosync-coroparse.o ../exec/corosync-logconfig.o \
+ ../exec/corosync-util.o ../exec/corosync-logsys.o \
+ $(LIBQB_LIBS) $(knet_LIBS)
+
+if VQSIM_READLINE
+corosync_vqsim_LDADD += -lreadline
+endif
+
+corosync_vqsim_DEPENDENCIES = $(top_builddir)/common_lib/libcorosync_common.la
+
+corosync_vqsim_SOURCES = vqmain.c parser.c vq_object.c vqsim_vq_engine.c
+
+endif
diff --git a/vqsim/Makefile.in b/vqsim/Makefile.in
new file mode 100644
index 0000000..df8ab19
--- /dev/null
+++ b/vqsim/Makefile.in
@@ -0,0 +1,787 @@
+# Makefile.in generated by automake 1.13.4 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+#
+# Copyright (c) 2009 Red Hat, Inc.
+#
+# Authors: Andrew Beekhof
+# Steven Dake (sdake@redhat.com)
+#
+# This software licensed under BSD license, the text of which follows:
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# - Redistributions of source code must retain the above copyright notice,
+# this list of conditions and the following disclaimer.
+# - Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+# - Neither the name of the MontaVista Software, Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from this
+# software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+# THE POSSIBILITY OF SUCH DAMAGE.
+
+
+VPATH = @srcdir@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+@BUILD_VQSIM_TRUE@bin_PROGRAMS = corosync-vqsim$(EXEEXT)
+@BUILD_VQSIM_TRUE@@VQSIM_READLINE_TRUE@am__append_1 = -lreadline
+subdir = vqsim
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+ $(top_srcdir)/depcomp $(am__noinst_HEADERS_DIST)
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/lib/libcfg.verso $(top_srcdir)/lib/libcpg.verso \
+ $(top_srcdir)/lib/libquorum.verso \
+ $(top_srcdir)/lib/libsam.verso \
+ $(top_srcdir)/lib/libvotequorum.verso \
+ $(top_srcdir)/lib/libcmap.verso $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/include/corosync/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__installdirs = "$(DESTDIR)$(bindir)"
+PROGRAMS = $(bin_PROGRAMS)
+am__corosync_vqsim_SOURCES_DIST = vqmain.c parser.c vq_object.c \
+ vqsim_vq_engine.c
+@BUILD_VQSIM_TRUE@am_corosync_vqsim_OBJECTS = \
+@BUILD_VQSIM_TRUE@ corosync_vqsim-vqmain.$(OBJEXT) \
+@BUILD_VQSIM_TRUE@ corosync_vqsim-parser.$(OBJEXT) \
+@BUILD_VQSIM_TRUE@ corosync_vqsim-vq_object.$(OBJEXT) \
+@BUILD_VQSIM_TRUE@ corosync_vqsim-vqsim_vq_engine.$(OBJEXT)
+corosync_vqsim_OBJECTS = $(am_corosync_vqsim_OBJECTS)
+am__DEPENDENCIES_1 =
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 =
+corosync_vqsim_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(corosync_vqsim_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o \
+ $@
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/corosync
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo " CC " $@;
+am__v_CC_1 =
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo " CCLD " $@;
+am__v_CCLD_1 =
+SOURCES = $(corosync_vqsim_SOURCES)
+DIST_SOURCES = $(am__corosync_vqsim_SOURCES_DIST)
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+am__noinst_HEADERS_DIST = vqsim.h
+HEADERS = $(noinst_HEADERS)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALLOCA = @ALLOCA@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUGTOOL = @AUGTOOL@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BASHPATH = @BASHPATH@
+BINDGEN = @BINDGEN@
+CARGO = @CARGO@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFG_SONAME = @CFG_SONAME@
+CFLAGS = @CFLAGS@
+CLIPPY = @CLIPPY@
+CMAP_SONAME = @CMAP_SONAME@
+COROSYSCONFDIR = @COROSYSCONFDIR@
+CPG_SONAME = @CPG_SONAME@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DBUS_CFLAGS = @DBUS_CFLAGS@
+DBUS_LIBS = @DBUS_LIBS@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DOT = @DOT@
+DOXYGEN = @DOXYGEN@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GREP = @GREP@
+GROFF = @GROFF@
+INITCONFIGDIR = @INITCONFIGDIR@
+INITDDIR = @INITDDIR@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBQB_CFLAGS = @LIBQB_CFLAGS@
+LIBQB_LIBS = @LIBQB_LIBS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LINT_FLAGS = @LINT_FLAGS@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LOGDIR = @LOGDIR@
+LOGROTATEDIR = @LOGROTATEDIR@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+QUORUM_SONAME = @QUORUM_SONAME@
+RANLIB = @RANLIB@
+RUSTC = @RUSTC@
+RUSTDOC = @RUSTDOC@
+RUSTFMT = @RUSTFMT@
+RUST_FLAGS = @RUST_FLAGS@
+RUST_TARGET_DIR = @RUST_TARGET_DIR@
+SAM_SONAME = @SAM_SONAME@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SNMPCONFIG = @SNMPCONFIG@
+SNMP_LIBS = @SNMP_LIBS@
+SOMAJOR = @SOMAJOR@
+SOMICRO = @SOMICRO@
+SOMINOR = @SOMINOR@
+SONAME = @SONAME@
+STRIP = @STRIP@
+SYSTEMDDIR = @SYSTEMDDIR@
+VERSCRIPT_LDFLAGS = @VERSCRIPT_LDFLAGS@
+VERSION = @VERSION@
+VOTEQUORUM_SONAME = @VOTEQUORUM_SONAME@
+WITH_LIST = @WITH_LIST@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+corosyncrustver = @corosyncrustver@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+knet_CFLAGS = @knet_CFLAGS@
+knet_LIBS = @knet_LIBS@
+libdir = @libdir@
+libexecdir = @libexecdir@
+libsystemd_CFLAGS = @libsystemd_CFLAGS@
+libsystemd_LIBS = @libsystemd_LIBS@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+nozzle_CFLAGS = @nozzle_CFLAGS@
+nozzle_LIBS = @nozzle_LIBS@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+statgrab_CFLAGS = @statgrab_CFLAGS@
+statgrab_LIBS = @statgrab_LIBS@
+statgrabge090_CFLAGS = @statgrabge090_CFLAGS@
+statgrabge090_LIBS = @statgrabge090_LIBS@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+MAINTAINERCLEANFILES = Makefile.in
+@BUILD_VQSIM_TRUE@noinst_HEADERS = vqsim.h
+@BUILD_VQSIM_TRUE@corosync_vqsim_CFLAGS = $(knet_CFLAGS)
+@BUILD_VQSIM_TRUE@corosync_vqsim_LDADD = $(top_builddir)/common_lib/libcorosync_common.la \
+@BUILD_VQSIM_TRUE@ ../exec/corosync-votequorum.o \
+@BUILD_VQSIM_TRUE@ ../exec/corosync-icmap.o \
+@BUILD_VQSIM_TRUE@ ../exec/corosync-coroparse.o \
+@BUILD_VQSIM_TRUE@ ../exec/corosync-logconfig.o \
+@BUILD_VQSIM_TRUE@ ../exec/corosync-util.o \
+@BUILD_VQSIM_TRUE@ ../exec/corosync-logsys.o $(LIBQB_LIBS) \
+@BUILD_VQSIM_TRUE@ $(knet_LIBS) $(am__append_1)
+@BUILD_VQSIM_TRUE@corosync_vqsim_DEPENDENCIES = $(top_builddir)/common_lib/libcorosync_common.la
+@BUILD_VQSIM_TRUE@corosync_vqsim_SOURCES = vqmain.c parser.c vq_object.c vqsim_vq_engine.c
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign vqsim/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign vqsim/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+install-binPROGRAMS: $(bin_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \
+ fi; \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed 's/$(EXEEXT)$$//' | \
+ while read p p1; do if test -f $$p \
+ || test -f $$p1 \
+ ; then echo "$$p"; echo "$$p"; else :; fi; \
+ done | \
+ sed -e 'p;s,.*/,,;n;h' \
+ -e 's|.*|.|' \
+ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \
+ sed 'N;N;N;s,\n, ,g' | \
+ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \
+ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
+ if ($$2 == $$4) files[d] = files[d] " " $$1; \
+ else { print "f", $$3 "/" $$4, $$1; } } \
+ END { for (d in files) print "f", d, files[d] }' | \
+ while read type dir files; do \
+ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
+ test -z "$$files" || { \
+ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \
+ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \
+ } \
+ ; done
+
+uninstall-binPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
+ files=`for p in $$list; do echo "$$p"; done | \
+ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \
+ -e 's/$$/$(EXEEXT)/' \
+ `; \
+ test -n "$$list" || exit 0; \
+ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \
+ cd "$(DESTDIR)$(bindir)" && rm -f $$files
+
+clean-binPROGRAMS:
+ @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \
+ echo " rm -f" $$list; \
+ rm -f $$list || exit $$?; \
+ test -n "$(EXEEXT)" || exit 0; \
+ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f" $$list; \
+ rm -f $$list
+
+corosync-vqsim$(EXEEXT): $(corosync_vqsim_OBJECTS) $(corosync_vqsim_DEPENDENCIES) $(EXTRA_corosync_vqsim_DEPENDENCIES)
+ @rm -f corosync-vqsim$(EXEEXT)
+ $(AM_V_CCLD)$(corosync_vqsim_LINK) $(corosync_vqsim_OBJECTS) $(corosync_vqsim_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/corosync_vqsim-parser.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/corosync_vqsim-vq_object.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/corosync_vqsim-vqmain.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/corosync_vqsim-vqsim_vq_engine.Po@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+corosync_vqsim-vqmain.o: vqmain.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(corosync_vqsim_CFLAGS) $(CFLAGS) -MT corosync_vqsim-vqmain.o -MD -MP -MF $(DEPDIR)/corosync_vqsim-vqmain.Tpo -c -o corosync_vqsim-vqmain.o `test -f 'vqmain.c' || echo '$(srcdir)/'`vqmain.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/corosync_vqsim-vqmain.Tpo $(DEPDIR)/corosync_vqsim-vqmain.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vqmain.c' object='corosync_vqsim-vqmain.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(corosync_vqsim_CFLAGS) $(CFLAGS) -c -o corosync_vqsim-vqmain.o `test -f 'vqmain.c' || echo '$(srcdir)/'`vqmain.c
+
+corosync_vqsim-vqmain.obj: vqmain.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(corosync_vqsim_CFLAGS) $(CFLAGS) -MT corosync_vqsim-vqmain.obj -MD -MP -MF $(DEPDIR)/corosync_vqsim-vqmain.Tpo -c -o corosync_vqsim-vqmain.obj `if test -f 'vqmain.c'; then $(CYGPATH_W) 'vqmain.c'; else $(CYGPATH_W) '$(srcdir)/vqmain.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/corosync_vqsim-vqmain.Tpo $(DEPDIR)/corosync_vqsim-vqmain.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vqmain.c' object='corosync_vqsim-vqmain.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(corosync_vqsim_CFLAGS) $(CFLAGS) -c -o corosync_vqsim-vqmain.obj `if test -f 'vqmain.c'; then $(CYGPATH_W) 'vqmain.c'; else $(CYGPATH_W) '$(srcdir)/vqmain.c'; fi`
+
+corosync_vqsim-parser.o: parser.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(corosync_vqsim_CFLAGS) $(CFLAGS) -MT corosync_vqsim-parser.o -MD -MP -MF $(DEPDIR)/corosync_vqsim-parser.Tpo -c -o corosync_vqsim-parser.o `test -f 'parser.c' || echo '$(srcdir)/'`parser.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/corosync_vqsim-parser.Tpo $(DEPDIR)/corosync_vqsim-parser.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='parser.c' object='corosync_vqsim-parser.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(corosync_vqsim_CFLAGS) $(CFLAGS) -c -o corosync_vqsim-parser.o `test -f 'parser.c' || echo '$(srcdir)/'`parser.c
+
+corosync_vqsim-parser.obj: parser.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(corosync_vqsim_CFLAGS) $(CFLAGS) -MT corosync_vqsim-parser.obj -MD -MP -MF $(DEPDIR)/corosync_vqsim-parser.Tpo -c -o corosync_vqsim-parser.obj `if test -f 'parser.c'; then $(CYGPATH_W) 'parser.c'; else $(CYGPATH_W) '$(srcdir)/parser.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/corosync_vqsim-parser.Tpo $(DEPDIR)/corosync_vqsim-parser.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='parser.c' object='corosync_vqsim-parser.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(corosync_vqsim_CFLAGS) $(CFLAGS) -c -o corosync_vqsim-parser.obj `if test -f 'parser.c'; then $(CYGPATH_W) 'parser.c'; else $(CYGPATH_W) '$(srcdir)/parser.c'; fi`
+
+corosync_vqsim-vq_object.o: vq_object.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(corosync_vqsim_CFLAGS) $(CFLAGS) -MT corosync_vqsim-vq_object.o -MD -MP -MF $(DEPDIR)/corosync_vqsim-vq_object.Tpo -c -o corosync_vqsim-vq_object.o `test -f 'vq_object.c' || echo '$(srcdir)/'`vq_object.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/corosync_vqsim-vq_object.Tpo $(DEPDIR)/corosync_vqsim-vq_object.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vq_object.c' object='corosync_vqsim-vq_object.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(corosync_vqsim_CFLAGS) $(CFLAGS) -c -o corosync_vqsim-vq_object.o `test -f 'vq_object.c' || echo '$(srcdir)/'`vq_object.c
+
+corosync_vqsim-vq_object.obj: vq_object.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(corosync_vqsim_CFLAGS) $(CFLAGS) -MT corosync_vqsim-vq_object.obj -MD -MP -MF $(DEPDIR)/corosync_vqsim-vq_object.Tpo -c -o corosync_vqsim-vq_object.obj `if test -f 'vq_object.c'; then $(CYGPATH_W) 'vq_object.c'; else $(CYGPATH_W) '$(srcdir)/vq_object.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/corosync_vqsim-vq_object.Tpo $(DEPDIR)/corosync_vqsim-vq_object.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vq_object.c' object='corosync_vqsim-vq_object.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(corosync_vqsim_CFLAGS) $(CFLAGS) -c -o corosync_vqsim-vq_object.obj `if test -f 'vq_object.c'; then $(CYGPATH_W) 'vq_object.c'; else $(CYGPATH_W) '$(srcdir)/vq_object.c'; fi`
+
+corosync_vqsim-vqsim_vq_engine.o: vqsim_vq_engine.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(corosync_vqsim_CFLAGS) $(CFLAGS) -MT corosync_vqsim-vqsim_vq_engine.o -MD -MP -MF $(DEPDIR)/corosync_vqsim-vqsim_vq_engine.Tpo -c -o corosync_vqsim-vqsim_vq_engine.o `test -f 'vqsim_vq_engine.c' || echo '$(srcdir)/'`vqsim_vq_engine.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/corosync_vqsim-vqsim_vq_engine.Tpo $(DEPDIR)/corosync_vqsim-vqsim_vq_engine.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vqsim_vq_engine.c' object='corosync_vqsim-vqsim_vq_engine.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(corosync_vqsim_CFLAGS) $(CFLAGS) -c -o corosync_vqsim-vqsim_vq_engine.o `test -f 'vqsim_vq_engine.c' || echo '$(srcdir)/'`vqsim_vq_engine.c
+
+corosync_vqsim-vqsim_vq_engine.obj: vqsim_vq_engine.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(corosync_vqsim_CFLAGS) $(CFLAGS) -MT corosync_vqsim-vqsim_vq_engine.obj -MD -MP -MF $(DEPDIR)/corosync_vqsim-vqsim_vq_engine.Tpo -c -o corosync_vqsim-vqsim_vq_engine.obj `if test -f 'vqsim_vq_engine.c'; then $(CYGPATH_W) 'vqsim_vq_engine.c'; else $(CYGPATH_W) '$(srcdir)/vqsim_vq_engine.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/corosync_vqsim-vqsim_vq_engine.Tpo $(DEPDIR)/corosync_vqsim-vqsim_vq_engine.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vqsim_vq_engine.c' object='corosync_vqsim-vqsim_vq_engine.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(corosync_vqsim_CFLAGS) $(CFLAGS) -c -o corosync_vqsim-vqsim_vq_engine.obj `if test -f 'vqsim_vq_engine.c'; then $(CYGPATH_W) 'vqsim_vq_engine.c'; else $(CYGPATH_W) '$(srcdir)/vqsim_vq_engine.c'; fi`
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(PROGRAMS) $(HEADERS)
+installdirs:
+ for dir in "$(DESTDIR)$(bindir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+ -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+clean: clean-am
+
+clean-am: clean-binPROGRAMS clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am: install-binPROGRAMS
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-binPROGRAMS
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean \
+ clean-binPROGRAMS clean-generic clean-libtool cscopelist-am \
+ ctags ctags-am distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-binPROGRAMS \
+ install-data install-data-am install-dvi install-dvi-am \
+ install-exec install-exec-am install-html install-html-am \
+ install-info install-info-am install-man install-pdf \
+ install-pdf-am install-ps install-ps-am install-strip \
+ installcheck installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags tags-am uninstall uninstall-am uninstall-binPROGRAMS
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/vqsim/parser.c b/vqsim/parser.c
new file mode 100644
index 0000000..2857184
--- /dev/null
+++ b/vqsim/parser.c
@@ -0,0 +1,418 @@
+/* Parses the interactive commands */
+
+#include <config.h>
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <netinet/in.h>
+#ifdef HAVE_READLINE_HISTORY_H
+#include <readline/history.h>
+#endif
+
+#include <corosync/coroapi.h>
+#include "vqsim.h"
+
+static void do_usage(void)
+{
+ printf(" All node IDs in the cluster are unique and belong to a numbered 'partition' (default=0)\n");
+ printf("\n");
+ printf("up [<partition>:][<nodeid>[,<nodeid>] ...] [[<partition>:][<nodeid>...]] [...]\n");
+ printf(" bring node(s) online in the specified partition(s)\n");
+ printf("down <nodeid>,[<nodeid>...]\n");
+ printf(" send nodes offline (shut them down)\n");
+ printf("move/split [<partition>:][<nodeid>[,<nodeid>] ...] [[<partition>:][<nodeid>...]] [...]\n");
+ printf(" Move nodes from one partition to another (netsplit)\n");
+ printf(" <partition> here is the partition to move the nodes to\n");
+ printf("join <partition> <partition> [<partition>] ... \n");
+ printf(" Join partitions together (reverse of a netsplit)\n");
+ printf("qdevice on|off [<partition>:][<nodeid>[,<nodeid>] ...] [[<partition>:][<nodeid>...]] [...]\n");
+ printf(" Enable quorum device in specified nodes\n");
+ printf("autofence on|off\n");
+ printf(" automatically 'down' nodes on inquorate side on netsplit\n");
+ printf("timeout <n> (default 250)\n");
+ printf(" Wait a maximum of <n> milli-seconds for the next command to complete.\n");
+ printf("sync on|off (default on)\n");
+ printf(" enable/disable synchronous execution of commands (wait for completion)\n");
+ printf("assert on|off (default off)\n");
+ printf(" Abort the simulation run if a timeout expires\n");
+ printf("show Show current nodes status\n");
+ printf("exit\n\n");
+}
+
+
+/* Commands return 0 if they return immediately, >1 if we are waiting for replies from nodes */
+typedef int (*cmd_routine_t)(int argc, char **argv);
+
+static int run_up_cmd(int argc, char **argv);
+static int run_down_cmd(int argc, char **argv);
+static int run_join_cmd(int argc, char **argv);
+static int run_move_cmd(int argc, char **argv);
+static int run_exit_cmd(int argc, char **argv);
+static int run_show_cmd(int argc, char **argv);
+static int run_timeout_cmd(int argc, char **argv);
+static int run_assert_cmd(int argc, char **argv);
+static int run_autofence_cmd(int argc, char **argv);
+static int run_qdevice_cmd(int argc, char **argv);
+static int run_sync_cmd(int argc, char **argv);
+
+static struct cmd_list_struct {
+ const char *cmd;
+ int min_args;
+ cmd_routine_t cmd_runner;
+} cmd_list[] = {
+ { "up", 1, run_up_cmd},
+ { "down", 1, run_down_cmd},
+ { "move", 2, run_move_cmd},
+ { "split", 2, run_move_cmd},
+ { "join", 2, run_join_cmd},
+ { "autofence", 1, run_autofence_cmd},
+ { "qdevice", 1, run_qdevice_cmd},
+ { "show", 0, run_show_cmd},
+ { "timeout", 1, run_timeout_cmd},
+ { "sync", 1, run_sync_cmd},
+ { "assert", 1, run_assert_cmd},
+ { "exit", 0, run_exit_cmd},
+ { "quit", 0, run_exit_cmd},
+ { "q", 0, run_exit_cmd},
+};
+static int num_cmds = (sizeof(cmd_list)) / sizeof(struct cmd_list_struct);
+#define MAX_ARGS 1024
+
+/* Takes a <partition>:[<node>[,<node>]...] list and return it
+ as a partition and a list of nodes.
+ Returns 0 if successful, -1 if not
+*/
+static int parse_partition_nodelist(char *string, int *partition, int *num_nodes, int **retnodes)
+{
+ int i;
+ int nodecount;
+ int len;
+ int last_comma;
+ char *nodeptr;
+ int *nodes;
+ char *colonptr = strchr(string, ':');
+
+ if (colonptr) {
+ *colonptr = '\0';
+ nodeptr = colonptr+1;
+ *partition = atoi(string);
+ }
+ else {
+ /* Default to partition 0 */
+ *partition = 0;
+ nodeptr = string;
+ }
+
+ /* Count the number of commas and allocate space for the nodes */
+ nodecount = 0;
+ for (i=0; i<strlen(nodeptr); i++) {
+ if (nodeptr[i] == ',') {
+ nodecount++;
+ }
+ }
+ nodecount++; /* The one between the last comma and the trailing NUL */
+ if (nodecount < 1 || nodecount > MAX_NODES) {
+ return -1;
+ }
+
+ nodes = malloc(sizeof(int) * nodecount);
+ if (!nodes) {
+ return -1;
+ }
+
+ nodecount = 0;
+ last_comma = 0;
+ len = strlen(nodeptr);
+ for (i=0; i<=len; i++) {
+ if (nodeptr[i] == ',' || nodeptr[i] == '\0') {
+
+ nodeptr[i] = '\0';
+ nodes[nodecount++] = atoi(&nodeptr[last_comma]);
+ last_comma = i+1;
+ }
+ }
+
+ *num_nodes = nodecount;
+ *retnodes = nodes;
+
+ return 0;
+}
+
+void parse_input_command(char *rl_cmd)
+{
+ int i;
+ int argc = 0;
+ int valid_cmd = 0;
+ char *argv[MAX_ARGS];
+ int last_arg_start = 0;
+ int last_was_space = 0;
+ int len;
+ int ret = 0;
+ char *cmd;
+
+ /* ^D quits */
+ if (rl_cmd == NULL) {
+ (void)run_exit_cmd(0, NULL);
+ }
+ /* '#' starts a comment */
+ if (rl_cmd[0] == '#') {
+ return;
+ }
+
+ cmd = strdup(rl_cmd);
+
+ /* Split cmd up into args
+ * destroying the original string mwahahahaha
+ */
+
+ len = strlen(cmd);
+
+ /* Span leading spaces */
+ for (i=0; cmd[i] == ' '; i++)
+ ;
+ last_arg_start = i;
+
+ for (; i<=len; i++) {
+ if (cmd[i] == ' ' || cmd[i] == '\0') {
+
+ /* Allow multiple spaces */
+ if (last_was_space) {
+ continue;
+ }
+
+ cmd[i] = '\0';
+ last_was_space = 1;
+
+ argv[argc] = &cmd[last_arg_start];
+ argc++;
+ }
+ else {
+ if (last_was_space) {
+ last_arg_start = i;
+ }
+ last_was_space = 0;
+ }
+ }
+
+ /* Ignore null commands */
+ if (argc < 1 || strlen(argv[0]) == 0) {
+ free(cmd);
+ resume_kb_input(0);
+ return;
+ }
+#ifdef HAVE_READLINE_HISTORY_H
+ add_history(rl_cmd);
+#endif
+
+ /* Dispatch command */
+ for (i=0; i<num_cmds; i++) {
+ if (strcasecmp(argv[0], cmd_list[i].cmd) == 0) {
+
+ if (argc < cmd_list[i].min_args) {
+ break;
+ }
+ ret = cmd_list[i].cmd_runner(argc, argv);
+ valid_cmd = 1;
+ }
+ }
+ if (!valid_cmd) {
+ do_usage();
+ }
+ free(cmd);
+
+ /* ret==0 means we can return immediately to command-line input */
+ if (ret == 0) {
+ resume_kb_input(ret);
+ }
+}
+
+
+
+static int run_up_cmd(int argc, char **argv)
+{
+ int partition;
+ int num_nodes;
+ int *nodelist;
+ int i,j;
+ int succeeded = 0;
+
+ if (argc <= 1) {
+ return 0;
+ }
+
+ cmd_start_sync_command();
+
+ for (i=1; i<argc; i++) {
+ if (parse_partition_nodelist(argv[i], &partition, &num_nodes, &nodelist) == 0) {
+ for (j=0; j<num_nodes; j++) {
+ if (!cmd_start_new_node(nodelist[j], partition)) {
+ succeeded++;
+ }
+ }
+ free(nodelist);
+ }
+ }
+ return succeeded;
+}
+
+static int run_down_cmd(int argc, char **argv)
+{
+ int nodeid;
+ int i;
+ int succeeded = 0;
+
+ cmd_start_sync_command();
+
+ for (i=1; i<argc; i++) {
+ nodeid = atoi(argv[1]);
+ if (!cmd_stop_node(nodeid)) {
+ succeeded++;
+ }
+ }
+ return succeeded;
+}
+
+static int run_join_cmd(int argc, char **argv)
+{
+ int i;
+
+ if (argc < 2) {
+ printf("join needs at least two partition numbers\n");
+ return 0;
+ }
+
+ cmd_start_sync_command();
+
+ for (i=2; i<argc; i++) {
+ cmd_join_partitions(atoi(argv[1]), atoi(argv[i]));
+ }
+ cmd_update_all_partitions(1);
+ return 1;
+}
+
+static int run_move_cmd(int argc, char **argv)
+{
+ int i;
+ int partition;
+ int num_nodes;
+ int *nodelist;
+
+ cmd_start_sync_command();
+
+ for (i=1; i<argc; i++) {
+ if (parse_partition_nodelist(argv[i], &partition, &num_nodes, &nodelist) == 0) {
+ cmd_move_nodes(partition, num_nodes, nodelist);
+ free(nodelist);
+ }
+ }
+ cmd_update_all_partitions(1);
+ return 1;
+}
+
+static int run_autofence_cmd(int argc, char **argv)
+{
+ int onoff = -1;
+
+ if (strcasecmp(argv[1], "on") == 0) {
+ onoff = 1;
+ }
+ if (strcasecmp(argv[1], "off") == 0) {
+ onoff = 0;
+ }
+ if (onoff == -1) {
+ fprintf(stderr, "ERR: autofence value must be 'on' or 'off'\n");
+ }
+ else {
+ cmd_set_autofence(onoff);
+ }
+ return 0;
+}
+
+static int run_qdevice_cmd(int argc, char **argv)
+{
+ int i,j;
+ int partition;
+ int num_nodes;
+ int *nodelist;
+ int onoff = -1;
+
+ if (strcasecmp(argv[1], "on") == 0) {
+ onoff = 1;
+ }
+ if (strcasecmp(argv[1], "off") == 0) {
+ onoff = 0;
+ }
+
+ if (onoff == -1) {
+ fprintf(stderr, "ERR: qdevice should be 'on' or 'off'\n");
+ return 0;
+ }
+
+ for (i=2; i<argc; i++) {
+ if (parse_partition_nodelist(argv[i], &partition, &num_nodes, &nodelist) == 0) {
+ for (j=0; j<num_nodes; j++) {
+ cmd_qdevice_poll(nodelist[j], onoff);
+ }
+ free(nodelist);
+ }
+ }
+ cmd_update_all_partitions(0);
+ return 0;
+}
+
+static int run_show_cmd(int argc, char **argv)
+{
+ cmd_show_node_states();
+ return 0;
+}
+
+static int run_timeout_cmd(int argc, char **argv)
+{
+ cmd_set_timeout(atol(argv[1]));
+ return 0;
+}
+
+static int run_sync_cmd(int argc, char **argv)
+{
+ int onoff = -1;
+
+ if (strcasecmp(argv[1], "on") == 0) {
+ onoff = 1;
+ }
+ if (strcasecmp(argv[1], "off") == 0) {
+ onoff = 0;
+ }
+ if (onoff == -1) {
+ fprintf(stderr, "ERR: sync value must be 'on' or 'off'\n");
+ }
+ else {
+ cmd_set_sync(onoff);
+ }
+ return 0;
+}
+
+static int run_assert_cmd(int argc, char **argv)
+{
+ int onoff = -1;
+
+ if (strcasecmp(argv[1], "on") == 0) {
+ onoff = 1;
+ }
+ if (strcasecmp(argv[1], "off") == 0) {
+ onoff = 0;
+ }
+ if (onoff == -1) {
+ fprintf(stderr, "ERR: assert value must be 'on' or 'off'\n");
+ }
+ else {
+ cmd_set_assert(onoff);
+ }
+ return 0;
+}
+
+static int run_exit_cmd(int argc, char **argv)
+{
+ cmd_stop_all_nodes();
+ exit(0);
+}
diff --git a/vqsim/vq_object.c b/vqsim/vq_object.c
new file mode 100644
index 0000000..d832e10
--- /dev/null
+++ b/vqsim/vq_object.c
@@ -0,0 +1,121 @@
+/*
+ This is a Votequorum object in the parent process. it's really just a conduit for the forked
+ votequorum entity
+*/
+
+#include <qb/qblog.h>
+#include <qb/qbloop.h>
+#include <qb/qbipcc.h>
+#include <netinet/in.h>
+
+#include "../exec/votequorum.h"
+#include "vqsim.h"
+
+struct vq_instance
+{
+ int nodeid;
+ int vq_socket;
+ pid_t pid;
+};
+
+vq_object_t vq_create_instance(qb_loop_t *poll_loop, int nodeid)
+{
+ struct vq_instance *instance = malloc(sizeof(struct vq_instance));
+ if (!instance) {
+ return NULL;
+ }
+
+ instance->nodeid = nodeid;
+
+ if (fork_new_instance(nodeid, &instance->vq_socket, &instance->pid)) {
+ free(instance);
+ return NULL;
+ }
+
+ return instance;
+}
+
+pid_t vq_get_pid(vq_object_t instance)
+{
+ struct vq_instance *vqi = instance;
+ return vqi->pid;
+}
+
+void vq_quit(vq_object_t instance)
+{
+ struct vq_instance *vqi = instance;
+ struct vqsim_msg_header msg;
+ int res;
+
+ msg.type = VQMSG_QUIT;
+ msg.from_nodeid = 0;
+ msg.param = 0;
+
+ res = write(vqi->vq_socket, &msg, sizeof(msg));
+ if (res <= 0) {
+ perror("Quit write failed");
+ }
+}
+
+int vq_quit_if_inquorate(vq_object_t instance)
+{
+ struct vq_instance *vqi = instance;
+ struct vqsim_msg_header msg;
+ int res;
+
+ msg.type = VQMSG_QUORUMQUIT;
+ msg.from_nodeid = 0;
+ msg.param = 0;
+
+ res = write(vqi->vq_socket, &msg, sizeof(msg));
+ if (res <= 0) {
+ perror("Quit write failed");
+ }
+ return 0;
+}
+
+int vq_set_nodelist(vq_object_t instance, struct memb_ring_id *ring_id, int *nodeids, int nodeids_entries)
+{
+ struct vq_instance *vqi = instance;
+ char msgbuf[sizeof(int)*nodeids_entries + sizeof(struct vqsim_sync_msg)];
+ struct vqsim_sync_msg *msg = (void*)msgbuf;
+ int res;
+
+ msg->header.type = VQMSG_SYNC;
+ msg->header.from_nodeid = 0;
+ msg->header.param = 0;
+ msg->view_list_entries = nodeids_entries;
+ memcpy(&msg->view_list, nodeids, nodeids_entries*sizeof(int));
+ memcpy(&msg->ring_id, ring_id, sizeof(struct memb_ring_id));
+
+ res = write(vqi->vq_socket, msgbuf, sizeof(msgbuf));
+ if (res <= 0) {
+ perror("Sync write failed");
+ return -1;
+ }
+ return 0;
+}
+
+int vq_set_qdevice(vq_object_t instance, struct memb_ring_id *ring_id, int onoff)
+{
+ struct vq_instance *vqi = instance;
+ struct vqsim_msg_header msg;
+ int res;
+
+ msg.type = VQMSG_QDEVICE;
+ msg.from_nodeid = 0;
+ msg.param = onoff;
+ res = write(vqi->vq_socket, &msg, sizeof(msg));
+ if (res <= 0) {
+ perror("qdevice register write failed");
+ return -1;
+ }
+ return 0;
+}
+
+int vq_get_parent_fd(vq_object_t instance)
+{
+ struct vq_instance *vqi = instance;
+
+ return vqi->vq_socket;
+}
diff --git a/vqsim/vqmain.c b/vqsim/vqmain.c
new file mode 100644
index 0000000..8e5f0e3
--- /dev/null
+++ b/vqsim/vqmain.c
@@ -0,0 +1,854 @@
+#include <config.h>
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <qb/qblog.h>
+#include <qb/qbloop.h>
+#include <sys/poll.h>
+#include <netinet/in.h>
+#include <sys/queue.h>
+#ifdef HAVE_READLINE_READLINE_H
+#include <readline/readline.h>
+#else
+#include <unistd.h> /* isatty */
+#endif
+
+#include "../exec/votequorum.h"
+#include "../exec/service.h"
+#include <corosync/logsys.h>
+#include <corosync/coroapi.h>
+
+#include "icmap.h"
+#include "vqsim.h"
+
+/* Easier than including the config file with a ton of conflicting dependencies */
+extern int coroparse_configparse (icmap_map_t config_map, const char **error_string);
+extern int corosync_log_config_read (const char **error_string);
+static int stdin_read_fn(int32_t fd, int32_t revents, void *data);
+void totemknet_configure_log_level(void);
+
+/* 'Keep the compiler happy' time */
+const char *corosync_get_config_file(void);
+
+/* One of these per partition */
+struct vq_partition {
+ TAILQ_HEAD(, vq_node) nodelist;
+ struct memb_ring_id ring_id;
+ int num;
+};
+
+/* One of these per node */
+struct vq_node {
+ vq_object_t instance;
+ unsigned int nodeid;
+ int fd;
+ struct vq_partition *partition;
+ TAILQ_ENTRY(vq_node) entries;
+
+ /* Last status */
+ int last_quorate;
+ struct memb_ring_id last_ring_id;
+ int last_view_list[MAX_NODES];
+ int last_view_list_entries;
+};
+
+static struct vq_partition partitions[MAX_PARTITIONS];
+static qb_loop_t *poll_loop;
+static int autofence;
+static int check_for_quorum;
+static FILE *output_file;
+static int sync_cmds = 1;
+static qb_loop_timer_handle kb_timer;
+static int waiting_for_sync = 0;
+static int is_tty;
+static int assert_on_timeout;
+static uint64_t command_timeout = 250000000L;
+
+static struct vq_node *find_by_pid(pid_t pid);
+static void send_partition_to_nodes(struct vq_partition *partition, int newring);
+static void start_kb_input_timeout(void *data);
+static void finish_wait_timeout(void *data);
+
+#ifndef HAVE_READLINE_READLINE_H
+#define INPUT_BUF_SIZE 1024
+static char input_buf[INPUT_BUF_SIZE];
+static size_t input_buf_term = 0;
+#endif
+
+/* 'Keep the compiler happy' time */
+static char corosync_config_file[PATH_MAX + 1] = COROSYSCONFDIR "/corosync.conf";
+
+const char *corosync_get_config_file(void)
+{
+ return (corosync_config_file);
+}
+
+/* Tell all non-quorate nodes to quit */
+static void force_fence(void)
+{
+ int i;
+ struct vq_node *vqn;
+
+ for (i=0; i<MAX_PARTITIONS; i++) {
+ TAILQ_FOREACH(vqn, &partitions[i].nodelist, entries) {
+ vq_quit_if_inquorate(vqn->instance);
+ }
+ }
+}
+
+/* Save quorum state from the incoming message */
+static void save_quorum_state(struct vq_node *node, struct vqsim_quorum_msg *qmsg)
+{
+ node->last_quorate = qmsg->quorate;
+ memcpy(&node->last_ring_id, &qmsg->ring_id, sizeof(struct memb_ring_id));
+ memcpy(node->last_view_list, qmsg->view_list, sizeof(int) * qmsg->view_list_entries);
+ node->last_view_list_entries = qmsg->view_list_entries;
+
+ /* If at least one node is quorate and autofence is enabled, then fence everyone who is not quorate */
+ if (check_for_quorum && qmsg->quorate & autofence) {
+ check_for_quorum = 0;
+ force_fence();
+ }
+}
+
+/* Print current node state */
+static void print_quorum_state(struct vq_node *node)
+{
+ int i;
+
+ if (node->last_quorate < 0) {
+ fprintf(output_file, "%d:" CS_PRI_NODE_ID ": q=UNINITIALIZED\n",
+ node->partition->num, node->nodeid);
+ return;
+ }
+
+ fprintf(output_file, "%d:" CS_PRI_NODE_ID ": q=%d ring=[" CS_PRI_RING_ID "] ", node->partition->num, node->nodeid, node->last_quorate,
+ node->last_ring_id.nodeid, (uint64_t)node->last_ring_id.seq);
+ fprintf(output_file, "nodes=[");
+ for (i = 0; i < node->last_view_list_entries; i++) {
+ if (i) {
+ fprintf(output_file, " ");
+ }
+ fprintf(output_file, CS_PRI_NODE_ID, node->last_view_list[i]);
+ }
+ fprintf(output_file, "]\n");
+
+}
+
+static void propogate_vq_message(struct vq_node *vqn, const char *msg, int len)
+{
+ struct vq_node *other_vqn;
+ ssize_t write_res;
+
+ /* Send it to everyone in that node's partition (including itself) */
+ TAILQ_FOREACH(other_vqn, &vqn->partition->nodelist, entries) {
+ write_res = write(other_vqn->fd, msg, len);
+ /*
+ * Read counterpart is not ready for receiving non-complete message so
+ * ensure all required information was send.
+ */
+ assert(write_res == len);
+ }
+}
+
+
+static void cmd_show_prompt_if_needed(void)
+{
+ qb_loop_timer_del(poll_loop, kb_timer);
+ if (is_tty) {
+ printf("vqsim> ");
+ fflush(stdout);
+ } else {
+ printf("#vqsim> ");
+ fflush(stdout);
+ }
+
+}
+
+void resume_kb_input(int show_status)
+{
+ /* If running synchronously, we don't display
+ the quorum messages as they come in. So run 'show' commamnd
+ */
+ if (show_status && waiting_for_sync) {
+ cmd_show_node_states();
+ }
+
+ waiting_for_sync = 0;
+
+ if (qb_loop_poll_add(poll_loop,
+ QB_LOOP_MED,
+ STDIN_FILENO,
+ POLLIN | POLLERR,
+ NULL,
+ stdin_read_fn)) {
+ if (errno != EEXIST) {
+ perror("qb_loop_poll_add1 returned error");
+ }
+ }
+ /* Always shows the prompt here, cos we cleared waiting_for_sync */
+ cmd_show_prompt_if_needed();
+}
+
+/* Return true (1) if all nodes in each partition have the same ring id, false(0) otherwise */
+static int all_nodes_consistent(void)
+{
+ int i;
+ struct vq_node *vqn;
+ struct memb_ring_id last_ring_id;
+
+ for (i=0; i<MAX_PARTITIONS; i++) {
+ memset(&last_ring_id, 0, sizeof(last_ring_id));
+ TAILQ_FOREACH(vqn, &partitions[i].nodelist, entries) {
+ if (last_ring_id.seq &&
+ last_ring_id.seq != vqn->last_ring_id.seq) {
+ return 0;
+ }
+ last_ring_id.seq = vqn->last_ring_id.seq;
+ }
+ }
+ return 1;
+}
+
+static int vq_parent_read_fn(int32_t fd, int32_t revents, void *data)
+{
+ char msgbuf[8192];
+ int msglen;
+ struct vqsim_msg_header *msg;
+ struct vqsim_quorum_msg *qmsg;
+ struct vq_node *vqn = data;
+
+ if (revents == POLLIN) {
+ msglen = read(fd, msgbuf, sizeof(msgbuf));
+ if (msglen < 0) {
+ perror("read failed");
+ } else if (msglen < sizeof(*msg)) {
+ fprintf(stderr, "Received message is too short\n");
+ } else {
+ msg = (void*)msgbuf;
+ switch (msg->type) {
+ case VQMSG_QUORUM:
+ qmsg = (void*)msgbuf;
+ /*
+ * Check length of message.
+ * SOCK_SEQPACKET is used so this check is not strictly needed.
+ */
+ if (msglen < sizeof(*qmsg) ||
+ qmsg->view_list_entries > MAX_NODES ||
+ msglen < sizeof(*qmsg) + sizeof(qmsg->view_list[0]) * qmsg->view_list_entries) {
+ fprintf(stderr, "Received quorum message is too short or corrupted\n");
+ return (0);
+ }
+ save_quorum_state(vqn, qmsg);
+ if (!sync_cmds) {
+ print_quorum_state(vqn);
+ }
+
+ /* Have the partitions stabilised? */
+ if (sync_cmds && waiting_for_sync &&
+ all_nodes_consistent()) {
+ qb_loop_timer_del(poll_loop, kb_timer);
+ resume_kb_input(sync_cmds);
+ }
+ break;
+ case VQMSG_EXEC:
+ /* Message from votequorum, pass around the partition */
+ propogate_vq_message(vqn, msgbuf, msglen);
+ break;
+ case VQMSG_QUIT:
+ case VQMSG_SYNC:
+ case VQMSG_QDEVICE:
+ case VQMSG_QUORUMQUIT:
+ /* not used here */
+ break;
+ }
+ }
+ }
+ if (revents == POLLERR) {
+ fprintf(stderr, "pollerr on " CS_PRI_NODE_ID "\n", vqn->nodeid);
+ }
+ return 0;
+}
+
+/* Dummy routine to keep the linker happy */
+void totemknet_configure_log_level(void)
+{
+
+}
+
+static int read_corosync_conf(void)
+{
+ int res;
+ const char *error_string;
+
+ int err = icmap_init();
+ if (!err) {
+ fprintf(stderr, "icmap_init failed\n");
+ }
+
+ /* Load corosync.conf */
+ logsys_format_set(NULL);
+ res = coroparse_configparse(icmap_get_global_map(), &error_string);
+ if (res == -1) {
+ log_printf (LOGSYS_LEVEL_INFO, "Error loading corosync.conf %s", error_string);
+ return -1;
+ }
+ else {
+ res = corosync_log_config_read (&error_string);
+ if (res < 0) {
+ log_printf (LOGSYS_LEVEL_INFO, "error reading log config %s", error_string);
+ syslog (LOGSYS_LEVEL_INFO, "error reading log config %s", error_string);
+ }
+ else {
+ logsys_config_apply();
+ }
+ }
+ if (logsys_thread_start() != 0) {
+ log_printf (LOGSYS_LEVEL_ERROR, "Can't initialize log thread");
+ return -1;
+ }
+
+ return 0;
+}
+
+static void remove_node(struct vq_node *node)
+{
+ struct vq_partition *part;
+ part = node->partition;
+
+ /* Remove from partition list */
+ TAILQ_REMOVE(&part->nodelist, node, entries);
+ free(node);
+
+ /* Rebuild quorum */
+ send_partition_to_nodes(part, 1);
+}
+
+static int32_t sigchld_handler(int32_t sig, void *data)
+{
+ pid_t pid;
+ int status;
+ struct vq_node *vqn;
+ const char *exit_status="";
+ char text[132];
+
+ pid = wait(&status);
+ if (WIFEXITED(status)) {
+ vqn = find_by_pid(pid);
+ if (vqn) {
+ switch (WEXITSTATUS(status)) {
+ case 0:
+ exit_status = "(on request)";
+ break;
+ case 1:
+ exit_status = "(autofenced)";
+ break;
+ default:
+ sprintf(text, "(exit code %d)", WEXITSTATUS(status));
+ break;
+ }
+ printf("%d:" CS_PRI_NODE_ID ": Quit %s\n", vqn->partition->num, vqn->nodeid, exit_status);
+
+ remove_node(vqn);
+ }
+ else {
+ fprintf(stderr, "Unknown child %d exited with status %d\n", pid, WEXITSTATUS(status));
+ }
+ }
+ if (WIFSIGNALED(status)) {
+ vqn = find_by_pid(pid);
+ if (vqn) {
+ printf("%d:" CS_PRI_NODE_ID " exited on signal %d%s\n", vqn->partition->num, vqn->nodeid, WTERMSIG(status), WCOREDUMP(status)?" (core dumped)":"");
+ remove_node(vqn);
+ }
+ else {
+ fprintf(stderr, "Unknown child %d exited with status %d%s\n", pid, WTERMSIG(status), WCOREDUMP(status)?" (core dumped)":"");
+ }
+ }
+ return 0;
+}
+
+static void send_partition_to_nodes(struct vq_partition *partition, int newring)
+{
+ struct vq_node *vqn;
+ int nodelist[MAX_NODES];
+ int nodes = 0;
+ int first = 1;
+
+ if (newring) {
+ /* Simulate corosync incrementing the seq by 4 for added authenticity */
+ partition->ring_id.seq += 4;
+ }
+
+ /* Build the node list */
+ TAILQ_FOREACH(vqn, &partition->nodelist, entries) {
+ nodelist[nodes++] = vqn->nodeid;
+ if (first) {
+ partition->ring_id.nodeid = vqn->nodeid;
+ first = 0;
+ }
+ }
+
+ TAILQ_FOREACH(vqn, &partition->nodelist, entries) {
+ vq_set_nodelist(vqn->instance, &partition->ring_id, nodelist, nodes);
+ }
+}
+
+static void init_partitions(void)
+{
+ int i;
+
+ for (i=0; i<MAX_PARTITIONS; i++) {
+ TAILQ_INIT(&partitions[i].nodelist);
+ partitions[i].ring_id.nodeid = 1000+i;
+ partitions[i].ring_id.seq = 0;
+ partitions[i].num = i;
+ }
+}
+
+static pid_t create_node(int nodeid, int partno)
+{
+ struct vq_node *newvq;
+
+ newvq = malloc(sizeof(struct vq_node));
+ if (newvq) {
+ newvq->last_quorate = -1; /* mark "uninitialized" */
+ newvq->instance = vq_create_instance(poll_loop, nodeid);
+ if (!newvq->instance) {
+ fprintf(stderr,
+ "ERR: could not create vq instance nodeid " CS_PRI_NODE_ID "\n",
+ nodeid);
+ free(newvq);
+ return (pid_t) -1;
+ }
+ newvq->partition = &partitions[partno];
+ newvq->nodeid = nodeid;
+ newvq->fd = vq_get_parent_fd(newvq->instance);
+ TAILQ_INSERT_TAIL(&partitions[partno].nodelist, newvq, entries);
+
+ if (qb_loop_poll_add(poll_loop,
+ QB_LOOP_MED,
+ newvq->fd,
+ POLLIN | POLLERR,
+ newvq,
+ vq_parent_read_fn)) {
+ perror("qb_loop_poll_add returned error");
+ return (pid_t) -1;
+ }
+
+ /* Send sync with all the nodes so far in it. */
+ send_partition_to_nodes(&partitions[partno], 1);
+ return vq_get_pid(newvq->instance);
+ }
+ return (pid_t) -1;
+}
+
+static size_t create_nodes_from_config(void)
+{
+ icmap_iter_t iter;
+ char tmp_key[ICMAP_KEYNAME_MAXLEN];
+ uint32_t node_pos;
+ uint32_t nodeid;
+ const char *iter_key;
+ int res;
+ pid_t pid;
+ size_t ret = 0;
+
+ init_partitions();
+
+ iter = icmap_iter_init("nodelist.node.");
+ while ((iter_key = icmap_iter_next(iter, NULL, NULL)) != NULL) {
+ res = sscanf(iter_key, "nodelist.node.%u.%s", &node_pos, tmp_key);
+ if (res != 2) {
+ continue;
+ }
+
+ if (strcmp(tmp_key, "ring0_addr") != 0) {
+ continue;
+ }
+
+ snprintf(tmp_key, ICMAP_KEYNAME_MAXLEN, "nodelist.node.%u.nodeid", node_pos);
+ if (icmap_get_uint32(tmp_key, &nodeid) == CS_OK) {
+ pid = create_node(nodeid, 0);
+ if (pid == (pid_t) -1) {
+ fprintf(stderr,
+ "ERR: nodeid " CS_PRI_NODE_ID " could not be spawned\n",
+ nodeid);
+ exit(1);
+ }
+ ret++;
+ }
+
+ }
+ icmap_iter_finalize(iter);
+
+ return ret;
+}
+
+static struct vq_node *find_node(int nodeid)
+{
+ int i;
+ struct vq_node *vqn;
+
+ for (i=0; i<MAX_PARTITIONS; i++) {
+ TAILQ_FOREACH(vqn, &partitions[i].nodelist, entries) {
+ if (vqn->nodeid == nodeid) {
+ return vqn;
+ }
+ }
+ }
+ return NULL;
+}
+
+static struct vq_node *find_by_pid(pid_t pid)
+{
+ int i;
+ struct vq_node *vqn;
+
+ for (i=0; i<MAX_PARTITIONS; i++) {
+ TAILQ_FOREACH(vqn, &partitions[i].nodelist, entries) {
+ if (vq_get_pid(vqn->instance) == pid) {
+ return vqn;
+ }
+ }
+ }
+ return NULL;
+}
+
+/* Routines called from the parser */
+
+
+/*
+ * The parser calls this before running a command where
+ * we might have to wait for a result to come back.
+ */
+void cmd_start_sync_command()
+{
+ if (sync_cmds) {
+ qb_loop_poll_del(poll_loop, STDIN_FILENO);
+ qb_loop_timer_add(poll_loop,
+ QB_LOOP_MED,
+ command_timeout,
+ NULL,
+ finish_wait_timeout,
+ &kb_timer);
+ waiting_for_sync = 1;
+ }
+}
+
+int cmd_start_new_node(int nodeid, int partition)
+{
+ struct vq_node *node;
+
+ node = find_node(nodeid);
+ if (node) {
+ fprintf(stderr, "ERR: nodeid " CS_PRI_NODE_ID " already exists in partition %d\n", nodeid, node->partition->num);
+ return -1;
+ }
+ if (create_node(nodeid, partition) == -1) {
+ return -1;
+ }
+ return 0;
+}
+
+void cmd_stop_all_nodes()
+{
+ int i;
+ struct vq_node *vqn;
+
+ for (i=0; i<MAX_PARTITIONS; i++) {
+ TAILQ_FOREACH(vqn, &partitions[i].nodelist, entries) {
+ vq_quit(vqn->instance);
+ }
+ }
+}
+
+void cmd_show_node_states()
+{
+ int i;
+ struct vq_node *vqn;
+
+ for (i=0; i<MAX_PARTITIONS; i++) {
+ TAILQ_FOREACH(vqn, &partitions[i].nodelist, entries) {
+ print_quorum_state(vqn);
+ }
+ }
+ fprintf(output_file, "#autofence: %s\n", autofence?"on":"off");
+}
+
+int cmd_stop_node(int nodeid)
+{
+ struct vq_node *node;
+
+ node = find_node(nodeid);
+ if (!node) {
+ fprintf(stderr, "ERR: nodeid " CS_PRI_NODE_ID " is not up\n", nodeid);
+ return -1;
+ }
+
+ /* Remove processor */
+ vq_quit(node->instance);
+
+ /* Node will be removed when the child process exits */
+ return 0;
+}
+
+/* Move all nodes in 'nodelist' into partition 'partition' */
+void cmd_move_nodes(int partition, int num_nodes, int *nodelist)
+{
+ int i;
+ struct vq_node *node;
+ struct vq_node *vqn;
+ int total_nodes = num_nodes;
+
+ /* Work out the number of nodes affected */
+ TAILQ_FOREACH(vqn, &partitions[partition].nodelist, entries) {
+ total_nodes++;
+ }
+
+ for (i=0; i<num_nodes; i++) {
+ node = find_node(nodelist[i]);
+ if (node) {
+
+ /* Remove it from the current partition */
+ TAILQ_REMOVE(&node->partition->nodelist, node, entries);
+
+ /* Add it to the new partition */
+ TAILQ_INSERT_TAIL(&partitions[partition].nodelist, node, entries);
+ node->partition = &partitions[partition];
+ }
+ else {
+ printf("ERR: node " CS_PRI_NODE_ID " does not exist\n", nodelist[i]);
+ }
+ }
+}
+
+/* Take all the nodes in part2 and join them to part1 */
+void cmd_join_partitions(int part1, int part2)
+{
+ struct vq_node *vqn;
+
+ while (!TAILQ_EMPTY(&partitions[part2].nodelist)) {
+ vqn = TAILQ_FIRST(&partitions[part2].nodelist);
+ TAILQ_REMOVE(&vqn->partition->nodelist, vqn, entries);
+ TAILQ_INSERT_TAIL(&partitions[part1].nodelist, vqn, entries);
+ vqn->partition = &partitions[part1];
+ }
+}
+
+void cmd_set_autofence(int onoff)
+{
+ autofence = onoff;
+ fprintf(output_file, "#autofence: %s\n", onoff?"on":"off");
+}
+
+void cmd_set_sync(int onoff)
+{
+ autofence = onoff;
+ fprintf(output_file, "#sync: %s\n", onoff?"on":"off");
+ sync_cmds = onoff;
+}
+
+void cmd_set_assert(int onoff)
+{
+ assert_on_timeout = onoff;
+}
+
+void cmd_update_all_partitions(int newring)
+{
+ int i;
+
+ check_for_quorum = 1;
+ for (i=0; i<MAX_PARTITIONS; i++) {
+ send_partition_to_nodes(&partitions[i], newring);
+ }
+}
+
+void cmd_qdevice_poll(int nodeid, int onoff)
+{
+ struct vq_node *node;
+
+ node = find_node(nodeid);
+ if (node) {
+ vq_set_qdevice(node->instance, &node->partition->ring_id, onoff);
+ }
+}
+
+/* If we get called then a command has timed-out */
+static void finish_wait_timeout(void *data)
+{
+ if (command_timeout) {
+ fprintf(stderr, "ERR: Partition(s) not stable within timeout\n");
+ if (assert_on_timeout) {
+ exit(2);
+ }
+ }
+
+ resume_kb_input(sync_cmds);
+}
+
+void cmd_set_timeout(uint64_t seconds)
+{
+ command_timeout = seconds * QB_TIME_NS_IN_MSEC;
+}
+
+/* ---------------------------------- */
+
+#ifndef HAVE_READLINE_READLINE_H
+static void dummy_read_char(void);
+
+static void dummy_read_char()
+{
+ int c, flush = 0;
+
+ while (!flush) {
+ c = getchar();
+ if (++input_buf_term >= INPUT_BUF_SIZE) {
+ if (c != '\n' && c != EOF)
+ fprintf(stderr, "User input overflows the limit: %zu\n",
+ (size_t) INPUT_BUF_SIZE);
+ input_buf[INPUT_BUF_SIZE - 1] = '\0';
+ flush = 1;
+ } else if (c == '\n' || c == EOF) {
+ input_buf[input_buf_term - 1] = '\0';
+ flush = 1;
+ } else {
+ input_buf[input_buf_term - 1] = c;
+ }
+ }
+
+ parse_input_command((c == EOF) ? NULL : input_buf);
+ input_buf_term = 0;
+}
+#endif
+
+static int stdin_read_fn(int32_t fd, int32_t revents, void *data)
+{
+#ifdef HAVE_READLINE_READLINE_H
+ /* Send it to readline */
+ rl_callback_read_char();
+#else
+ dummy_read_char();
+#endif
+ return 0;
+}
+
+
+static void start_kb_input_timeout(void *data)
+{
+ resume_kb_input(1);
+}
+
+static void usage(char *program)
+{
+ printf("Usage:\n");
+ printf("\n");
+ printf("%s [-c <config-file>] [-o <output-file>]\n", program);
+ printf("\n");
+ printf(" -c config file. defaults to /etc/corosync/corosync.conf\n");
+ printf(" -o output file. defaults to stdout\n");
+ printf(" -n no synchronization (on adding a node)\n");
+ printf(" -h display this help text\n");
+ printf("\n");
+ printf("%s always takes input from STDIN, but cannot use a file.\n", program);
+ printf("If you want to script it then use\n cat | %s\n", program);
+ printf("\n");
+}
+
+int main(int argc, char **argv)
+{
+ qb_loop_signal_handle sigchld_qb_handle;
+ int ch;
+ char *output_file_name = NULL;
+
+ while ((ch = getopt (argc, argv, "c:o:nh")) != EOF) {
+ switch (ch) {
+ case 'c':
+ if (strlen(optarg) >= sizeof(sizeof(corosync_config_file) - 1)) {
+ fprintf(stderr, "Corosync config file path too long\n");
+ exit(1);
+ }
+ strncpy(corosync_config_file, optarg, sizeof(corosync_config_file) - 1);
+ break;
+ case 'o':
+ output_file_name = optarg;
+ break;
+ case 'n':
+ sync_cmds = 0;
+ break;
+ default:
+ usage(argv[0]);
+ exit(0);
+ }
+ }
+
+ if (output_file_name) {
+ output_file = fopen(output_file_name, "w");
+ if (!output_file) {
+ fprintf(stderr, "Unable to open %s for output: %s\n", output_file_name, strerror(errno));
+ exit(3);
+ }
+ }
+ else {
+ output_file = stdout;
+ }
+
+ is_tty = isatty(STDIN_FILENO);
+
+ qb_log_filter_ctl(QB_LOG_SYSLOG, QB_LOG_FILTER_ADD,
+ QB_LOG_FILTER_FUNCTION, "*", LOG_DEBUG);
+
+ qb_log_ctl(QB_LOG_STDERR, QB_LOG_CONF_ENABLED, QB_TRUE);
+ qb_log_filter_ctl(QB_LOG_STDERR, QB_LOG_FILTER_ADD,
+ QB_LOG_FILTER_FUNCTION, "*", LOG_DEBUG);
+
+ poll_loop = qb_loop_create();
+
+ /* SIGCHLD handler to reap sub-processes and reconfigure the cluster */
+ qb_loop_signal_add(poll_loop,
+ QB_LOOP_MED,
+ SIGCHLD,
+ NULL,
+ sigchld_handler,
+ &sigchld_qb_handle);
+
+
+#ifdef HAVE_READLINE_READLINE_H
+ /* Readline will deal with completed lines when they arrive */
+ /*
+ * For scripting add '#' to the start of the prompt so that
+ * parsers can ignore input lines
+ */
+ rl_already_prompted = 1;
+ if (is_tty) {
+ rl_callback_handler_install("vqsim> ", parse_input_command);
+ } else {
+ rl_callback_handler_install("#vqsim> ", parse_input_command);
+ }
+#endif
+
+
+
+/* Create a full cluster of nodes from corosync.conf */
+ read_corosync_conf();
+ if (create_nodes_from_config() && sync_cmds) {
+ /* Delay kb input handling by 1 second when we've just
+ added the nodes from corosync.conf; expect that
+ the delay will be cancelled substantially earlier
+ once they all have reported their quorum info
+ (the delay is in fact a failsafe input enabler here) */
+ qb_loop_timer_add(poll_loop,
+ QB_LOOP_MED,
+ 1000000000,
+ NULL,
+ start_kb_input_timeout,
+ &kb_timer);
+ waiting_for_sync = 1;
+ } else {
+ resume_kb_input(0);
+ }
+
+ qb_loop_run(poll_loop);
+ return 0;
+}
diff --git a/vqsim/vqsim.h b/vqsim/vqsim.h
new file mode 100644
index 0000000..0c4c973
--- /dev/null
+++ b/vqsim/vqsim.h
@@ -0,0 +1,82 @@
+
+typedef enum {VQMSG_QUIT=1,
+ VQMSG_SYNC, /* set nodelist */
+ VQMSG_QUORUM, /* quorum state of this 'node' */
+ VQMSG_EXEC, /* message for exec_handler */
+ VQMSG_QDEVICE, /* quorum device enable/disable */
+ VQMSG_QUORUMQUIT, /* quit if you don't have quorum */
+} vqsim_msg_type_t;
+
+typedef struct vq_instance *vq_object_t;
+
+struct vqsim_msg_header
+{
+ vqsim_msg_type_t type;
+ int from_nodeid;
+ int param;
+};
+
+/* This is the sync sent from the controller process */
+struct vqsim_sync_msg
+{
+ struct vqsim_msg_header header;
+ struct memb_ring_id ring_id;
+ size_t view_list_entries;
+ unsigned int view_list[];
+};
+
+/* This is just info sent from each VQ instance */
+struct vqsim_quorum_msg
+{
+ struct vqsim_msg_header header;
+ int quorate;
+ struct memb_ring_id ring_id;
+ size_t view_list_entries;
+ unsigned int view_list[];
+};
+
+struct vqsim_exec_msg
+{
+ struct vqsim_msg_header header;
+ char execmsg[];
+};
+
+struct vqsim_lib_msg
+{
+ struct vqsim_msg_header header;
+ char libmsg[];
+};
+
+#define MAX_NODES 1024
+#define MAX_PARTITIONS 16
+
+/* In vq_object.c */
+vq_object_t vq_create_instance(qb_loop_t *poll_loop, int nodeid);
+void vq_quit(vq_object_t instance);
+int vq_set_nodelist(vq_object_t instance, struct memb_ring_id *ring_id, int *nodeids, int nodeids_entries);
+int vq_get_parent_fd(vq_object_t instance);
+int vq_set_qdevice(vq_object_t instance, struct memb_ring_id *ring_id, int onoff);
+int vq_quit_if_inquorate(vq_object_t instance);
+pid_t vq_get_pid(vq_object_t instance);
+
+/* in vqsim_vq_engine.c - effectively the constructor */
+int fork_new_instance(int nodeid, int *vq_sock, pid_t *child_pid);
+
+/* In parser.c */
+void parse_input_command(char *cmd);
+
+/* These are in vqmain.c */
+int cmd_stop_node(int nodeid);
+void cmd_stop_all_nodes(void);
+int cmd_start_new_node(int nodeid, int partition);
+void cmd_set_autofence(int onoff);
+void cmd_set_sync(int onoff);
+void cmd_set_assert(int onoff);
+void cmd_move_nodes(int partition, int num_nodes, int *nodelist);
+void cmd_join_partitions(int part1, int part2);
+void cmd_update_all_partitions(int newring);
+void cmd_qdevice_poll(int nodeid, int onoff);
+void cmd_show_node_states(void);
+void cmd_set_timeout(uint64_t seconds);
+void cmd_start_sync_command(void);
+void resume_kb_input(int show_state);
diff --git a/vqsim/vqsim_vq_engine.c b/vqsim/vqsim_vq_engine.c
new file mode 100644
index 0000000..e0bb0bd
--- /dev/null
+++ b/vqsim/vqsim_vq_engine.c
@@ -0,0 +1,479 @@
+
+/* This is the bit of VQSIM that runs in the forked process.
+ It represents a single votequorum instance or, if you like,
+ a 'node' in the cluster.
+*/
+
+#include <sys/types.h>
+#include <qb/qblog.h>
+#include <qb/qbloop.h>
+#include <qb/qbipc_common.h>
+#include <netinet/in.h>
+#include <sys/poll.h>
+#include <sys/socket.h>
+#include <stdio.h>
+
+#include "../exec/votequorum.h"
+#include "../exec/service.h"
+#include "../include/corosync/corotypes.h"
+#include "../include/corosync/votequorum.h"
+#include "../include/corosync/ipc_votequorum.h"
+#include <corosync/logsys.h>
+#include <corosync/coroapi.h>
+
+#include "icmap.h"
+#include "vqsim.h"
+
+#define QDEVICE_NAME "VQsim_qdevice"
+
+/* Static variables here are per-instance because we are forked */
+static struct corosync_service_engine *engine;
+static int parent_socket; /* Our end of the socket */
+static char buffer[8192];
+static int our_nodeid;
+static char *private_data;
+static qb_loop_t *poll_loop;
+static qb_loop_timer_handle sync_timer;
+static qb_loop_timer_handle qdevice_timer;
+static int we_are_quorate;
+static void *fake_conn = (void*)1;
+static cs_error_t last_lib_error;
+static struct memb_ring_id current_ring_id;
+static int qdevice_registered;
+static unsigned int qdevice_timeout = VOTEQUORUM_QDEVICE_DEFAULT_TIMEOUT;
+
+/* 'Keep the compiler happy' time */
+char *get_run_dir(void);
+
+int api_timer_add_duration (
+ unsigned long long nanosec_duration,
+ void *data,
+ void (*timer_fn) (void *data),
+ corosync_timer_handle_t *handle);
+
+static void api_error_memory_failure(void) __attribute__((noreturn));
+static void api_error_memory_failure()
+{
+ fprintf(stderr, "Out of memory error\n");
+ exit(-1);
+}
+static void api_timer_delete(corosync_timer_handle_t th)
+{
+ qb_loop_timer_del(poll_loop, th);
+}
+
+int api_timer_add_duration (
+ unsigned long long nanosec_duration,
+ void *data,
+ void (*timer_fn) (void *data),
+ corosync_timer_handle_t *handle)
+{
+ return qb_loop_timer_add(poll_loop,
+ QB_LOOP_MED,
+ nanosec_duration,
+ data,
+ timer_fn,
+ handle);
+}
+
+static unsigned int api_totem_nodeid_get(void)
+{
+ return our_nodeid;
+}
+
+static int api_totem_mcast(const struct iovec *iov, unsigned int iovlen, unsigned int type)
+{
+ struct vqsim_msg_header header;
+ struct iovec iovec[iovlen+1];
+ int total = sizeof(header);
+ int res;
+ int i;
+
+ header.type = VQMSG_EXEC;
+ header.from_nodeid = our_nodeid;
+ header.param = 0;
+
+ iovec[0].iov_base = &header;
+ iovec[0].iov_len = sizeof(header);
+ for (i=0; i<iovlen; i++) {
+ iovec[i+1].iov_base = iov[i].iov_base;
+ iovec[i+1].iov_len = iov[i].iov_len;
+ total += iov[i].iov_len;
+ }
+
+ res = writev(parent_socket, iovec, iovlen+1);
+ if (res != total) {
+ fprintf(stderr, "writev wrote only %d of %d bytes\n", res, total);
+ }
+ return 0;
+}
+static void *api_ipc_private_data_get(void *conn)
+{
+ return private_data;
+}
+static int api_ipc_response_send(void *conn, const void *msg, size_t len)
+{
+ struct qb_ipc_response_header *qb_header = (void*)msg;
+
+ /* Save the error so we can return it */
+ last_lib_error = qb_header->error;
+ return 0;
+}
+
+static struct corosync_api_v1 corosync_api = {
+ .error_memory_failure = api_error_memory_failure,
+ .timer_delete = api_timer_delete,
+ .timer_add_duration = api_timer_add_duration,
+ .totem_nodeid_get = api_totem_nodeid_get,
+ .totem_mcast = api_totem_mcast,
+ .ipc_private_data_get = api_ipc_private_data_get,
+ .ipc_response_send = api_ipc_response_send,
+};
+
+/* -------------------- Above is all for providing the corosync_api support routines --------------------------------------------*/
+/* They need to be in the same file as the engine as they use the local 'poll_loop' variable which is per-process */
+
+static void start_qdevice_poll(int longwait);
+static void start_sync_timer(void);
+
+/* Callback from Votequorum to tell us about the quorum state */
+static void quorum_fn(const unsigned int *view_list,
+ size_t view_list_entries,
+ int quorate, struct memb_ring_id *ring_id)
+{
+ char msgbuf[8192];
+ int len;
+ struct vqsim_quorum_msg *quorum_msg = (void*) msgbuf;
+
+ we_are_quorate = quorate;
+
+ /* Send back to parent */
+ quorum_msg->header.type = VQMSG_QUORUM;
+ quorum_msg->header.from_nodeid = our_nodeid;
+ quorum_msg->header.param = 0;
+ quorum_msg->quorate = quorate;
+ memcpy(&quorum_msg->ring_id, ring_id, sizeof(*ring_id));
+ quorum_msg->view_list_entries = view_list_entries;
+
+ memcpy(quorum_msg->view_list, view_list, sizeof(unsigned int)*view_list_entries);
+
+ if ( (len=write(parent_socket, msgbuf, sizeof(*quorum_msg) + sizeof(unsigned int)*view_list_entries)) <= 0) {
+ perror("write (view list to parent) failed");
+ }
+ memcpy(&current_ring_id, ring_id, sizeof(*ring_id));
+}
+
+char *corosync_service_link_and_init(struct corosync_api_v1 *api,
+ struct default_service *service_engine)
+{
+ /* dummy */
+ return NULL;
+}
+
+/* For votequorum */
+char *get_run_dir()
+{
+ static char cwd_buffer[PATH_MAX];
+
+ return getcwd(cwd_buffer, PATH_MAX);
+}
+
+/* This is different to the one in totemconfig.c in that we already
+ * know the 'local' node ID, so we can just search for that.
+ * It needs to be here rather than at main config read time as it's
+ * (obviously) going to be different for each instance.
+ */
+static void set_local_node_pos(struct corosync_api_v1 *api)
+{
+ icmap_iter_t iter;
+ uint32_t node_pos;
+ char name_str[ICMAP_KEYNAME_MAXLEN];
+ uint32_t nodeid;
+ const char *iter_key;
+ int res;
+ int found = 0;
+
+ iter = icmap_iter_init("nodelist.node.");
+ while ((iter_key = icmap_iter_next(iter, NULL, NULL)) != NULL) {
+ res = sscanf(iter_key, "nodelist.node.%u.%s", &node_pos, name_str);
+ if (res != 2) {
+ continue;
+ }
+ if (strcmp(name_str, "nodeid")) {
+ continue;
+ }
+
+ res = icmap_get_uint32(iter_key, &nodeid);
+ if (res == CS_OK) {
+ if (nodeid == our_nodeid) {
+ found = 1;
+ res = icmap_set_uint32("nodelist.local_node_pos", node_pos);
+ assert(res == CS_OK);
+ }
+ }
+ }
+ if (!found) {
+ /* This probably indicates a dynamically-added node
+ * set the pos to zero and use the votes of the
+ * first node in corosync.conf
+ */
+ res = icmap_set_uint32("nodelist.local_node_pos", 0);
+ assert(res == CS_OK);
+ }
+}
+
+static int load_quorum_instance(struct corosync_api_v1 *api)
+{
+ const char *error_string;
+ int res;
+
+ error_string = votequorum_init(api, quorum_fn);
+ if (error_string) {
+ fprintf(stderr, "Votequorum init failed: %s\n", error_string);
+ return -1;
+ }
+
+ engine = votequorum_get_service_engine_ver0();
+ error_string = engine->exec_init_fn(api);
+ if (error_string) {
+ fprintf(stderr, "votequorum exec init failed: %s\n", error_string);
+ return -1;
+ }
+
+ private_data = malloc(engine->private_data_size);
+ if (!private_data) {
+ perror("Malloc in child failed");
+ return -1;
+ }
+
+ res = engine->lib_init_fn(fake_conn);
+
+ return res;
+}
+
+static void sync_dispatch_fn(void *data)
+{
+ if (engine->sync_process()) {
+ start_sync_timer();
+ }
+ else {
+ engine->sync_activate();
+ }
+}
+
+static void start_sync_timer()
+{
+ qb_loop_timer_add(poll_loop,
+ QB_LOOP_MED,
+ 10000000,
+ NULL,
+ sync_dispatch_fn,
+ &sync_timer);
+}
+
+static void send_sync(char *buf, int len)
+{
+ struct vqsim_sync_msg *msg = (void*)buf;
+
+ /* Votequorum doesn't use the transitional node list :-) */
+ engine->sync_init(NULL, 0,
+ msg->view_list, msg->view_list_entries,
+ &msg->ring_id);
+
+ start_sync_timer();
+}
+
+static void send_exec_msg(char *buf, int len)
+{
+ struct vqsim_exec_msg *execmsg = (void*)buf;
+ struct qb_ipc_request_header *qb_header = (void*)execmsg->execmsg;
+
+ engine->exec_engine[qb_header->id & 0xFFFF].exec_handler_fn(execmsg->execmsg, execmsg->header.from_nodeid);
+}
+
+static int send_lib_msg(int type, void *msg)
+{
+ /* Clear this as not all lib functions return a response immediately */
+ last_lib_error = CS_OK;
+
+ engine->lib_engine[type].lib_handler_fn(fake_conn, msg);
+
+ return last_lib_error;
+}
+
+static int poll_qdevice(int onoff)
+{
+ struct req_lib_votequorum_qdevice_poll pollmsg;
+ int res;
+
+ pollmsg.cast_vote = onoff;
+ pollmsg.ring_id.nodeid = current_ring_id.nodeid;
+ pollmsg.ring_id.seq = current_ring_id.seq;
+ strcpy(pollmsg.name, QDEVICE_NAME);
+
+ res = send_lib_msg(MESSAGE_REQ_VOTEQUORUM_QDEVICE_POLL, &pollmsg);
+ if (res != CS_OK) {
+ fprintf(stderr, CS_PRI_NODE_ID ": qdevice poll failed: %d\n", our_nodeid, res);
+ }
+ return res;
+}
+
+static void qdevice_dispatch_fn(void *data)
+{
+ if (poll_qdevice(1) == CS_OK) {
+ start_qdevice_poll(0);
+ }
+}
+
+static void start_qdevice_poll(int longwait)
+{
+ unsigned long long timeout;
+
+ timeout = (unsigned long long)qdevice_timeout*500000; /* Half the corosync timeout */
+ if (longwait) {
+ timeout *= 2;
+ }
+
+ qb_loop_timer_add(poll_loop,
+ QB_LOOP_MED,
+ timeout,
+ NULL,
+ qdevice_dispatch_fn,
+ &qdevice_timer);
+}
+
+static void stop_qdevice_poll(void)
+{
+ qb_loop_timer_del(poll_loop, qdevice_timer);
+ qdevice_timer = 0;
+}
+
+static void do_qdevice(int onoff)
+{
+ int res;
+
+ if (onoff) {
+ if (!qdevice_registered) {
+ struct req_lib_votequorum_qdevice_register regmsg;
+
+ strcpy(regmsg.name, QDEVICE_NAME);
+ if ( (res=send_lib_msg(MESSAGE_REQ_VOTEQUORUM_QDEVICE_REGISTER, &regmsg)) == CS_OK) {
+ qdevice_registered = 1;
+ start_qdevice_poll(1);
+ }
+ else {
+ fprintf(stderr, CS_PRI_NODE_ID ": qdevice registration failed: %d\n", our_nodeid, res);
+ }
+ }
+ else {
+ if (!qdevice_timer) {
+ start_qdevice_poll(0);
+ }
+ }
+ }
+ else {
+ poll_qdevice(0);
+ stop_qdevice_poll();
+ }
+}
+
+
+/* From controller */
+static int parent_pipe_read_fn(int32_t fd, int32_t revents, void *data)
+{
+ struct vqsim_msg_header *header = (void*)buffer;
+ int len;
+
+ len = read(fd, buffer, sizeof(buffer));
+ if (len > 0) {
+ /* Check header and route */
+ switch (header->type) {
+ case VQMSG_QUIT:
+ exit(0);
+ break;
+ case VQMSG_EXEC: /* For votequorum exec messages */
+ send_exec_msg(buffer, len);
+ break;
+ case VQMSG_SYNC:
+ send_sync(buffer, len);
+ break;
+ case VQMSG_QDEVICE:
+ do_qdevice(header->param);
+ break;
+ case VQMSG_QUORUMQUIT:
+ if (!we_are_quorate) {
+ exit(1);
+ }
+ break;
+ case VQMSG_QUORUM:
+ /* not used here */
+ break;
+ }
+ }
+ return 0;
+}
+
+static void initial_sync(int nodeid)
+{
+ unsigned int trans_list[1] = {nodeid};
+ unsigned int member_list[1] = {nodeid};
+ struct memb_ring_id ring_id;
+
+ ring_id.nodeid = our_nodeid;
+ ring_id.seq = 1;
+
+ /* cluster with just us in it */
+ engine->sync_init(trans_list, 1,
+ member_list, 1,
+ &ring_id);
+ start_sync_timer();
+}
+
+/* Return pipe FDs & child PID if sucessful */
+int fork_new_instance(int nodeid, int *vq_sock, pid_t *childpid)
+{
+ int pipes[2];
+ pid_t pid;
+
+ if (socketpair(AF_UNIX, SOCK_SEQPACKET | SOCK_NONBLOCK, 0, pipes)) {
+ return -1;
+ }
+ parent_socket = pipes[0];
+
+ switch ( (pid=fork()) ) {
+ case -1:
+ perror("fork failed");
+ return -1;
+ case 0:
+ /* child process - continue below */
+ break;
+ default:
+ /* parent process */
+ *vq_sock = pipes[1];
+ *childpid = pid;
+ return 0;
+ }
+
+ our_nodeid = nodeid;
+ poll_loop = qb_loop_create();
+
+ if (icmap_get_uint32("quorum.device.timeout", &qdevice_timeout) != CS_OK) {
+ qdevice_timeout = VOTEQUORUM_QDEVICE_DEFAULT_TIMEOUT;
+ }
+
+ set_local_node_pos(&corosync_api);
+ load_quorum_instance(&corosync_api);
+
+ qb_loop_poll_add(poll_loop,
+ QB_LOOP_MED,
+ parent_socket,
+ POLLIN,
+ NULL,
+ parent_pipe_read_fn);
+
+ /* Start it up! */
+ initial_sync(nodeid);
+ qb_loop_run(poll_loop);
+
+ return 0;
+}